Microsoft Entra ID (Azure AD) SSO
Audience: Entra administrators wiring OIDC or SAML for TokenTimer Enterprise.
Multi-provider SSO: Configure each Entra app under System Settings → Manage SSO providers (or bootstrap via
sso-providers.json/ HelmssoProviders[]). URLs are slug-scoped. See the OIDC quickstart or SAML quickstart first.
See the SSO identity provider guides for shared prerequisites and callback URLs. Claim paths: Claim mapping.
URLs to register
Replace <slug> with your provider slug (e.g. entra; use two distinct slugs if you run OIDC and SAML for the same tenant).
| Purpose | Value |
|---|---|
| OIDC redirect URI (Web platform) | https://tokentimer.example.com/auth/oidc/<slug>/callback |
| SAML Reply URL (ACS) | https://tokentimer.example.com/auth/saml/<slug>/callback |
Part A: OpenID Connect (recommended)
A.1 App registration
- Microsoft Entra admin center, then Entra ID, App registrations, New registration (quickstart).
- Name: e.g.
TokenTimer Enterprise. - Supported account types: Single tenant for one organization; use multitenant only if you intentionally serve multiple Entra tenants.
- Register and note:
- Application (client) ID: goes to
config.client_id - Directory (tenant) ID: used in issuer URL below
- Application (client) ID: goes to
A.2 Redirect URI and client secret
- Authentication, Add a platform, Web (how-to).
- Do not use SPA if you need a client secret (TokenTimer is a confidential server-side client).
- Redirect URIs:
https://tokentimer.example.com/auth/oidc/<slug>/callback(exact match with the URL shown in SSO Providers). - Certificates & secrets, New client secret, store as
SSO_<SLUG>_OIDC_CLIENT_SECRETor in SSO Providers.
A.3 Issuer and discovery
Use the v2.0 issuer (matches tokens from the v2.0 authorize endpoint):
https://login.microsoftonline.com/<tenant-id>/v2.0
Replace <tenant-id> with your Directory (tenant) ID. Confirm discovery:
https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration
Set Issuer in SSO Providers to the issuer value from that JSON
(typically ends in /v2.0, no trailing slash unless discovery shows one).
A.4 API permissions / scopes
Under API permissions, Microsoft Graph User.Read is added by default for
sign-in. TokenTimer requests openid profile email (default scopes on the provider row).
Optional: email optional claim if managed users do not get email in the ID
token (optional claims).
A.5 Groups in the token
Entra does not include all group memberships in every token by default. For SSO
role mapping you need a groups claim (or map roles another way).
- Token configuration (app registration), Add groups claim, or edit
the app manifest
groupMembershipClaims(optional claims / groups). - Choose Security groups or All groups as appropriate.
- If the user is in more than 200 groups (JWT limit), Entra emits
hasgroupsinstead of listing groups; you must use Graph or reduce groups (groups overage).
Claim paths in SSO Providers under Claim mapping:
| Field | Paths |
|---|---|
email | |
| Display name | name |
| Groups | groups |
| Subject | oid |
Use oid (object ID) as subject, not sub: sub is pairwise per client app;
oid is stable across apps in the tenant (ID token claims).
Group values are often object IDs. Map those IDs under System Settings → Single Sign-On, or configure Entra to emit group display names if your process
requires names. If your Entra plan does not allow group assignment to Enterprise Applications, display-name group emission may not be available; use object IDs from idp_groups_sample or map Entra app roles instead.
A.6 TokenTimer configuration
In System Settings → Manage SSO providers (slug e.g. entra):
| Field | Value |
|---|---|
| Issuer | https://login.microsoftonline.com/<tenant-id>/v2.0 |
| Client ID | <application-client-id> |
| Scopes | openid profile email |
SSO_ENTRA_OIDC_CLIENT_SECRET=<secret>
API_URL=https://tokentimer.example.com
APP_URL=https://tokentimer.example.com
Helm: use helm/examples/values-sso-basic-oidc.yaml from the delivery as a template; set
oidc.clientSecretRef and the matching tokentimer.api.envFrom block, or put SSO_<SLUG>_OIDC_CLIENT_SECRET on <release>-enterprise-secrets.
A.7 Verify OIDC
- System Settings → License shows a valid license with OIDC entitlement (
feature:oidc). GET /api/auth/featuresreturns your slug inproviders.oidc[]withsignInReady: true.- Login page shows the provider button (e.g. Sign in with Azure AD); Entra login lands on the dashboard.
- Audit:
LOGIN_SUCCESS,method=oidc,idp_groups_seenwhen groups are present.
Part B: SAML 2.0
Use SAML when OIDC is not an option. TokenTimer is the SAML service provider (SP); Entra is the identity provider (IdP).
B.1 Enterprise application
- Entra ID, Enterprise applications, New application, Create your own application (non-gallery) (SAML SSO setup).
- Single sign-on, then SAML.
- Basic SAML Configuration, Edit:
| Entra field | TokenTimer value |
|---|---|
| Identifier (Entity ID) | SP entity ID on the provider row (config.issuer), e.g. https://tokentimer.example.com/saml |
| Reply URL (Assertion Consumer Service URL) | https://tokentimer.example.com/auth/saml/<slug>/callback (TokenTimer ACS is HTTP POST) |
| Sign on URL (optional) | https://tokentimer.example.com/auth/saml/<slug> |
Optional: export TokenTimer SP metadata from
GET https://tokentimer.example.com/auth/saml/<slug>/metadata and upload to Entra if
your process uses SP-initiated federation metadata.
B.2 Attributes and groups
Attributes & Claims (SAML):
| Claim | Suggested source |
|---|---|
email or emailaddress | user.mail |
displayName | user.displayname |
groups | Group claims (or user.assignedgroups) |
TokenTimer defaults already include Microsoft group claim URIs; tune in SSO Providers under Claim mapping if needed:
| Field | Paths |
|---|---|
email, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress | |
| Display name | displayName, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name |
| Groups | groups, http://schemas.microsoft.com/ws/2008/06/identity/claims/role |
| Subject | nameID |
Group mapping tip: Entra often emits group object IDs (GUIDs), not
display names. After a test login, copy the value from the LOGIN_SUCCESS
audit field idp_groups_sample into your System Admin (global) mapping.
If your Entra plan does not allow group assignment to Enterprise Applications,
display-name group emission may not be available; use object IDs or map Entra
app roles instead.
Directory roles vs security groups: A mapping only matches values TokenTimer
reads from the SAML token (groups, roles, or wids claims). Entra Global
Administrator is a directory role, not a security group. Either assign users
to a security group, emit that group in the token, and map the group value, or
map the directory role template ID from idp_groups_sample (Global Administrator
is fe930be9-4440-434a-b55e-f9040d007299). Configure Token configuration →
Optional claims so groups or directory roles appear in the assertion.
Use a persistent NameID format when possible (SAML NameID).
B.3 Certificates and metadata
- SAML Signing Certificate: download Certificate (Base64) for the IdP
cert (
SSO_<SLUG>_SAML_CERTor upload in SSO Providers). - Set up application: copy Login URL into
config.entry_point. - Optional: upload SP metadata if you generate it; TokenTimer primarily needs
entry_point, SP entity ID (config.issuer), IdP cert, and claim paths (see the SSO identity provider guides).
In System Settings → Manage SSO providers (slug e.g. entra):
| Field | Value |
|---|---|
| Entry point | https://login.microsoftonline.com/<tenant-id>/saml2 |
| SP entity ID | https://tokentimer.example.com/saml |
| IdP cert | via SSO_ENTRA_SAML_CERT or UI upload |
Issuer in SAML responses from Entra is typically
https://sts.windows.net/<tenant-id>/; TokenTimer validates assertions using
the IdP cert and configured entry point, not Entra's issuer string in env.
B.4 Verify SAML
GET /api/auth/featuresreturns your slug inproviders.saml[]withsignInReady: true.- Assign users/groups to the enterprise app.
- Browse
https://tokentimer.example.com/auth/saml/<slug>or use the Entra Test blade. - Confirm group mappings apply after login.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
AADSTS50011 redirect mismatch | Reply/redirect URI typo | Match exact URL, scheme, no extra /api |
Invalid issuer | Wrong tenant in issuer URL | Use v2.0 issuer from discovery document in SSO Providers |
| Login OK, no roles | No groups in token | Configure groups claim; watch 200-group overage |
| Wrong user after rename | Used sub or email as subject | Set subject claim path to oid |
| SAML signature errors | Rotated IdP cert | Update IdP cert on the provider; use secondary cert during rotation |
| Callback HTTP behind TLS | Proxy trust | Set TRUST_PROXY_HOPS correctly |