---
title: Federation
path: concepts/federation
status: published
---

# Federation

ScaiKey can delegate user authentication to an external identity provider per tenant. Each tenant configures zero or more IdPs; end users see them as buttons on the login page ("Sign in with `<your IdP>`") and never interact with ScaiKey-shaped UI for federated accounts.

This page covers what federation is, which protocols are supported, and where the data lives. For provisioning shapes (just-in-time vs. SCIM-pushed), see [Users and groups](/docs/scaikey/concepts/users-and-groups). For the OAuth flow that issues tokens after a federated login, see [OAuth and OIDC](/docs/scaikey/concepts/oauth-and-oidc).

## Supported protocols

| Protocol | Direction | Typical use |
|---|---|---|
| **OIDC** | ScaiKey delegates to a third-party | Okta, Auth0, Azure AD, Google Workspace, Keycloak, custom OIDC provider |
| **SAML 2.0** | ScaiKey delegates to a third-party | Entra ID (Microsoft 365), ADFS, Workday, Ping Identity, OneLogin |
| **LDAP / LDAPS** | ScaiKey reads from a third-party (sync) | On-prem Active Directory, OpenLDAP, FreeIPA |
| **SCIM 2.0** | Third-party pushes to ScaiKey | Okta provisioning, Workday HR-driven provisioning, any SCIM 2.0 client |

ScaiKey is a relying party / service provider / SCIM target in all four cases — not an IdP itself, in this direction. (For the other direction, where ScaiKey acts as an IdP to your applications, see the OAuth pages.)

## Configuration scope

Federation is configured **per tenant**. A tenant can have any number of IdPs enabled at once — for example, an enterprise might keep LDAP for legacy on-prem accounts, OIDC for the SaaS-employee group, and SCIM-incoming for a contractor population provisioned out of a separate HR system.

Cross-tenant federation (one IdP shared by multiple tenants) is not supported — it would break the tenant-isolation model. If two tenants need to share an IdP, configure it identically on each; JIT-provisioned users land in the right tenant by virtue of which `/admin/identity-providers/<idp_id>` row they authenticated through.

## OIDC federation

Configure with a discovery URL (`/.well-known/openid-configuration`) and a client ID / secret you registered at the upstream provider. ScaiKey caches the discovery document and the JWKS, refreshing both periodically.

```http
POST /api/v1/admin/identity-providers
Content-Type: application/json

{
  "tenant_id": "tnt_…",
  "name": "Acme SSO",
  "type": "OIDC",
  "discovery_url": "https://login.acme.example/.well-known/openid-configuration",
  "client_id": "scaikey-relying-party",
  "client_secret": "…",
  "scopes": ["openid", "profile", "email", "groups"],
  "attribute_mapping": {
    "email": "email",
    "display_name": "name",
    "first_name": "given_name",
    "last_name": "family_name",
    "groups": "groups"
  },
  "is_enabled": true
}
```

`attribute_mapping` maps inbound IdP claims to ScaiKey user fields. Defaults match standard OIDC claim names, but the mapping is explicit so an IdP using non-standard names (`upn` instead of `email`) can be wired without code changes.

## SAML 2.0 federation

Configure with either an IdP metadata URL or pasted metadata XML. ScaiKey acts as a SAML SP; it generates a SP metadata document at `/api/v1/auth/saml/<idp_id>/metadata` that you import into the upstream IdP.

Attribute statements in the SAML assertion map to ScaiKey user fields the same way as OIDC. The mapping accepts both unqualified attribute names (`email`) and full URNs (`urn:oid:0.9.2342.19200300.100.1.3`) — useful for ADFS deployments that emit the latter by default.

## LDAP / LDAPS

Configure with a bind DN, password (stored encrypted at rest), search base, and a search filter. ScaiKey runs a background sync worker every `sync_interval_minutes` (configurable per IdP, default 60) that:

- Resolves all users matching the filter.
- Diffs against existing ScaiKey users with `identity_source = LDAP` pointing at this IdP.
- Creates, updates, soft-deletes accordingly. Deletions are soft — an LDAP entry disappearing doesn't hard-delete the ScaiKey row, so audit history is preserved.
- Maps LDAP groups (filterable separately) to ScaiKey groups, including nested groups when the directory supports them.

Authentication is real-time: a user logging in with LDAP credentials goes straight to the directory at login time. Only directory population is background-synced.

## SCIM 2.0 incoming

ScaiKey exposes a SCIM 2.0 server at `/api/v1/scim/v2/` per tenant, gated by a bearer token. An upstream provisioning system (Okta, Workday HR, custom) POSTs users and groups in; ScaiKey accepts, normalises, and stores them with `identity_source = SCIM`.

Configure on the ScaiKey side by creating an IdP row of type `SCIM_INCOMING` and minting a SCIM bearer token via `/api/v1/admin/scim-tokens`. The token is the only credential the upstream system sees — tenant-scoped, rotatable independently, audit-logged on every SCIM call.

## Just-in-time (JIT) provisioning

For OIDC and SAML, the first time a federated user authenticates successfully, ScaiKey can create the user row automatically. JIT is enabled per-IdP via `jit_provisioning_enabled: true`. The created user's `identity_source` reflects the IdP type, `external_id` carries the IdP's stable identifier (subject claim for OIDC, NameID for SAML), and the attribute mapping populates the rest.

Disable JIT (`jit_provisioning_enabled: false`) for IdPs where the user population is curated centrally — typical for LDAP-synced or SCIM-pushed populations, where seeing an unrecognised user attempt to log in should be a hard failure rather than a silent account creation.

## Login UI

Each tenant's login page shows:

- A primary login form (email + password) for `identity_source = LOCAL` users.
- A button per enabled federation IdP, labelled with `name` from the IdP row.
- Optional automatic redirect ("force SSO") if the tenant has exactly one IdP and `is_default: true`.

`idp_hint=<idp_id>` on `/authorize` skips the picker and goes straight to the named IdP — useful when your portal already knows which IdP a user belongs to.

## What's next

- [OAuth and OIDC](/docs/scaikey/concepts/oauth-and-oidc) — the token flows that fire after a federated login succeeds.
- [Users and groups](/docs/scaikey/concepts/users-and-groups) — provisioning lifecycle for federated users.
- [Identity Providers API](/docs/scaikey/reference/api/identity-providers) — endpoint reference.
