← Documentation

SSO Connections

A Connection is one customer identity provider, brokered through the account's Keycloak realm.

Two sides of one record

Each Connection belongs to an Account and has a type of "saml" or "oidc". Its fields split cleanly into two sides: values RealmSSO generates and hands to the customer (our service-provider side), and values the customer hands to RealmSSO describing their own identity provider.

Our SP sideCustomer IdP side
entityId — our SP entity ID / audienceidpEntityId — the customer IdP's issuer
acsUrl — where the customer's IdP POSTs the SAML assertionidpSsoUrl — the customer IdP's SSO endpoint (AuthnRequest destination)
idpCertificate — the customer IdP's X.509 signing certificate

A related SsoConfig row holds the generated values actually published for the connection — acsUrl, entityId, audience, and (for OIDC) redirectUris. Because RealmSSO runs the “Keycloak-direct” model described in Architecture Overview, these URLs point at Keycloak's own broker endpoint in the account's realm, not at any route on RealmSSO itself — the assertion or authorization code is consumed by Keycloak, never proxied through RealmSSO's API.

Provisioning flow

Creating a connection (POST /api/v1/connections/saml or /oidc) writes the row with status: "pending", computes a deterministic Keycloak identity-provider alias (e.g. saml-<account-slug>-<connection-id prefix>), resolves which realm to provision into — adopting a pre-existing legacy footprint if one is found, per Accounts (Tenants) — and then calls Keycloak to create the identity provider. On success the row flips to "active" and records the alias; on failure it flips to "error" with the failure captured in metadata, and the connection is re-read before being returned so callers never see a stale “pending” status.

For SAML, the customer's IdP details can arrive either as a metadataUrl (which Keycloak fetches and parses directly) or as explicit idpEntityId / idpSsoUrl / idpCertificate values. Attribute mappers are created for both paths so a brokered user lands with email/first/last name populated from whichever claim schema the IdP happens to use (Okta and Entra ID both differ).

Pasted SAML metadata XML is not supported yet

The schema has a metadataXml field, but provisioning rejects it outright with a validation error rather than silently dropping it: Keycloak's metadata importer takes a URL or a file upload, neither of which a pasted XML string satisfies yet. Use a metadata URL, or supply the IdP entity ID, SSO URL, and certificate directly.

Health checks

POST /api/v1/connections/:id/test checks whether the connection's Keycloak identity provider is enabled and reachable, then writes the result back onto the connection as healthStatus ("healthy" or "down") and lastHealthCheckAt. Every test is recorded both as an audit entry and as an observability event, so health history is queryable alongside login activity.

Deletion order matters

Removing a connection that has a live keycloakIdpAlias first terminates the sessions of every user who logged in through that identity provider and then deletes the identity provider itself — and only then removes the database row. Deleting the row first would strand a live identity provider in Keycloak that nothing in RealmSSO could find again.