Authentication & SSO.
Last updated
OAuth 2.0 / OIDC
What it is. Single sign-on through an external identity provider, so
people log in with accounts they already have instead of an AccessFlow password. Google,
GitHub, Microsoft, and GitLab are built in; two more tabs cover self-hosted GitHub
Enterprise and GitLab (self-managed) (you provide the instance base URL, e.g.
https://github.acme.corp, and AccessFlow appends the well-known sub-paths); and
a generic OpenID Connect tab integrates any other OIDC provider (Keycloak, Auth0,
Okta, Authentik, Zitadel). It all lives in the database, so adding a provider needs no
restart.
How do users sign in to AccessFlow?
By default, with an email and password issued in AccessFlow, optionally protected by TOTP two-factor. Organizations can instead delegate sign-in to an identity provider over OAuth 2.0 / OIDC or SAML 2.0, in which case users are auto-provisioned on first login and never hold an AccessFlow password.
Configure it. Manage providers at /admin/oauth2:
/admin/oauth2 — one tab per built-in provider (Google / GitHub / Microsoft / GitLab), two self-hosted tabs (GitHub Enterprise / GitLab self-managed), plus a generic OpenID Connect tab. Each tab carries its own redirect URI and provider-specific guidance.- Register an OAuth app at the provider using the redirect URI shown in the AccessFlow tab (copy it directly from the info callout). The format is
{ACCESSFLOW_PUBLIC_BASE_URL}/api/v1/auth/oauth2/callback/{provider}. - Open
/admin/oauth2, pick the provider tab, and paste the Client ID and Client secret. Microsoft additionally needs a Tenant ID; other providers expose optional Scopes override for custom claims. For GitHub Enterprise and GitLab (self-managed), also enter the Server base URL of your self-hosted instance (origin only — no path, no query;https://only). AccessFlow appends/login/oauth/authorize,/login/oauth/access_token, and/api/v3/*for GitHub Enterprise, and/oauth/authorize,/oauth/token,/oauth/userinfo,/oauth/discovery/keysfor self-managed GitLab. For the OpenID Connect tab, also enter the IdP's Display name (rendered on the login button as "Continue with …"), Authorization endpoint URL, Token endpoint URL, UserInfo endpoint URL, JWK set URL, and Issuer URL — most IdPs publish all five at/.well-known/openid-configuration. Optional attribute-claim fields (User-name claim, Email claim, Email-verified claim, Display-name claim) default to the standard OIDC names (sub,email,email_verified,name) and only need to be set if your IdP uses non-standard claims. - (Optional) Restrict who may sign in. Use Allowed organizations and Allowed email domains on the same tab:
- Google — populate Allowed email domains with your Workspace domain(s); the organization list is ignored.
- GitHub — list the org logins users must belong to (e.g.
bablsoft) in Allowed organizations. AccessFlow callsGET /user/orgs, so the Scopes override must includeread:org— saving an active config without it returns a 422 with a clear message. - Microsoft — list AAD group object IDs in Allowed organizations. The Entra app registration must be configured (Token configuration → groups) to emit the
groupsclaim. - GitLab — list full group paths from the OIDC
groupsclaim (e.g.acme/team). - GitHub Enterprise — same as GitHub but the orgs call hits
{base_url}/api/v3/user/orgs;read:orgscope is still required. - GitLab (self-managed) — same as GitLab (OIDC
groupsclaim) but resolved against your self-hosted instance. - OpenID Connect — set the Groups claim field to the claim name your IdP uses (often
groupsorroles), then list the group identifiers users must belong to in Allowed organizations. Leave the claim field blank to disable group enforcement and rely on Allowed email domains instead.
OAUTH2_ORG_NOT_ALLOWEDorOAUTH2_EMAIL_DOMAIN_NOT_ALLOWED. - Pick a default role for first-time sign-ins (defaults to
READONLY) and flip Active on to enable the provider's button on the login page. - Set
ACCESSFLOW_OAUTH2_FRONTEND_CALLBACK_URLif the frontend lives at a different origin than the backend's CORS origin (default{CORS_ALLOWED_ORIGIN}/auth/oauth/callback).
Email verification is required before an OAuth account is linked, and account-linking is conservative — a provider-supplied email will not silently take over an existing local user. Implementation details: docs/07-security.md → Authentication.
Tune it. ACCESSFLOW_OAUTH2_FRONTEND_CALLBACK_URL (where the
provider round-trip lands, default ${CORS_ALLOWED_ORIGIN}/auth/oauth/callback)
and ACCESSFLOW_OAUTH2_EXCHANGE_CODE_TTL (one-time exchange-code lifetime,
default PT1M).
SAML 2.0 SSO
What it is. Single sign-on via a SAML 2.0 identity provider (Okta, Azure AD, OneLogin, …) — the enterprise-SSO alternative to OAuth / OIDC. Configure one record per organization; both SP-initiated and IdP-initiated logins work.
Configure it. Fill the single form at /admin/saml:
/admin/saml — a single config form covering IdP metadata, SP entity, and attribute mapping.- Open
/admin/saml. - Identity provider. Paste the IdP metadata URL (preferred — AccessFlow refreshes it periodically), or fall back to IdP entity ID + Signing certificate (PEM) when the IdP doesn't publish metadata over HTTP.
- Service provider. Set SP entity ID, ACS URL, and SLO URL — register these with your IdP.
- Attributes. Map the IdP assertion attributes that carry email, display name, and role. Pick a default role for users whose assertion doesn't include one, then flip Active on to enable the SAML button on the login page.
SAML users rely on the IdP's MFA rather than AccessFlow's TOTP. Full SP metadata, signing-cert rotation, and assertion validation rules live in docs/07-security.md.
Tune it. ACCESSFLOW_SAML_FRONTEND_CALLBACK_URL
(default ${CORS_ALLOWED_ORIGIN}/auth/saml/callback) and
ACCESSFLOW_SAML_EXCHANGE_CODE_TTL (default PT1M). To pin the
service-provider signing keypair instead of the auto-generated one, set
ACCESSFLOW_SAML_SP_SIGNING_KEY_PEM and
ACCESSFLOW_SAML_SP_SIGNING_CERT_PEM.