For the complete documentation index, see llms.txt. This page is also available as Markdown.

SSO & MFA

Configure OIDC single sign-on and TOTP multi-factor authentication

Sling Platform supports OpenID Connect single sign-on and TOTP multi-factor authentication. Both are self-hosted only and require the Advanced plan.

Single Sign-On (Microsoft Entra ID / OIDC)

SSO is self-hosted only and requires the Advanced plan. Set SLING_PLATFORM_SSO to a JSON object (or a bare provider name). When the env var is unset, login is unchanged.

SLING_PLATFORM_HOST must be the external URL browsers use. Entra ID requires an https:// redirect URI (localhost HTTP is the only exception). A missing SLING_PLATFORM_HOST with SSO configured is a fatal boot error.

Register this Web redirect URI at the IdP:

https://<SLING_PLATFORM_HOST>/auth/sso/callback

Microsoft Entra ID

  1. Entra admin center → App registrations → New registration. Single tenant. Platform Web. Redirect URI as above.

  2. Certificates & secrets → new client secret.

  3. Optional (defense in depth): Token configuration → add the email and xms_edov optional claims. They are not required. A single-tenant app is trusted by the tid pin; xms_edov and allowed_domains are extra filters.

services:
  sling-platform:
    environment:
      SLING_PLATFORM_HOST: "https://sling.example.com"
      SLING_PLATFORM_SSO: '{"provider":"microsoft","tenant_id":"<entra-tenant-id>","client_id":"<app-id>","client_secret":"<secret>","display_name":"Sign in with Microsoft","default_role":"power","allowed_domains":["company.com"],"session_duration":"12h","enforce":false}'

Full JSON:

SLING_PLATFORM_SSO full JSON
{
  "provider": "microsoft",
  "tenant_id": "<entra-tenant-id>",
  "client_id": "<app-registration-client-id>",
  "client_secret": "<client-secret>",
  "display_name": "Sign in with Microsoft",
  "default_role": "power",
  "allowed_domains": ["company.com", "example.com"],
  "scopes": ["openid", "profile", "email"],
  "session_duration": "12h",
  "enforce": false
}

tenant_id must be a single-tenant ID — never common / organizations / consumers.

Email trust. First login and JIT provisioning accept the IdP email when any of these hold:

  1. provider is microsoft and the ID-token tid matches tenant_id (the tenant admin is the customer).

  2. email_verified or Entra xms_edov is true.

  3. The email domain is in allowed_domains.

Otherwise the login redirects with sso_error=email_not_verified. For provider: oidc, allowed_domains is required and is the trust anchor when the vendor does not send email_verified.

JIT users are added to every project that exists at provisioning time. Later membership changes (remove from a project, new projects) are manual — SSO login does not re-grant access.

Generic OIDC (Okta, Keycloak, Auth0, …)

allowed_domains is required for provider: oidc (it is the trust anchor when the vendor does not send email_verified). The issuer URL must match the iss claim byte-for-byte (Auth0 issuers usually end with /; Okta custom authorization servers use /oauth2/<name>).

Okta example (turn Always include claims in token off is fine — Sling falls back to /userinfo):

Keycloak example:

Field
Required
Default
Notes

provider

yes

microsoft or oidc

tenant_id

microsoft

Expanded to https://login.microsoftonline.com/<tenant>/v2.0

issuer_url

oidc

Full issuer URL

client_id / client_secret

yes

From the IdP app registration

scopes

no

openid profile email

openid is always added

display_name

no

per provider

Login button label

default_role

no

power

Role for JIT-provisioned users (editor is an alias for power)

allowed_domains

oidc

Email-domain allow-list. Optional for microsoft

session_duration

no

PocketBase 14 days

Go duration (8h, 12h, 24h). Applied to every session on the install

enforce

no

false

Hide email/password and reject password auth. The SLING_PLATFORM_ADMIN_CREDENTIALS account is exempt (break-glass)

SSO and MFA require the Advanced plan. If the license is Standard (or lapsed), the platform still boots with the feature active, logs a warning, and shows a banner. Password login is never silently re-opened when enforce is on.

Rate limits (per client IP unless noted). A 429 is a real throttle, not an IdP error.

Route
Limit

GET /auth/sso/init, GET /auth/sso/callback

60 / minute / IP

POST /auth/sso/handoff

none (one-time 32-byte code, 60s TTL)

POST /auth/login

30 / minute / IP and 10 / minute / IP+email

POST /auth/login/mfa

60 / minute / IP (5 attempts per challenge)

MFA enroll / verify / disable / regenerate

20 / minute / user

Multi-Factor Authentication

MFA is self-hosted only, Advanced plan, and applies to email/password logins. SSO users skip Sling TOTP — enforce MFA at the IdP (Entra Conditional Access).

Field
Default
Notes

enabled

true when the env var is set

Bare "true" is shorthand for {"enabled": true}

required

false

Force enrollment on next password login

issuer

Sling Platform

Label shown in authenticator apps

Users enroll from the user menu → Security (QR + recovery codes). Rotating the authenticator or regenerating recovery codes requires a current TOTP or recovery code. After a recovery-code login, a warning appears when 2 or fewer codes remain.

Project admins can Reset MFA on the Members settings tab (shown only for enrolled users). The admin account from SLING_PLATFORM_ADMIN_CREDENTIALS can always use password login under SSO enforce; if that account enrolls MFA, the TOTP challenge still applies.

Last updated

Was this helpful?