Use Okta as Identity Provider to login to Halo portal using SSO.

## Prerequisites

- Okta authorization server configured for Halo (see [Okta Authorization Server](/halo/okta-authorization-server))

## Register your app in Okta

### Create app integration

1. Login to Okta Admin Console → Navigate to `Applications` -> `Applications`.
2. Click Create App Integration → Choose OIDC - OpenID Connect.
3. Click Single-Page Application.

![image.png](/.attachments/image-e6e11714-0c36-4a15-af1c-0947cc06a965.png)

### Configure app integration

4. Configure the following settings:
   - App integration name:  e.g. `Glasswall Halo Portal`
   - Grant type: Choose below 3 options
     - Authorization Code
     - Refresh Token
     - Implicit (hybrid)
   - Sign-in redirect URIs: e.g. `https://<your-halo-domain>/authentication/login-callback`
   - Sign-out redirect URIs: e.g. `https://<your-halo-domain>/authentication/logout-callback`
   - Controlled access: Choose `Allow everyone in your organization to access`. Or select only specific groups if you want to limit the access to few people.
   - Unselect `Enable immediate access with Federation Broker Mode`.

![Screenshot: Halo Portal Client](/.attachments/image-aca97b4a-4b46-4bf4-a42a-529c9737dd21.png)
![Screenshot: Halo Portal Client](/.attachments/image-97b96edb-ea97-40d4-81e4-f69587f7db29.png)

### Save application and note client ID

5. Save the Application and note the `Client ID`.

    ```sh
    export PORTAL_CLIENT_ID=""
    ```

![Screenshot: Portal client id](/.attachments/image-1129c561-2bbe-40c6-84ab-66facee12b36.png)

### Grant API scopes

6. Navigate to `Okta API Scopes` tab in the application and grant below scopes.
    - `okta.myAccount.email.read`
    - `okta.myAccount.profile.read`
    - `okta.users.read`
    - `okta.users.read.self`

![Screenshots: Portal Okta API Scopes](/.attachments/image-f745d7d3-6d57-4223-bd3e-7e23f3ab643b.png)

### Note issuer URI and audience

7. From the authorization server configured in the [prerequisite step](/halo/okta-authorization-server), note the `Issuer Metadata URI` and `VALID_AUDIENCE`:

    ```sh
    export OKTA_ISSUER_URI="https://<your-okta-domain>/oauth2/<authorization-server-id>"
    export OKTA_ORIGIN="https://<your-okta-domain>"
    export VALID_AUDIENCE="api://halo"
    ```

### Add access policy for portal

8. Navigate to the authorization server's `Access Policies` tab (`Security` -> `API` -> select your authorization server -> `Access Policies`).
9. Add a new access policy:
    - Name: e.g. `Portal SSO Access`
    - Description: e.g. `Access policy for Halo Portal SSO users`
    - Assign to: the Portal SPA client created above (search by name `Glasswall Halo Portal`)
10. Add a rule:
    - Name: e.g. `Allow Portal Users`
    - Grant type: `Authorization Code`
    - User is a member of: `Everyone` (or restrict to a specific group, e.g., `Halo-Admin`, if you want to limit Portal access)
    - Leave other settings as defaults or adjust as needed.

![Screenshot: Access policy for Portal SSO](/.attachments/image-60586cbc-bad9-4fcd-b8bf-602c36414351.png)
![Screenshot: Add rule](/.attachments/image-670efadd-cb0a-4a23-b0a9-d7bcb10b8ed6.png)

## Update Portal service

```sh
export HALO_DOMAIN=<your-halo-domain>
helm upgrade --install cdrplatform-portal cdrplatform-portal -n cdrplatform --reuse-values \
  --set configuration.AutoAdmin=false \
  --set configuration.BackendScope="email openid profile" \
  --set configuration.BackendUrl="https://${HALO_DOMAIN:?}" \
  --set configuration.EnabledPages="SystemSettings\,PolicySettings\,IcapSettings\,IcapRequests\,IcapReporting" \
  --set configuration.OIDC.ProviderOptions.Authority="${OKTA_ISSUER_URI:?}" \
  --set configuration.OIDC.ProviderOptions.ClientId="${PORTAL_CLIENT_ID:?}" \
  --set configuration.OIDC.ProviderOptions.PostLogoutRedirectUri="https://${HALO_DOMAIN:?}/authentication/logout-callback" \
  --set configuration.OIDC.ProviderOptions.RedirectUri="https://${HALO_DOMAIN:?}/authentication/login-callback" \
  --set appenvironment.HTTP_CSP_CONNECT_SRC="'self' ${OKTA_ORIGIN:?}" \
  --set appenvironment.HTTP_CSP_FRAME_SRC="'self' ${OKTA_ORIGIN:?}" \
  --set appenvironment.HTTP_CSP_FRAME_ANCESTORS="'self' ${OKTA_ORIGIN:?}" \
  --set ingress.enabled=true \
  --set ingress.tls.domain="${HALO_DOMAIN:?}" \
  --set ingress.tls.enabled=true \
  --atomic
```

## Update Portal-Access service

```sh
helm upgrade --install cdrplatform-portal-access -n cdrplatform cdrplatform-portal-access --reuse-values \
  --set configuration.Authentication__Schemes__Bearer__Authority="${OKTA_ISSUER_URI:?}" \
  --set configuration.Authentication__Schemes__Bearer__ValidAudiences__0="${VALID_AUDIENCE:?}" \
  --set configuration.Authentication__Schemes__Bearer__ValidIssuer="${OKTA_ISSUER_URI:?}" \
  --set configuration.AuthenticationScheme="Bearer" \
  --set configuration.CORSDOMAIN="'*'" \
  --set ingress.enabled=true \
  --set ingress.tls.domain="${HALO_DOMAIN:?}" \
  --set ingress.tls.enabled=true \
  --atomic
```

## Provide access to users

There are 2 roles in Halo - `User` and `Admin`. Roles are configured via group membership on the Okta authorization server (see [Define Roles](/halo/okta-authorization-server#define-roles)).

- To provide user role, add the user to the `Halo_User` group.
- To provide admin role, add the user to the `Halo_Admin` group.