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

# Identity providers

> Sign people in with Keycloak, Okta or Entra ID, sync their groups, and let agents act with their own permissions.

Connect your identity provider over OIDC. Everything is set in **Platform > Organization > Access**, and groups in **Platform > Organization > Members & groups**.

![Diagram](https://docs.xpander.ai/images/diagrams/run-integrations-identity-providers-5cfa1387.svg)

## Sign-in per deployment

| Deployment | Sign-in |
| - | - |
| xpander cloud and Hybrid | Email code, Google, GitHub, or your identity provider over OIDC (an enterprise feature). Registration on xpander cloud is self-serve and free |
| Air-Gapped | A bootstrap admin password, email codes, or your OIDC provider |

Roles are **Root access**, **Admin** and **Member**. See [Govern every agent](https://docs.xpander.ai/run/govern.md#who-may-do-what).

## The OIDC client

Create a confidential client at the identity provider:

| Setting | Value |
| - | - |
| Client type | Confidential, client authentication on |
| Flow | Authorization code (Keycloak: "Standard flow") |
| Redirect URIs | Three exact URIs, no wildcard: `.../oidc/<org-id>/callback`, `.../oidc/<org-id>/logout` and `.../oidc/<org-id>/login`. **Redirect URIs** in the OIDC settings copies each one |
| Web origins | `https://<app-host>` |
| Scopes | `openid`, `profile`, `email`, plus a `groups` client scope for group sync |
| Claims | `email` in userinfo, set to the user's address |

### What you enter in xpander

| Field | Value |
| - | - |
| Issuer URL | Exactly as in the discovery document, including any context path, for example `https://idp.example.com/auth/realms/<realm>` |
| Client ID and secret | From the client you created |
| Extra scopes | Optional |
| **API service app** card | Optional second client plus a generated **Directory key**, used for directory reads and agent token exchange. Okta needs key-pair authentication on it. |

The token and userinfo calls run from inside the cluster, so the IdP must be reachable from the pods, not only from the browser.

## Group sync

**1. Create the groups client scope at the IdP**

In Keycloak, create a **client scope named `groups`** with a **Group Membership** mapper (claim `groups`, full path off, in userinfo), and assign it to the client as optional. A mapper on the client alone fails with `error=invalid_scope`.

**2. Request the scope in xpander**

Under OIDC, **Additional sign-in scopes**, choose **Add**, type `groups`, then **Save configuration**.

**3. Link the groups**

After the next sign-in, open a group's menu under **Members & groups** and choose **Link SSO groups**. Pick the values the IdP sent, or type one under **Add a group by name or ID** and choose **Add to list**. **Save links** adds an **SSO** badge. Members join at their next sign-in.

![Members & groups on the Groups tab with the Link SSO groups to Engineering panel open: no groups received yet, an Add a group by name or ID field with Add to list, and Save links](https://mintcdn.com/xpanderai-099931d1/wqIIXSsh0kqA2hZ_/images/verify/lab-user-groups-link-dialog.png?fit=max\&auto=format\&n=wqIIXSsh0kqA2hZ_\&q=85\&s=83377ec6afea181708d7be88dfd8b67a)

Link SSO groups, before the identity provider has sent any groups: add one by name or ID, then Save links. Shown with sample data.

If the IdP returns an error, the browser lands on `/` signed out with no message. Look for `error=` on the callback request in the browser's network log. More on [SSO with your identity provider](https://docs.xpander.ai/self-hosted/sso.md#group-sync-with-keycloak).

## Agent pre-authentication

At the moment of a call, xpander exchanges the asking person's sign-in token (OIDC token exchange) for one scoped to the target system. The agent then acts with that person's permissions where the system allows.

| Side | What it needs |
| - | - |
| IdP client | Token exchange on (Keycloak 26: `standard.token.exchange.enabled=true`), direct access grants, an audience client for the target system, and a client scope with an audience mapper |
| xpander | Under OIDC, **Agent pre-authentication**: **Enable agent pre-authentication**, **Audiences** (one per target system) and **Token exchange scopes**, then **Save configuration** |

Leave it off to start.

## Air-Gapped chart values

```yaml theme={"dark"}
client-auth:
  env:
    APP_URL: https://<app-host>   # the UI origin, no trailing slash; it forms the redirect_uri
ui:
  authProviders: [sso]            # renders the SSO button
```

## Next steps

> **[Set up SSO on a self-hosted install](https://docs.xpander.ai/self-hosted/sso.md)**
>
> Keycloak screens and troubleshooting

> **[Decide who may do what](https://docs.xpander.ai/run/govern.md#who-may-do-what)**
>
> Roles and groups


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.