Skip to main content
Connect your identity provider (IdP) over OIDC: one client gives you sign-in, group sync and agent pre-authentication. Everything is set in Platform > Organization > Access > Single sign-on, and groups in Platform > Organization > Members & groups. SSO is a license feature on self-hosted installs (Licensing).

Sign-in per deployment

Hybrid and Air-Gapped organizations are set up by their own admins. Provisioning, deprovisioning and MFA for OIDC sign-ins stay in your identity provider. Each person can also add xpander’s own two-step sign-in in Settings > Security. Roles are on Access control.
Access page with Single sign-on, Roles and API keys tabs and the identity provider settings

Platform > Organization > Access > Single sign-on. Shown with sample data.

Set up sign-in

1

Create a client at your identity provider

On Keycloak, also map the email onto preferred_username (see Keycloak and preferred_username below).
2

Enter it in xpander

Under Platform > Organization > Access:
3

Self-hosted: give the pods a path to the IdP

The token and userinfo calls run from inside the cluster, so the IdP must be reachable from the pods, not only from browsers. Node egress addresses change, so an IP-restricted public entry refuses those calls even when the browser redirect works. Use a private-zone record and an internal load balancer, for example keycloak.internal.<domain> on an internal ingress class, resolved so the issuer hostname still matches. On Air-Gapped, also set the chart values below.
4

Sign in

Click SSO, type your work email under Sign in with SSO, and sign in at your IdP.
client-auth is published as client-auth.<domain> and also serves skill OAuth redirects. Google and GitHub social buttons are a separate path (GoTrue providers, supabase.auth.extraEnv in the chart).
  1. The user clicks SSO and types their work email under Sign in with SSO. The email only picks the organization and is never sent to the IdP.
  2. client-auth redirects the browser to your IdP with scopes openid profile email plus any you add. The client is confidential (client_id and client_secret, no PKCE).
  3. The IdP redirects back to https://<app-host>/oidc/<organization-id>/callback with a code.
  4. client-auth exchanges the code and reads the user from the IdP’s userinfo endpoint, from inside the cluster.
  5. xpander finds or creates the user by email in GoTrue and starts the session.
Keycloak sign-in page titled Sign in to your account with Username or email and Password fields

After the SSO button: the identity provider's own sign-in page, here Keycloak. Shown with sample data.

Keycloak sends the account username, so user creation fails with Unable to validate email address: invalid format. Map the email onto it:
  1. Client scopes, the client’s dedicated scope, Add mapper, By configuration, User Property.
  2. Name preferred_username, Property email, Token Claim Name preferred_username, type String, “Add to userinfo” on.
  3. Retry the SSO sign-in.
Or set “Email as username” under Realm settings, Login. Releases with the September 2026 edge-functions image or later read email first, but add the mapper anyway: it works on every release.
Give the pod at least 2 GiB when you use kcadm.sh (each call starts a second JVM). Install Keycloak after its database, role and admin secret exist, or the release deadlocks.

Group sync with Keycloak

IdP groups map to xpander user groups:
  1. Create a groups client scope. Client scopes, Create client scope, name groups, type Optional. Add a Group Membership mapper: name groups, Token Claim Name groups, Full group path off, Add to userinfo on. Then add groups to your xpander client as Optional. A mapper on the dedicated scope alone is not enough: Keycloak answers error=invalid_scope.
  2. Request the scope. Under Additional sign-in scopes, Add groups, then Save configuration. xpander records claim groups from userinfo.
  3. Sign in once, so xpander sees the group values.
  4. Link a group. Platform > Organization > Members & groups, the group’s menu, Link SSO groups. Pick a seen value or Add a group by name or ID with Add to list, then Save links. The row shows an SSO badge.
Members join the xpander group at their next sign-in, so joiners and leavers are handled in your directory.
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

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

GET /oidc/<org-id>/groups exists for Okta and Entra ID only. With Keycloak it answers 400, which is harmless.

Agent pre-authentication

Lets an agent act with the asking person’s own permissions where systems allow. At the moment of a call, xpander exchanges the person’s sign-in token (OIDC token exchange, RFC 8693) for a token scoped to the target system. Turn it on only after sign-in works. To sign each person in to an MCP connector through this IdP, see Per-person sign-in for MCP connectors.

When it fails

Logs: the client-auth pod (token and userinfo), the auth (GoTrue) pod (user creation) and the edge-runtime pod (oidc-callback).

Next steps

Sign each person in to MCP connectors

Per-person permissions.

Check what the license enables

SSO is a license feature.