> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thoras.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Okta OIDC dashboard auth

> Log into the Thoras dashboard via Okta using the chart's built-in oauth2-proxy sidecar in OIDC mode.

This guide covers the Okta-specific steps for authenticating dashboard users
against Okta. See the
[dashboard authentication overview](/guides/dashboard-auth) for how the built-in
sidecar works and how the two auth modes compare.

<Tip>
  If you already run your own oauth2-proxy sidecar against Okta from a pre-5.0
  install, your app registration and Secret carry over unchanged. See [Migrating
  from a hand-rolled oauth2-proxy
  sidecar](/guides/dashboard-auth#migrating-from-a-hand-rolled-oauth2-proxy-sidecar).
</Tip>

## Setup

### 1. Register an app in Okta

1. In the Okta Admin Console, go to **Applications -> Applications -> Create App
   Integration**.
2. Choose **OIDC - OpenID Connect** as the sign-in method and **Web
   Application** as the application type.
3. Set a **Sign-in redirect URI** of
   `https://thoras.yourcompany.com/oauth2/callback`.
4. Under **Assignments**, grant access to the group(s) that should be able to
   reach the dashboard (or "Everyone" for org-wide access).
5. Once created, note the **Client ID** and **Client secret** from the app's
   **General** tab, and your **Okta domain** (e.g. `dev-133337.okta.com`) from
   the top of the Admin Console.

Your issuer URL is `https://<your-okta-domain>/oauth2/default` if you're using
the default custom authorization server,
`https://<your-okta-domain>/oauth2/<auth-server-id>` if you've configured a
custom authorization server under **Security -> API**, or
`https://<your-okta-domain>` if you're using the org authorization server.

<Warning>
  **The `default` custom authorization server may not be available or usable.**
  Custom authorization servers (including the one named `default`) are part of
  Okta's [API Access Management](https://developer.okta.com/docs/concepts/api-access-management/)
  add-on. Production orgs that don't have that add-on cannot use `/oauth2/default`
  at all, and newly provisioned Integrator Free Plan orgs ship without an Access
  Policy on it. Without a matching Access Policy, login fails with `You are not
      allowed to access this app` and a `no_matching_policy` error in the Okta system
  log. Fix it one of two ways:

  * **Add an Access Policy** to the default custom auth server under **Security ->
    API -> Authorization Servers -> default -> Access Policies**, then add a rule
    that applies to your app.
  * **Use the org authorization server instead** by dropping `/oauth2/default`
    from the issuer URL. Set the issuer to `https://<your-okta-domain>`. This
    works on every Okta org and needs no add-on. See
    [Authorization servers (Okta docs)](https://developer.okta.com/docs/concepts/auth-servers/).
</Warning>

See oauth2-proxy's own Okta walkthrough (under the OpenID Connect provider,
which is what Okta uses):
[OpenID Connect - Okta](https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/openid_connect#okta),
and Okta's writeup of the same integration:
[Add Auth to Any App with OAuth2 Proxy](https://developer.okta.com/blog/2022/07/14/add-auth-to-any-app-with-oauth2-proxy).

### 2. Create the Kubernetes secret

The sidecar needs three values, read from a Kubernetes Secret you manage rather
than inlined in `values.yaml`. The chart never generates these:

| Key             | Purpose                                                        |
| --------------- | -------------------------------------------------------------- |
| `client-id`     | The application's client ID                                    |
| `client-secret` | The application's client secret                                |
| `cookie-secret` | A random value oauth2-proxy uses to encrypt its session cookie |

Generate the cookie secret with:

```bash theme={null}
openssl rand -base64 32 | head -c 32 | base64
```

Create the secret (values below are base64-encoded automatically by `kubectl`
when using `--from-literal`):

```bash theme={null}
kubectl create secret generic oauth2-proxy-secrets \
  --namespace thoras \
  --from-literal=client-id="<your-client-id>" \
  --from-literal=client-secret="<your-client-secret>" \
  --from-literal=cookie-secret="$(openssl rand -base64 32 | head -c 32 | base64)"
```

### 3. Switch the chart into OIDC mode

In `values.yaml`, set `thorasDashboard.auth.mode: oidc` and fill in the OIDC
block:

```yaml theme={null}
thorasDashboard:
  auth:
    mode: oidc
    oidc:
      provider: oidc
      issuerURL: https://<your-okta-domain>/oauth2/default
      redirectURL: https://thoras.yourcompany.com/oauth2/callback
      emailDomains: [yourcompany.com]
      existingSecret:
        secretName: oauth2-proxy-secrets
```

#### Field notes

* `provider`: `oidc`. oauth2-proxy has no Okta-specific provider; Okta is served
  by the generic OpenID Connect provider, which is what oauth2-proxy's own Okta
  example uses. `okta` is not a valid value and the sidecar will fail to start.
* `issuerURL`: points at your Okta authorization server. Use
  `https://<your-okta-domain>/oauth2/default` for the default custom
  authorization server, `https://<your-okta-domain>/oauth2/<auth-server-id>` for
  another custom one, or `https://<your-okta-domain>` for the org authorization
  server (see the Warning above).
* `redirectURL`: must be the real external hostname of the dashboard, over
  HTTPS, and must exactly match the sign-in redirect URI registered on the Okta
  app.
* `emailDomains`: restricts login to your org's email domain(s). Use `["*"]` to
  allow any authenticated user.
* `existingSecret.secretName`: points at the Secret you created in step 2.

### 4. Deploy and verify

1. `helm upgrade` the release with the updated `values.yaml`.
2. Confirm the dashboard pod comes up healthy, and check the sidecar logs if
   something goes wrong:
   ```bash theme={null}
   kubectl -n thoras get pods -l app=thoras-dashboard
   kubectl -n thoras logs deploy/thoras-dashboard -c oauth2-proxy
   ```
3. Visit the dashboard URL. You should be redirected to your identity provider's
   login page, and land back on the dashboard after authenticating.
4. If the redirect fails or loops, double-check that `redirectURL` exactly
   matches a redirect URI registered on your identity provider's app, and that
   `issuerURL` is correct.

## Exposing the sidecar externally

The chart's built-in oauth2-proxy sidecar owns the dashboard's `containerPort`,
so the existing `thorasDashboard` Service already routes external traffic
through the auth check. No `service.targetPort` override is needed.

Expose the Service using whichever mechanism the chart already supports:

**Ingress**

```yaml theme={null}
thorasDashboard:
  ingress:
    enabled: true
    hosts:
      - host: thoras.yourcompany.com
        paths:
          - path: /
            pathType: Prefix
```

**Gateway API**

```yaml theme={null}
thorasDashboard:
  gatewayAPI:
    enabled: true
    parentRefs:
      - name: eg
        sectionName: http
    hostnames:
      - thoras.yourcompany.com
```

Adjust `ingressClassName`/`parentRefs` to match your cluster's actual Ingress
controller or `Gateway`, and terminate TLS there (or upstream at a
cert-manager-issued `Certificate` bound to it). Once DNS for
`thoras.yourcompany.com` resolves and a valid TLS cert is issued, visiting the
dashboard URL should trigger the login flow described above.

## Further reading

* [oauth2-proxy documentation home](https://oauth2-proxy.github.io/oauth2-proxy/)
* [oauth2-proxy OpenID Connect provider - Okta section](https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/openid_connect#okta)
* [Add Auth to Any App with OAuth2 Proxy (Okta blog)](https://developer.okta.com/blog/2022/07/14/add-auth-to-any-app-with-oauth2-proxy)
* [Okta authorization servers (org vs. custom)](https://developer.okta.com/docs/concepts/auth-servers/)
* [Configuration overview / full flag reference](https://oauth2-proxy.github.io/oauth2-proxy/configuration/overview)
* [Session storage options](https://oauth2-proxy.github.io/oauth2-proxy/configuration/session_storage)
* [TLS configuration](https://oauth2-proxy.github.io/oauth2-proxy/configuration/tls)
