Skip to main content

Federation (OIDC / SAML SSO)

Alexandria EE supports OIDC Authorization Code + PKCE and SAML 2.0 SP-initiated SSO. Providers are configured in the server TOML config. JIT-provisioning creates accounts on first login.

The oidc license entitlement is required to use federation endpoints. Community deployments receive 402 on authenticated admin views.


GET /auth/providers

Lists configured SSO providers for the login page. Public — no authentication required.

Response 200

{
"providers": [
{ "name": "okta", "display_name": "Okta", "kind": "oidc" },
{ "name": "azure", "display_name": "Azure AD", "kind": "saml" }
]
}

OIDC Authorization Code + PKCE

GET /auth/oidc/{provider}/authorize

Redirects the browser to the IdP's authorization endpoint. PKCE state is stored server-side and consumed at callback.

Query params

  • redirect (optional) — post-login URL; tokens are placed in the URL fragment
GET /auth/oidc/okta/authorize?redirect=https://app.example.com/dashboard
→ 302 https://company.okta.com/oauth2/.../authorize?state=...&code_challenge=...

GET /auth/oidc/{provider}/callback

IdP redirects here after the user authenticates. The handler:

  1. Validates state (single-use, deletes the DB row)
  2. Exchanges the authorization code for an ID token
  3. JIT-provisions the user if it's their first login
  4. Redirects the browser with tokens in the URL fragment, or returns JSON if Accept: application/json

JSON response (when Accept: application/json):

{
"access_token": "eyJ...",
"refresh_token": "...",
"token_type": "Bearer",
"expires_in": 900
}

OIDC CLI Device-Code Flow

For non-browser environments (CLI, scripts) that cannot complete a redirect flow.

Step 1 — start the flow

POST /auth/oidc/{provider}/cli-start

// Response 200
{
"auth_url": "https://company.okta.com/oauth2/.../authorize?...",
"session_id": "abc123"
}

Open auth_url in a browser, then poll.

Step 2 — poll for completion

GET /auth/oidc/{provider}/cli-poll/{session_id}

// While pending
{ "status": "pending" }

// On success
{
"status": "complete",
"access_token": "eyJ...",
"refresh_token": "...",
"token_type": "Bearer",
"expires_in": 900
}

// On error
{ "status": "error", "error": "provision: user denied access" }

SAML 2.0

GET /auth/saml/{provider}/metadata

Returns SP metadata XML. Register this URL with your IdP. No auth required.

Content-Type: application/samlmetadata+xml

GET /auth/saml/{provider}/sso

Begins SP-initiated SSO by redirecting to the IdP's SSO URL.

Query params

  • redirect (optional) — post-login URL

POST /auth/saml/{provider}/acs

Assertion Consumer Service. The IdP POSTs SAMLResponse and optional RelayState here.

On success, redirects with tokens in the URL fragment (or JSON if Accept: application/json).


Admin federation management

GET /admin/federation/providers

Admin view of configured providers (includes config summary). Requires oidc entitlement.

GET /admin/users/{id}/federation

Lists all federation identity links for a user (provider, external user ID, etc).

DELETE /admin/users/{id}/federation/{provider}

Unlinks a federation identity. Forces re-JIT provisioning on the next SSO login.


curl example

# List providers (public)
curl http://localhost:8080/auth/providers | jq .

# CLI OIDC flow
SESSION=$(curl -s -X POST http://localhost:8080/auth/oidc/okta/cli-start | jq -r .session_id)
echo "Open in browser: $(curl -s ... | jq -r .auth_url)"

# Poll
curl http://localhost:8080/auth/oidc/okta/cli-poll/$SESSION | jq .