Okta SSO
Audience: Okta administrators wiring OIDC or SAML for TokenTimer Enterprise.
Multi-provider SSO: Configure each Okta 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. okta for OIDC or SAML).
| Purpose | Value |
|---|---|
| OIDC Sign-in redirect URI | https://tokentimer.example.com/auth/oidc/<slug>/callback |
| SAML ACS URL | https://tokentimer.example.com/auth/saml/<slug>/callback |
Part A: OpenID Connect (recommended)
A.1 Create app integration
- Okta Admin Console, Applications, Applications, Create App Integration (create app).
- Sign-in method: OIDC - OpenID Connect.
- Application type: Web Application (confidential client with secret).
- Grant type: Authorization Code (auth code guide).
A.2 URIs and credentials
| Okta field | Value |
|---|---|
| Sign-in redirect URIs | https://tokentimer.example.com/auth/oidc/<slug>/callback |
| Sign-out redirect URIs (optional) | https://tokentimer.example.com/login |
| Controlled access | Assign users/groups who may use TokenTimer |
On the app General tab, copy Client ID and Client secret into
SSO Providers (or your bootstrap manifest and SSO_<SLUG>_OIDC_CLIENT_SECRET).
A.3 Issuer (authorization server)
Okta exposes one issuer per authorization server. For the built-in default custom authorization server:
https://<yourOktaDomain>/oauth2/default
Example discovery:
https://<yourOktaDomain>/oauth2/default/.well-known/openid-configuration
Set Issuer in SSO Providers to the issuer field from that document.
If you use a custom authorization server, open Security, API,
Authorization Servers, select the server, and copy its Issuer URI (each
server has its own /.well-known/openid-configuration).
A.4 Scopes and claims
Assign the openid, profile, and email scopes to the app (Okta OpenID Connect / Scopes tab or via the authorization server).
Groups for role mapping:
- Directory, Profile Editor, user profile, or use a Groups claim in the authorization server.
- Common pattern: add a groups claim to the ID token or userinfo via an Authorization Server claim (customize tokens).
In SSO Providers under Claim mapping:
| Field | Paths |
|---|---|
email | |
| Display name | name |
| Groups | groups |
| Subject | sub |
A.5 TokenTimer configuration
In SSO Providers (slug e.g. okta):
| Field | Value |
|---|---|
| Issuer | https://<yourOktaDomain>/oauth2/default |
| Client ID | <client-id> |
| Scopes | openid profile email |
SSO_OKTA_OIDC_CLIENT_SECRET=<client-secret>
API_URL=https://tokentimer.example.com
APP_URL=https://tokentimer.example.com
A.6 Verify OIDC
GET /api/auth/featuresreturns your slug inproviders.oidc[]withsignInReady: true.- Use the provider button on the login page (label =
displayName, e.g. Sign in with Okta). - Confirm System Settings → Single Sign-On mappings match Okta group names (case-insensitive).
Part B: SAML 2.0
TokenTimer is the SP; Okta is the IdP.
B.1 Create SAML integration
- Create App Integration, SAML 2.0 (SAML wizard).
- General Settings: name e.g.
TokenTimer Enterprise.
Configure SAML (field reference):
| Okta field | Value |
|---|---|
| Single sign-on URL (Recipient / Destination default) | Often same as ACS; TokenTimer initiates SP flow via /auth/saml/<slug> |
| Audience URI (SP Entity ID) | SP entity ID on the provider row (config.issuer), e.g. https://tokentimer.example.com/saml |
| Default RelayState | Leave blank unless you use IdP-initiated SSO with a fixed landing page |
| Name ID format | EmailAddress or Persistent (match your directory) |
| Application username | Okta username or email attribute |
| Attribute Statements (examples) | email from user.email, displayName from user.displayName |
| Group Attribute Statements | Filter: Matches regex .* into groups (or your group attribute name) |
ACS URL: In the SAML wizard, set the Assertion Consumer Service URL to (TokenTimer accepts the SAML response via HTTP POST):
https://tokentimer.example.com/auth/saml/<slug>/callback
If the wizard only shows Single sign-on URL, use the ACS URL above for the POST consumer endpoint; Okta sends the SAML response to the ACS URL on SP-initiated flows.
B.2 Okta metadata for TokenTimer
- Sign On tab, View SAML setup instructions or Identity Provider metadata.
- Identity Provider Single Sign-On URL goes to
config.entry_pointin SSO Providers. - Identity Provider Issuer (entity ID) is Okta's issuer; TokenTimer validates
with
config.entry_pointplus IdP cert. - Download X.509 Certificate into
SSO_<SLUG>_SAML_CERT(PEM).
In System Settings → Manage SSO providers (slug e.g. okta):
| Field | Value |
|---|---|
| Entry point | https://<yourOktaDomain>/app/<appName>/<appId>/sso/saml |
| SP entity ID | https://tokentimer.example.com/saml |
| IdP cert | via SSO_OKTA_SAML_CERT env or UI upload |
Claim paths in Claim mapping:
| Field | Paths |
|---|---|
email, urn:oid:0.9.2342.19200300.100.1.3 | |
| Display name | displayName |
| Groups | groups |
| Subject | nameID |
B.3 Assign and test
- Assignments tab: assign users/groups.
- Open
https://tokentimer.example.com/auth/saml/<slug>or use Okta Test with SAML.
B.4 Verify SAML
GET /api/auth/featuresreturns your slug inproviders.saml[]withsignInReady: true.- Use the provider button on the login page (label =
displayName). - Confirm System Settings → Single Sign-On mappings match Okta group names (case-insensitive).
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
invalid_client | Wrong secret or wrong auth server | Match client to issuer's authorization server |
| Redirect mismatch | URI not listed | Add exact callback to app integration |
Invalid issuer | Issuer is org URL, not /oauth2/default | Copy issuer from discovery JSON into SSO Providers |
| SAML ACS mismatch | Wrong ACS in Okta | Set ACS to /auth/saml/<slug>/callback |
| No groups | Missing group attribute statement | Add groups claim/attribute in SAML app |