Skip to content

Authentik (SSO) ​

Users sign in with Authentik over OIDC (Authorization Code Flow with PKCE). MFA, password rules, account recovery, and the login flow are managed in Authentik. This application manages users, the global administrator flag, browser sessions, and the audit log. Permissions inside a Project are set in this application.

Permissions are decided in two levels.

LevelDecided byWhere to change
Can sign in / is a global administratorAuthentik groups and a mapping in the API server's environmentGroup membership in Authentik and .env
Project role (Viewer / Editor / Admin)The stronger of a direct grant and a group grant. In a Public Project, everyone who can sign in is an EditorProject settings

1. Register in Authentik ​

Create an application and an OAuth2/OpenID provider in Authentik. Replace https://tracking.example.com below with the actual HTTPS URL of this application (MMT_PUBLIC_URL).

  1. In the Authentik admin interface, open Applications → Providers → Create and create an OAuth2/OpenID Provider.
  2. Set the following values.
FieldValue
Client typeConfidential
Redirect URIshttps://tracking.example.com/api/auth/callback (exact match)
ScopesThe openid, profile, email, and offline_access mappings
Back-channel logout URIhttps://tracking.example.com/api/auth/oidc/backchannel-logout
  1. Create an application under Applications → Create and select the provider. Use ml-tracking as the slug in this example.
  2. Note the provider's client ID and client secret. Put the client secret only in the API server's .env.

The issuer URL is per application. With the slug ml-tracking it is https://sso.example.com/application/o/ml-tracking/.

Scopes and groups ​

Both the ID token and UserInfo must contain these claims:

  • email and email_verified (logins where email_verified is not true are refused)
  • name (display name)
  • groups (an array of group names)

If UserInfo has no groups, the periodic recheck after login decides that the user is in no group, and everyone's session ends. Check that the provider's scope mappings emit groups.

offline_access (Authentik's built-in "authentik default OAuth Mapping: OpenID 'offline_access'") makes Authentik issue refresh tokens. Without it the application still works, but users must sign in again each time Authentik's access token expires (the provider's Access token validity, 5 minutes by default).

For a seven-day login, edit the Provider and add that mapping under Advanced protocol settings → Scopes. Set Refresh Token Validity to days=7 or longer; an existing days=30 setting can stay as it is. Access Token Validity can remain minutes=5 because the application refreshes access tokens.

2. Configure the API server ​

Put the following in the API server's .env. HTTPS is required in production. Use hybrid while introducing SSO so that a local administrator remains for emergencies ("Move to SSO" in Authentication).

dotenv
NODE_ENV=production
AUTH_MODE=hybrid
AUTH_SESSION_IDLE_SECONDS=604800
AUTH_SESSION_ABSOLUTE_SECONDS=604800
MMT_PUBLIC_URL=https://tracking.example.com
MMT_WEB_ORIGIN=https://tracking.example.com
OIDC_ISSUER_URL=https://sso.example.com/application/o/ml-tracking/
OIDC_CLIENT_ID=<provider client ID>
OIDC_CLIENT_SECRET=<provider client secret>
OIDC_LABEL=Authentik
OIDC_SCOPES=openid profile email offline_access
OIDC_ALLOWED_GROUPS=mmt-users,mmt-admins
OIDC_ROLE_MAPPING_JSON={"mmt-admins":"admin","mmt-users":"user"}
OIDC_DEFAULT_ROLE=user
OIDC_AUTO_LINK_VERIFIED_EMAIL=false
MMT_SESSION_ENCRYPTION_KEY=<value generated by the command below>
OIDC_RECHECK_SECONDS=60
OIDC_TOKEN_SYNC_MAX_AGE_SECONDS=604800

MMT_SESSION_ENCRYPTION_KEY encrypts the Authentik tokens stored with sessions. Generate it in a terminal and write it only in .env. Use a value different from the storage key (MMT_STORAGE_SECRET_KEY).

sh
openssl rand -base64 32

Restart the API after changing the settings. Each variable is listed under "Authentication and SSO" in Environment variables.

These settings keep a login for seven days, including inactivity. Update an existing .env too: changing examples or defaults does not replace values already set there. Sign in once after applying the settings to obtain a refresh token.

Allowed groups and the administrator group ​

  • OIDC_ALLOWED_GROUPS: groups allowed to sign in (comma-separated). Required in oidc and hybrid; the API does not start if it is empty. People in none of these groups cannot sign in, and no user is created for them.
  • OIDC_ROLE_MAPPING_JSON: a group → global role mapping. The roles are admin (global administrator) and user (sign-in only). Any other value is a startup error. Without it, no one who signs in through SSO is a global administrator.
  • OIDC_DEFAULT_ROLE: the role of allowed users who match no group in the mapping. Default user.

A user in several groups gets the stronger role (admin). Include the groups in the mapping in OIDC_ALLOWED_GROUPS too. People whose groups are all outside the allowed list cannot sign in, whatever the mapping says.

Authentik groups (example)In OIDC_ALLOWED_GROUPSMapped roleResult
mmt-adminsYesadminCan sign in and is a global administrator
mmt-usersYesuserCan sign in and work in Public Projects as an Editor. Other roles are granted separately
Only mmt-proj-asr-editorsNo—Cannot sign in
mmt-users and mmt-proj-asr-editorsmmt-users isuserCan sign in, and grants to mmt-proj-asr-editors apply

Check ​

  1. Open this application in a browser and check that the login screen shows the Authentik button (the value of OIDC_LABEL).
  2. Have someone in mmt-admins sign in with SSO, open Global settings from the user menu, and check that the Administration group (Projects, Users, and so on) appears in the sidebar.
  3. Have someone only in mmt-users sign in, open Global settings from the user menu, and check that the sidebar shows the Global settings group (Account, Computers) but not the Administration group.
  4. Check that someone in neither group is refused. The reason is recorded in the audit log as auth.oidc.denied ("Cannot sign in with SSO" in Troubleshooting).

What is synchronized at each login ​

  • A user is created at the first SSO login. There is no self sign-up screen.
  • The global administrator flag and the user's groups are synchronized at every login. If you change the flag on the screen, the next login restores Authentik's state. Change Authentik groups for a permanent change.
  • The display name and email are updated from Authentik at every login.
  • A login that would leave no active global administrator is refused (last_admin).
  • Creation, linking, and changes to the global role or groups are recorded in the audit log as auth.oidc.sync.

Local accounts with the same email ​

By default (OIDC_AUTO_LINK_VERIFIED_EMAIL=false), an SSO user becomes a separate user even if a local account has the same email. With true, the SSO identity is linked to the local account only when all of the following hold:

  • email_verified is true
  • Exactly one local account, not yet linked to SSO, has the same email (case-insensitive)
  • That local account is neither a global administrator nor an Admin of any Project

Privileged local accounts are never linked automatically, so that an Authentik account cannot take over an administrator. Such logins are refused with privileged_link_required.

Rechecking permissions during a session ​

This stops people removed from a group in Authentik without waiting for their next login.

  • An SSO session checks the current groups with Authentik's UserInfo every OIDC_RECHECK_SECONDS (default 60 seconds). If the access token has expired, it is refreshed with the refresh token first.
  • If the user is still in an allowed group, the groups and the global administrator flag are updated and the session continues. Project roles change from the next request.
  • If the user has left all allowed groups, all of the user's SSO sessions end and the user's API tokens stop.
  • If Authentik refuses the tokens (the user signed out of Authentik, the user was disabled, the refresh token expired), that session ends.
  • If Authentik cannot be reached, the API returns 503 oidc_unavailable and keeps the session. Requests are not allowed with unchecked permissions. Once Authentik is back, the same session continues.

Local account sessions and API token requests never call Authentik.

Back-channel logout ​

If you register the Back-channel logout URI in the Authentik provider, ending a user or session in Authentik also ends the sessions in this application. This is recorded in the audit log as auth.oidc.backchannel_logout.

API tokens of SSO users ​

A user who only uses API tokens would never notice group changes. So an SSO user's API tokens work only until OIDC_TOKEN_SYNC_MAX_AGE_SECONDS (default 7 days) after the last group sync (a login or a recheck). After that they return 401 identity_sync_required. The tokens are not revoked; signing in once in a browser makes the same tokens work again.

Use Service Account tokens, not personal tokens, for long-running workers, automation, and CI. Service Accounts are exempt from this limit (API tokens and Service Accounts).

Grant Project roles to groups ​

Instead of granting a role to each person, you can grant a Project role to an Authentik group.

  1. Create a group per Project in Authentik (for example mmt-proj-asr-editors).
  2. Add the members to the group and have them sign in with SSO once.
  3. Open Project settings and click Add group under Authentik group.
  4. Enter the group name and role, and save.
FieldValue
Group nameThe Authentik group name as is. Exact match, including case and spaces. Example: mmt-proj-asr-editors
RoleViewer, Editor, or Admin

The suggestions list only groups that have been synchronized by someone's login. Type the name directly for a group nobody has signed in with yet.

After saving, the members of the group appear in the Members list with the source "group mmt-proj-asr-editors". The grant is in place.

The group does not need to be in OIDC_ALLOWED_GROUPS. However, its members still need to be in one of the allowed groups to sign in.

Group membership is synchronized at login and at each recheck (every 60 seconds by default). Someone added to the group in Authentik gets the permission within about a minute, even during a session; someone removed loses it within about a minute. A user who only uses API tokens keeps the old groups until the next sync. To stop access immediately, remove the grant in the Project or revoke the tokens.

How the effective role is decided is described in Permissions and roles.