# Single sign-on with Okta (agent runbook)

Add Okta (OIDC) sign-in to a running install, beside password sign-in, in four steps.

Rendered page: https://agentrelay.com/docs/self-hosting/agents/okta-sso
Markdown endpoint: https://agentrelay.com/docs/self-hosting/agents/okta-sso.md

---

> **Enterprise feature.** Single sign-on is part of Agent Relay Enterprise and
> needs an Enterprise agreement for production use. See
> [Licensing](https://agentrelay.com/docs/self-hosting/agents/overview#licensing).

> **Agent:** STOP before step 1 and ask the human to confirm their organization has an Agent
> Relay Enterprise agreement, or that this is an evaluation install.

**Safe to try:** password sign-in stays on beside Okta, and step 4 turns Okta
off again. With Okta on, people **don't need accounts created**: an Okta user
assigned to the app, whose email domain you allow, joins as a member the first
time they sign in. Nothing here is sent to Agent Relay.

These steps are written for EKS. A real Okta organization hasn't been run
through them yet, so tell us if a step differs. On GKE they are the same, using step 11 of
[Install on GKE](https://agentrelay.com/docs/self-hosting/agents/install-gke) for the upgrade. Any OIDC provider works the same way:
create a web app with the redirect below and use its issuer.

## 1. Create the Okta app and store its secret (Okta admin, about 2 minutes)

From the `agent-relay-install` folder, with `kubectl` access and an Okta API
token (Okta Admin › Security › API › Tokens). `okta-setup.sh` came with step 1's
files:

```sh
source settings.sh
OKTA_ORG=https://<your-org>.okta.com \
APP_DOMAIN="$DOMAIN" \
OKTA_GROUP='<Okta group allowed to use Agent Relay>' \
ALLOWED_DOMAIN=<your email domain> \
  bash okta-setup.sh
```

The script:

- asks for the API token without echoing it;
- creates an OIDC web app with the redirect `https://<domain>/login/oidc/callback`;
- assigns the group;
- picks the issuer;
- stores the client secret in the cluster (`agent-relay-secrets`, key
  `oidc-client-secret`) and in `~/.agent-relay-install`;
- prints the lines for step 2.

It never prints the token or the client secret.

**Done when:** it prints `client secret stored`, followed by the values for
step 2.

**Prefer the Okta console?** Create an OIDC **Web Application** with the
Authorization Code grant, sign-in redirect `https://<domain>/login/oidc/callback`,
and assign the group. Then store the secret:

```sh
read -rs -p 'Okta client secret: ' X; echo
printf '%s' "$X" > ~/.agent-relay-install/secret-files/agent-relay-secrets/oidc-client-secret; unset X
kubectl -n agent-relay create secret generic agent-relay-secrets \
  --from-file=$HOME/.agent-relay-install/secret-files/agent-relay-secrets --dry-run=client -o yaml | kubectl apply -f -
```

The issuer is `https://<org>.okta.com/oauth2/default` if you have Okta API
Access Management, otherwise `https://<org>.okta.com`.

**Using helm-secrets or vals** ([Secrets](https://agentrelay.com/docs/self-hosting/agents/secrets))? After
this step, rerun your secrets commands. They pick up the new
`oidc-client-secret` file, and stop a later upgrade from dropping it.

> **Agent:** This step needs an Okta admin's API token: ASK THE HUMAN (Okta admin) to run
> okta-setup.sh, or the console steps, in their own terminal. Never ask for,
> accept or type the token or the client secret. Ask them to paste back only the
> issuer and client ID lines the script prints.

## 2. Add the settings to values.yaml

Under `relay-control:` in `values.yaml`:

- in `secretKeys:`, add `oidcClientSecret: oidc-client-secret`;
- in `auth:`, add (the script prints these filled in):

  ```yaml
      oidc:
        issuer: <issuer>
        clientId: <client ID>
        allowedDomains: [<your email domain>]
        displayName: Okta
      autoJoinDomains: [<your email domain>]
  ```

`autoJoinDomains` (beside `oidc:`) lets those people join without an invite.

The client ID isn't secret; it's fine in `values.yaml`.

## 3. Apply and check

Run the `helm upgrade` from step 11 of the install, then:

```sh
curl -s "https://api.$DOMAIN/cloud/api/v1/auth/login-config" | jq '{methods, oidc}'
```

**Done when:**

- `oidc` shows `Okta`;
- `https://<domain>/login` shows **Continue with Okta** beside the password form;
- someone in the group can sign in with it and lands in your organization as a
  member;
- someone outside the group is refused by Okta.

> **Agent:** ASK THE HUMAN for approval before the helm upgrade. The last two checks need
> real people: ASK THE HUMAN to try both and report the result.

## 4. To turn it off

Remove the `oidc:` block, `autoJoinDomains` and the `oidcClientSecret` line from `values.yaml`,
then run the `helm upgrade` again. Password sign-in keeps working throughout.
