Beta, off by default. The sign-in policy below shares theOAuth and OpenID Connect providers (enabled under Settings, OAuth sign-in, see Identity and access) get the same controls SAML connections have. For each provider you decide who may sign in, whether a first sign-in creates an account, which role each group earns and whether the role follows the group on later sign-ins.saml-scimbeta feature with SAML and SCIM: turn it on under Settings, Beta features or withAPP_EXPERIMENTAL=saml-scim. While it is off, the policy settings page and routes answer404and the sign-in page shows no “Continue with SSO” button, but the policy you saved is still enforced at sign-in. It is tested against a fake OpenID Connect provider that signs real tokens, and has not been run against a live Okta, Microsoft Entra ID, Google or Keycloak tenant (see What has not been verified).
The defaults are least privilege
Providers that were already enabled when you upgraded keep their old behavior for new emails (they create accounts, as before). Turn Create an account on first sign-in off to close that. A provider you enable after upgrading starts with it off.
Setup
- Enable the provider under Settings, OAuth sign-in with its client ID and secret. For a provider that sends groups, use the generic OpenID Connect provider (see the table below).
- Open Settings, Single sign-on. The provider is listed under OAuth and OIDC sign-in. Choose Configure.
- Set the policy, then map groups to roles in the shared Group to role mappings card on the same page.
- Choose Test login. You sign in at the provider and land back on the page with what the sign-in would do: the groups the provider sent, the role they earn, and whether the account would be linked, created or refused. A test login creates no account, role or session. Each failure comes with a typed fix: one click for a wrong claim name, a missing domain or account creation being off, and a plain instruction when the fix is at your identity provider.
sso oidc evaluate runs the same rules as a real sign-in on the facts you give it and changes nothing. Every command takes --json.
Providers
Safety rules
Every rule is enforced in code and covered by a test.
The people you want to let in without account creation still work the usual way: invite them, or create the account, and they link at their first sign-in when the provider marks their email verified.
Sign in by email domain
When allowed domains are set, the sign-in page’s Continue with SSO button asks for a work email and sends the person to the provider (or SAML connection) that claims that domain. Only the part after the@ leaves the browser, so the lookup says nothing about any person. A domain no connection claims, a malformed one and a rate limited request all get the same empty answer, and the page shows one neutral message. Two connections cannot claim one domain: saving the second is refused with 409, and if both somehow exist the domain routes nowhere. The lookup is rate limited per client address (APP_SSO_ROUTE_RATE_PER_MINUTE, default 60).
That a domain has single sign-on at all is visible to anyone who tries it, as it is for any identity provider’s home realm discovery.
API
The policy responses carry no client secret or token. Client credentials stay on
PUT /api/v1/settings/oauth/{provider}, where the secret is write-only.
What is not supported
- Group sync from userinfo, the access token or provider APIs (GitHub teams, Google Workspace groups, Microsoft Graph groups). Only a groups claim in the verified ID token is read.
- Several OIDC connections per provider. There is one generic OpenID Connect provider. Use SAML for a second identity provider of the same kind.
- Per-connection group mappings. The mapping table is shared by SAML, OIDC and SCIM.
- Required SSO per domain. Require SSO is instance wide.
- Deprovisioning. Removing someone at the identity provider does not end their session or disable the account here. Use SCIM for that, or disable the account.