From b6324d08f2a92355995e47989d839fe5be0df5fc Mon Sep 17 00:00:00 2001 From: amanda-vanscoy Date: Thu, 11 Jun 2026 14:46:36 -0400 Subject: [PATCH 01/11] First draft --- .../session-expiry-enterprise-connections.mdx | 238 ++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx new file mode 100644 index 0000000000..25a7f13af9 --- /dev/null +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -0,0 +1,238 @@ +--- +description: Learn how to enforce upstream identity provider session expiry using the IPSIE `session_expiry` claim for Okta and OIDC enterprise connections. +title: Configure Session Expiry for Enterprise Connections (IPSIE) +--- + +Auth0 supports the `session_expiry` claim based on the [IPSIE SL1 OpenID Connect Profile](https://openid.net/specs/ipsie-openid-connect-sl1-profile-1_0.html) for Okta and OIDC enterprise connections. When enabled, Auth0 captures the `session_expiry` value from the upstream identity provider (IdP) and includes the ID Token issued to your application. +The `session_expiry` claim ensures Auth0 and applications sessions cannot outlive the session the upstream IdP originally established. + + + +Before enabling session expiry enforcement: + +* Your tenant must have the `id_token_session_expiry_federated` feature flag enabled. Contact [Auth0 Support](https://support.auth0.com) to request enablement. +* You must have an existing [Okta](/docs/authenticate/identity-providers/enterprise-identity-providers/okta/express-configuration) or [OIDC](/docs/authenticate/identity-providers/enterprise-identity-providers/oidc) Enterprise connection. +* The upstream identity provider must emit a `session_expiry` claim in its ID token. +* If you use Auth0 SDKs (Next.js, Express, React, iOS, Android, and others), they enforce the session ceiling automatically. No additional application code is required. + + + + + +This feature is supported for **Okta and OIDC enterprise connections only**. It is not available for Microsoft Entra ID (Azure AD) connections. Microsoft does not include the `session_expiry` claim in Entra ID tokens. + + + +## How it works + +When a user authenticates through a `session_expiry`-enabled Enterprise connection, Auth0: + +1. Captures the `session_expiry` claim from the upstream IdP's ID token. +2. Computes the effective session ceiling as the minimum of: the tenant's configured absolute session lifetime, the upstream `session_expiry` value, and any value set by a Post-Login Action. +3. Includes the computed `session_expiry` value in the ID token issued to your application. + +The `session_expiry` claim is a Unix timestamp (integer, seconds since epoch) representing the absolute ceiling for the user's session: + +```json +{ + "iss": "https://YOUR_DOMAIN.auth0.com/", + "aud": "YOUR_CLIENT_ID", + "sub": "oidc|user@example.com", + "iat": 1748534400, + "exp": 1748538000, + "session_expiry": 1748566800 +} +``` + +| Claim | What it represents | Scope | +| --- | --- | --- | +| `exp` | ID token lifetime (typically minutes) | Token validation | +| `session_expiry` | Application session ceiling (hours or days) | Session management | +| Idle timeout | Inactivity limit | Separate, configured in tenant settings | + +`session_expiry` is **not** a replacement for `exp`. The ID token's own `exp` remains short-lived and unchanged. `session_expiry` is a session-level ceiling that travels alongside the token claims. + +**`session_expiry` is fixed at login.** It is set once when the user authenticates and is not updated when tokens are refreshed. A user already logged in before this feature is enabled will not have `session_expiry` on their existing session; the claim only appears after their next login. + + + +This feature addresses scheduled session expiry only. For real-time revocation — for example, when a user is off-boarded mid-session — use [Back-Channel Logout](/docs/authenticate/login/logout/back-channel-logout). + + + +## Enable session expiry enforcement + +Configure session expiry enforcement on your Enterprise connection using the Auth0 Dashboard or Management API. + + + + +1. Navigate to [**Authentication > Enterprise**](https://manage.auth0.com/#/connections/enterprise) in the Auth0 Dashboard. +2. Select the Okta or OIDC Enterprise connection you want to configure. +3. Select the **Settings** tab. +4. Enable **Enforce upstream session expiry (IPSIE)**. +5. Select **Save**. + + + + +To use the Management API, you need a [Management API access token](/docs/secure/tokens/access-tokens/management-api-access-tokens) with `update:connections` scope. + +Make a `PATCH` request to the [Update a connection](https://auth0.com/docs/api/management/v2/connections/patch-connections-by-id) endpoint: + +```curl +PATCH https://YOUR_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID +Content-Type: application/json +Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN + +{ + "options": { + "id_token_session_expiry_supported": true + } +} +``` + +Replace the placeholder values: + +* **YOUR_DOMAIN**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. +* **YOUR_CONNECTION_ID**: The ID of your Okta or OIDC Enterprise connection. +* **YOUR_MANAGEMENT_API_TOKEN**: A Management API token with `update:connections` scope. + + + +If you `PATCH` the `options` parameter, the entire `options` object is overridden. Ensure all existing properties are included when you `PATCH` `options`. + + + + + + +## SDK behavior + +If you use Auth0 SDKs, session expiry is enforced automatically with no changes to your application code. The SDK reads `session_expiry` at login, persists it with the session, and treats the session as expired once the current time reaches or passes `session_expiry`: + +| SDK type | How expiry is enforced | +| --- | --- | +| **Regular Web App** (Next.js, Express, Python) | Middleware clears the session and redirects with `prompt=login`; `getAccessToken()` throws `SessionExpiredError` | +| **Single-Page App** (React, Angular, Vue) | `getTokenSilently()` / `getAccessTokenSilently()` rejects and triggers re-login with `prompt=login` | +| **Mobile** (iOS/Swift, Android/Kotlin) | `CredentialsManager.credentials()` returns `noCredentials` and the app's existing login path handles re-authentication | + +When a session expires due to `session_expiry`, the SDK behaves the same as it would for any other session expiry: the user is redirected to log in. No additional error handling is required. + +## Read the session expiry value in your app (optional) + +You can read `session_expiry` to show users a session-expiring warning or to bind your application's own session lifetime to the upstream IdP's value. + + + + +```javascript +const claims = await auth0.getIdTokenClaims(); +const sessionExpiresAt = claims?.session_expiry; // Unix seconds +const remainingSeconds = sessionExpiresAt - Math.floor(Date.now() / 1000); +``` + + + + +```javascript +const session = await auth0.getSession(); +const sessionExpiresAt = session?.sessionExpiresAt; // top-level field, Unix seconds +const remainingSeconds = (sessionExpiresAt ?? Infinity) - Math.floor(Date.now() / 1000); +``` + + + + +```swift +credentialsManager.credentials { result in + switch result { + case .success(let credentials): + let sessionExpiresAt = credentials.idToken?.session_expiry // Unix seconds + case .failure: + startLogin() + } +} +``` + + + + +Do not persist the `session_expiry` value in a long-lived store — such as a cookie or `localStorage` — without re-validating it on each read. The value is only meaningful relative to the current wall-clock time. + +## Customize session behavior with Post-Login Actions + +A [Post-Login Action](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) can read the upstream IdP's `session_expiry` value and use it to control session and token behavior. If you need to enforce a stricter expiry than the IdP asserts, you can set the session to expire sooner. However, the Action-set value is **upper-capped by the IdP's `session_expiry`** — it cannot extend the session beyond what the IdP permits. + +```javascript +exports.onExecutePostLogin = async (event, api) => { + const idpExpiry = event.authentication?.session_expiry; + if (idpExpiry) { + // Bind the Auth0 session to the IdP's session_expiry value. + api.session.setExpiresAt(idpExpiry); + // Ensure the claim appears in the ID token. + api.idToken.setCustomClaim("session_expiry", idpExpiry); + } +}; +``` + +To enforce a shorter session — for example, limiting to 8 hours regardless of the IdP value — pass an earlier timestamp to `setExpiresAt`. Passing a value later than `idpExpiry` has no effect; the IdP's value remains the ceiling. + +To learn more about the `api.session` methods available in Post-Login Actions, read [Configure Session Lifetime](/docs/manage-users/sessions/configure-session-lifetime). + +## Verify in tenant logs + +After enabling session expiry enforcement, verify the feature is working by checking [tenant logs](/docs/deploy-monitor/logs). + +Navigate to [**Auth0 Dashboard > Monitoring > Logs**](https://manage.auth0.com/#/logs) and look for a successful login (`s`) event for a user authenticating through the configured Enterprise connection. When the upstream IdP's `session_expiry` is less than or equal to your tenant's configured absolute session lifetime, the log entry includes the `idp_session_expiry` field (a Unix timestamp in milliseconds): + +```json +{ + "type": "s", + "description": "Success Login", + "details": { + "idp_session_expiry": 1748566800000 + } +} +``` + +If `idp_session_expiry` is absent from the `s` log, the upstream IdP either did not assert a `session_expiry` claim or its value exceeds the tenant's configured maximum — in which case the tenant's own absolute session lifetime is the ceiling. + +## Disable session expiry enforcement + + + + +1. Navigate to [**Authentication > Enterprise**](https://manage.auth0.com/#/connections/enterprise) in the Auth0 Dashboard. +2. Select the connection you want to configure. +3. Select the **Settings** tab. +4. Disable **Enforce upstream session expiry (IPSIE)**. +5. Select **Save**. + + + + +Set `id_token_session_expiry_supported` to `false` in your connection options: + +```curl +PATCH https://YOUR_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID +Content-Type: application/json +Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN + +{ + "options": { + "id_token_session_expiry_supported": false + } +} +``` + + + + +## Learn more + +* [Session Lifecycle](/docs/manage-users/sessions/session-lifecycle) +* [Configure Session Lifetime](/docs/manage-users/sessions/configure-session-lifetime) +* [Sessions with Actions](/docs/manage-users/sessions/manage-sessions-actions) +* [Back-Channel Logout](/docs/authenticate/login/logout/back-channel-logout) +* [IPSIE SL1 OpenID Connect Profile](https://openid.net/specs/ipsie-openid-connect-sl1-profile-1_0.html) From f3fe9525efba753d3f8d13335c2d10c652455496 Mon Sep 17 00:00:00 2001 From: amanda-vanscoy Date: Thu, 11 Jun 2026 14:48:34 -0400 Subject: [PATCH 02/11] docs: update session expiry for enterprise connections content and navigation - Add navigation entry for session-expiry-enterprise-connections page - Move warning callout above intro paragraph for better visibility - Improve content clarity: consistent ID Token casing, cleaner phrasing, and linked references - Add session expiry section to session-lifecycle page with link to new article Co-Authored-By: Claude Sonnet 4.6 --- main/config/navigation/authenticate.json | 3 +- .../session-expiry-enterprise-connections.mdx | 57 +++++++++---------- .../sessions/session-lifecycle.mdx | 6 ++ 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/main/config/navigation/authenticate.json b/main/config/navigation/authenticate.json index f2cb9b6532..141ff04613 100644 --- a/main/config/navigation/authenticate.json +++ b/main/config/navigation/authenticate.json @@ -345,7 +345,8 @@ ] }, "docs/authenticate/enterprise-connections/private-key-jwt-client-auth", - "docs/authenticate/enterprise-connections/enable-dpop-enterprise-connections" + "docs/authenticate/enterprise-connections/enable-dpop-enterprise-connections", + "docs/authenticate/enterprise-connections/session-expiry-enterprise-connections" ] }, { diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index 25a7f13af9..349a95e661 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -1,9 +1,15 @@ --- -description: Learn how to enforce upstream identity provider session expiry using the IPSIE `session_expiry` claim for Okta and OIDC enterprise connections. +description: Learn how to enforce upstream identity provider session expiry using the IPSIE `session_expiry` claim for Okta and OIDC Enterprise connections. title: Configure Session Expiry for Enterprise Connections (IPSIE) --- -Auth0 supports the `session_expiry` claim based on the [IPSIE SL1 OpenID Connect Profile](https://openid.net/specs/ipsie-openid-connect-sl1-profile-1_0.html) for Okta and OIDC enterprise connections. When enabled, Auth0 captures the `session_expiry` value from the upstream identity provider (IdP) and includes the ID Token issued to your application. + + +Session Expiry is supported for **Okta and OIDC Enterprise connections only**. It is not available for Microsoft Entra ID (Azure AD) connections. Microsoft does not include the `session_expiry` claim in Entra ID Tokens. + + + +Auth0 supports the `session_expiry` claim based on the [IPSIE SL1 OpenID Connect Profile](https://openid.net/specs/ipsie-openid-connect-sl1-profile-1_0.html) for Okta and OIDC Enterprise connections. When enabled, Auth0 captures the `session_expiry` value from the upstream identity provider (IdP) and includes the ID Token issued to your application. The `session_expiry` claim ensures Auth0 and applications sessions cannot outlive the session the upstream IdP originally established. @@ -12,30 +18,23 @@ Before enabling session expiry enforcement: * Your tenant must have the `id_token_session_expiry_federated` feature flag enabled. Contact [Auth0 Support](https://support.auth0.com) to request enablement. * You must have an existing [Okta](/docs/authenticate/identity-providers/enterprise-identity-providers/okta/express-configuration) or [OIDC](/docs/authenticate/identity-providers/enterprise-identity-providers/oidc) Enterprise connection. -* The upstream identity provider must emit a `session_expiry` claim in its ID token. -* If you use Auth0 SDKs (Next.js, Express, React, iOS, Android, and others), they enforce the session ceiling automatically. No additional application code is required. +* The upstream identity provider must emit a `session_expiry` claim in its ID Token. - - -This feature is supported for **Okta and OIDC enterprise connections only**. It is not available for Microsoft Entra ID (Azure AD) connections. Microsoft does not include the `session_expiry` claim in Entra ID tokens. - - - ## How it works When a user authenticates through a `session_expiry`-enabled Enterprise connection, Auth0: -1. Captures the `session_expiry` claim from the upstream IdP's ID token. -2. Computes the effective session ceiling as the minimum of: the tenant's configured absolute session lifetime, the upstream `session_expiry` value, and any value set by a Post-Login Action. -3. Includes the computed `session_expiry` value in the ID token issued to your application. +1. Captures the `session_expiry` claim from the upstream IdP's ID Token. +2. Computes the effective session expiration as the minimum of the tenant's configured absolute session lifetime, the upstream `session_expiry` value, and any value set by a [Post-Login Action](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger). +3. Includes the computed `session_expiry` value in the ID Token issued to your application. -The `session_expiry` claim is a Unix timestamp (integer, seconds since epoch) representing the absolute ceiling for the user's session: +The `session_expiry` claim is a [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds representing the absolute expiration limit for the user's session: ```json { - "iss": "https://YOUR_DOMAIN.auth0.com/", + "iss": "https://YOUR_AUTH_DOMAIN.auth0.com/", "aud": "YOUR_CLIENT_ID", "sub": "oidc|user@example.com", "iat": 1748534400, @@ -46,17 +45,17 @@ The `session_expiry` claim is a Unix timestamp (integer, seconds since epoch) re | Claim | What it represents | Scope | | --- | --- | --- | -| `exp` | ID token lifetime (typically minutes) | Token validation | +| `exp` | ID Token lifetime (typically minutes) | Token validation | | `session_expiry` | Application session ceiling (hours or days) | Session management | | Idle timeout | Inactivity limit | Separate, configured in tenant settings | -`session_expiry` is **not** a replacement for `exp`. The ID token's own `exp` remains short-lived and unchanged. `session_expiry` is a session-level ceiling that travels alongside the token claims. +The session expiry claim is **not** a replacement for `exp`. The ID Token's own `exp` remains short-lived and unchanged. `session_expiry` is a session-level limit included with the token claims. **`session_expiry` is fixed at login.** It is set once when the user authenticates and is not updated when tokens are refreshed. A user already logged in before this feature is enabled will not have `session_expiry` on their existing session; the claim only appears after their next login. -This feature addresses scheduled session expiry only. For real-time revocation — for example, when a user is off-boarded mid-session — use [Back-Channel Logout](/docs/authenticate/login/logout/back-channel-logout). +This feature addresses scheduled session expiry only. For real-time session revocation, like when a user is off-boarded mid-session, we recommend you use [Back-Channel Logout](/docs/authenticate/login/logout/back-channel-logout). @@ -94,9 +93,9 @@ Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN Replace the placeholder values: -* **YOUR_DOMAIN**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. -* **YOUR_CONNECTION_ID**: The ID of your Okta or OIDC Enterprise connection. -* **YOUR_MANAGEMENT_API_TOKEN**: A Management API token with `update:connections` scope. +* **`YOUR_DOMAIN`**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. +* **`YOUR_CONNECTION_ID`**: The ID of your Okta or OIDC Enterprise connection. +* **`YOUR_MANAGEMENT_API_TOKEN`**: A Management API token with `update:connections` scope. @@ -109,7 +108,7 @@ If you `PATCH` the `options` parameter, the entire `options` object is overridde ## SDK behavior -If you use Auth0 SDKs, session expiry is enforced automatically with no changes to your application code. The SDK reads `session_expiry` at login, persists it with the session, and treats the session as expired once the current time reaches or passes `session_expiry`: +If you use [Auth0 SDKs](/docs/libraries), session expiry is enforced automatically with no changes to your application code. The SDK reads `session_expiry` at login, persists it with the session, and treats the session as expired once the current time reaches or passes `session_expiry`: | SDK type | How expiry is enforced | | --- | --- | @@ -117,11 +116,11 @@ If you use Auth0 SDKs, session expiry is enforced automatically with no changes | **Single-Page App** (React, Angular, Vue) | `getTokenSilently()` / `getAccessTokenSilently()` rejects and triggers re-login with `prompt=login` | | **Mobile** (iOS/Swift, Android/Kotlin) | `CredentialsManager.credentials()` returns `noCredentials` and the app's existing login path handles re-authentication | -When a session expires due to `session_expiry`, the SDK behaves the same as it would for any other session expiry: the user is redirected to log in. No additional error handling is required. +When a session expires due to the`session_expiry` claim, the SDK behaves the same as it would for any other session expiry: the user is redirected to log in. No additional error handling is required. -## Read the session expiry value in your app (optional) +## Session expiry value in your app (optional) -You can read `session_expiry` to show users a session-expiring warning or to bind your application's own session lifetime to the upstream IdP's value. +Your application can read `session_expiry` to show users a session-expiring warning or to bind your application's own session lifetime to the upstream IdP's value. @@ -158,11 +157,11 @@ credentialsManager.credentials { result in -Do not persist the `session_expiry` value in a long-lived store — such as a cookie or `localStorage` — without re-validating it on each read. The value is only meaningful relative to the current wall-clock time. +Do not persist the `session_expiry` value in a long-lived store, such as a cookie or `localStorage`, without re-validating it on each read. The value is only meaningful relative to the current wall-clock time. ## Customize session behavior with Post-Login Actions -A [Post-Login Action](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) can read the upstream IdP's `session_expiry` value and use it to control session and token behavior. If you need to enforce a stricter expiry than the IdP asserts, you can set the session to expire sooner. However, the Action-set value is **upper-capped by the IdP's `session_expiry`** — it cannot extend the session beyond what the IdP permits. +A [Post-Login Action](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) can read the upstream IdP's `session_expiry` value and use it to control session and token behavior. If you need to enforce a stricter expiry than the IdP asserts, you can set the session to expire sooner. However, the Action-set value is capped by the IdP's `session_expiry` and the session cannot extend beyond what the IdP permits. ```javascript exports.onExecutePostLogin = async (event, api) => { @@ -170,13 +169,13 @@ exports.onExecutePostLogin = async (event, api) => { if (idpExpiry) { // Bind the Auth0 session to the IdP's session_expiry value. api.session.setExpiresAt(idpExpiry); - // Ensure the claim appears in the ID token. + // Ensure the claim appears in the ID Token. api.idToken.setCustomClaim("session_expiry", idpExpiry); } }; ``` -To enforce a shorter session — for example, limiting to 8 hours regardless of the IdP value — pass an earlier timestamp to `setExpiresAt`. Passing a value later than `idpExpiry` has no effect; the IdP's value remains the ceiling. +To enforce a shorter session, pass an earlier timestamp to `setExpiresAt`. For example, if you want to enforce an 8 hour session regardless of the IdP's session limitation. Passing a value later than `idpExpiry` has no effect; the IdP's value remains the ceiling. To learn more about the `api.session` methods available in Post-Login Actions, read [Configure Session Lifetime](/docs/manage-users/sessions/configure-session-lifetime). diff --git a/main/docs/manage-users/sessions/session-lifecycle.mdx b/main/docs/manage-users/sessions/session-lifecycle.mdx index e37e74b76c..17eec9606a 100644 --- a/main/docs/manage-users/sessions/session-lifecycle.mdx +++ b/main/docs/manage-users/sessions/session-lifecycle.mdx @@ -52,6 +52,12 @@ Session lifetime has the following limits: | Persistent | Inactivity timeout | Timeframe after which a session expires if there’s no interaction with the Authorization Server | 3 days | 100 days | | | Require Login after | Maximum session lifetime, regardless of activity | 30 days | 365 days | +## Session expiry from upstream identity providers + +When using Okta or OIDC enterprise connections, you can enforce the session lifetime asserted by the upstream identity provider. Auth0 captures the `session_expiry` claim from the upstream IdP's ID token and uses it as an upper bound on the user's session — ensuring Auth0 sessions cannot outlive the IdP session that created them. + +To learn more, read [Configure Session Expiry for Enterprise Connections (IPSIE)](/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections). + ## Next steps * To learn more about using Actions to configure the session lifecycle, read [Sessions with Actions](/docs/manage-users/sessions/manage-sessions-actions). From aba519465bba61ec0b4acab38ceda81bc388f00e Mon Sep 17 00:00:00 2001 From: amanda-vanscoy Date: Thu, 11 Jun 2026 16:46:34 -0400 Subject: [PATCH 03/11] Minor changes --- .../session-expiry-enterprise-connections.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index 349a95e661..cb89ce90c0 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -175,7 +175,7 @@ exports.onExecutePostLogin = async (event, api) => { }; ``` -To enforce a shorter session, pass an earlier timestamp to `setExpiresAt`. For example, if you want to enforce an 8 hour session regardless of the IdP's session limitation. Passing a value later than `idpExpiry` has no effect; the IdP's value remains the ceiling. +To enforce a shorter session, pass an earlier timestamp to `setExpiresAt`. For example, if you want to enforce an 8 hour session regardless of the IdP's session Passing a value later than `idpExpiry` has no effect; the IdP's value remains the ceiling. To learn more about the `api.session` methods available in Post-Login Actions, read [Configure Session Lifetime](/docs/manage-users/sessions/configure-session-lifetime). From cf633a7f64c14935dad3a2a8f30aad2cf4cb63ec Mon Sep 17 00:00:00 2001 From: amanda-vanscoy Date: Tue, 23 Jun 2026 17:11:42 -0400 Subject: [PATCH 04/11] Updated with Auth0 Actions and requested Legal verbage --- .../session-expiry-enterprise-connections.mdx | 155 ++++++++++++++---- 1 file changed, 120 insertions(+), 35 deletions(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index cb89ce90c0..392a32477a 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -3,20 +3,22 @@ description: Learn how to enforce upstream identity provider session expiry usin title: Configure Session Expiry for Enterprise Connections (IPSIE) --- - + Session Expiry is supported for **Okta and OIDC Enterprise connections only**. It is not available for Microsoft Entra ID (Azure AD) connections. Microsoft does not include the `session_expiry` claim in Entra ID Tokens. - + + +Auth0 supports the `session_expiry` claim based on the [Interoperability Profile for Secure Identity in the Enterprise (IPSIE) standard](https://openid.net/specs/ipsie-openid-connect-sl1-profile-1_0.html) for Okta and OIDC Enterprise connections. When enabled, Auth0 captures the `session_expiry` (represented in seconds as a Unix timestamp) from the upstream Identity Provider (IdP) and includes the ID Token issued to your application. Auth0 consumes the `session_expiry` claim and syncronizes the local Auth0 session with the upstream IdP's session lifecycle, and ensure when a user's session expires at the enterprise IdP, their Auth0 session also terminates. -Auth0 supports the `session_expiry` claim based on the [IPSIE SL1 OpenID Connect Profile](https://openid.net/specs/ipsie-openid-connect-sl1-profile-1_0.html) for Okta and OIDC Enterprise connections. When enabled, Auth0 captures the `session_expiry` value from the upstream identity provider (IdP) and includes the ID Token issued to your application. -The `session_expiry` claim ensures Auth0 and applications sessions cannot outlive the session the upstream IdP originally established. + +The customer is responsible for processing the received `session_expiry` claim and to terminate and manage user sessions in their applications. + Before enabling session expiry enforcement: -* Your tenant must have the `id_token_session_expiry_federated` feature flag enabled. Contact [Auth0 Support](https://support.auth0.com) to request enablement. * You must have an existing [Okta](/docs/authenticate/identity-providers/enterprise-identity-providers/okta/express-configuration) or [OIDC](/docs/authenticate/identity-providers/enterprise-identity-providers/oidc) Enterprise connection. * The upstream identity provider must emit a `session_expiry` claim in its ID Token. @@ -26,17 +28,20 @@ Before enabling session expiry enforcement: When a user authenticates through a `session_expiry`-enabled Enterprise connection, Auth0: -1. Captures the `session_expiry` claim from the upstream IdP's ID Token. -2. Computes the effective session expiration as the minimum of the tenant's configured absolute session lifetime, the upstream `session_expiry` value, and any value set by a [Post-Login Action](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger). -3. Includes the computed `session_expiry` value in the ID Token issued to your application. +1. Auth0 captures the `session_expiry` claim from the upstream IdP's ID Token. +2. Auth0 calculates session expiration by evaluating specific parameters and sets the final Auth0 sessions expiration to the minimum (earliest) value of the following factors: + * The IdP `session_expiry` claim: The absolute timestamp in an ID Token from the upstream Identity Provider. + * Your Auth0 tenant's default Absolute Expiration setting: The session lifetime limit you configure in Auth0 Dashboard or Management API. To learn more, read [Configure Session Lifetime Settings](/docs/manage-users/sessions/configure-session-lifetime-settings). + *Auth0 Actions [`setExpiresAt`]: Any custom expiration timestamp programmatically set during the login transaction with the Post-Login Action [`api.session.setExpiresAt()`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object#api-session-setexpiresat-absolute) method. +3. The final evaluated session expiration passes to your application by injecting it as a [custom claim](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object#api-idtoken-setcustomclaim-key-value) into the Auth0-issued ID Token with a Post-Login Action you configure during enablement. The `session_expiry` claim is a [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds representing the absolute expiration limit for the user's session: ```json { - "iss": "https://YOUR_AUTH_DOMAIN.auth0.com/", + "iss": "https://YOUR_AUTH0_DOMAIN.auth0.com/", "aud": "YOUR_CLIENT_ID", - "sub": "oidc|user@example.com", + "sub": "oidc|username@domain.com", "iat": 1748534400, "exp": 1748538000, "session_expiry": 1748566800 @@ -49,7 +54,7 @@ The `session_expiry` claim is a [UNIX timestamp](https://en.wikipedia.org/wiki/U | `session_expiry` | Application session ceiling (hours or days) | Session management | | Idle timeout | Inactivity limit | Separate, configured in tenant settings | -The session expiry claim is **not** a replacement for `exp`. The ID Token's own `exp` remains short-lived and unchanged. `session_expiry` is a session-level limit included with the token claims. +The `session_expiry` claim is not a replacement for `exp`. The ID Token's own `exp` remains short-lived and unchanged. `session_expiry` is a session-level limit included with the token claims. **`session_expiry` is fixed at login.** It is set once when the user authenticates and is not updated when tokens are refreshed. A user already logged in before this feature is enabled will not have `session_expiry` on their existing session; the claim only appears after their next login. @@ -80,7 +85,7 @@ To use the Management API, you need a [Management API access token](/docs/secure Make a `PATCH` request to the [Update a connection](https://auth0.com/docs/api/management/v2/connections/patch-connections-by-id) endpoint: ```curl -PATCH https://YOUR_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID +PATCH https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN @@ -93,7 +98,7 @@ Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN Replace the placeholder values: -* **`YOUR_DOMAIN`**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. +* **`YOUR_AUTH0_DOMAIN`**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. * **`YOUR_CONNECTION_ID`**: The ID of your Okta or OIDC Enterprise connection. * **`YOUR_MANAGEMENT_API_TOKEN`**: A Management API token with `update:connections` scope. @@ -106,6 +111,106 @@ If you `PATCH` the `options` parameter, the entire `options` object is overridde +### Send the session_expiry claim to your application + +While Auth0 uses the calculated session expiration to manage its own session layer, your downstream applications may also need to know this absolute expiration time to enforce local session limits simultaneously. + +You can pass the final, evaluated session expiration to your application by injecting it as a custom claim into the Auth0-issued ID Token using a Post-Login Action. + + + + +1. Navigate to [**Actions > Library**](https://manage.auth0.com/#/actions/library) in the Auth0 Dashboard and select **Build Custom**. +2. Enter a name for the Action, select **Login / Post Login** as the trigger, and select **Create**. +3. Add the following code to your Action: + +```javascript +exports.onExecutePostLogin = async (event, api) => { + // Check if a session expiration has been established + if (event.session?.expires_at) { + // Convert the ISO string date to a Date object + const exp_date = new Date(event.session.expires_at); + // Set the session_expiry custom claim as a Unix timestamp (seconds) + api.idToken.setCustomClaim('session_expiry', Math.floor((exp_date.getTime()) / 1000)); + } +}; +``` + +4. Select **Deploy**. +5. Navigate to [**Actions > Flows**](https://manage.auth0.com/#/actions/flows) and select **Login**. +6. In the **Add Action** panel, locate your Action and drag it into the Login flow. Select **Apply**. + + + + +Configuring the Action via the Management API requires three steps: create the Action, deploy it, then bind it to the Login trigger. You need a [Management API access token](/docs/secure/tokens/access-tokens/management-api-access-tokens) with `create:actions`, `read:actions`, and `update:actions` scopes. + +## Create the Action + +1. Make a `POST` request to the [Create an action](https://auth0.com/docs/api/management/v2/actions/post-action) endpoint: + + ```curl + POST https://YOUR_AUTH0_DOMAIN/api/v2/actions/actions + Content-Type: application/json + Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN + + { + "name": "Set session_expiry claim", + "supported_triggers": [ + { "id": "post-login" } + ], + "code": "exports.onExecutePostLogin = async (event, api) => {\n if (event.session?.expires_at) {\n const exp_date = new Date(event.session.expires_at);\n api.idToken.setCustomClaim('session_expiry', Math.floor((exp_date.getTime()) / 1000));\n }\n};" + } + ``` + +Note the `id` value in the response since you need it in the following steps. + +## Deploy the Action + +1. Make a `POST` request to the [Deploy an action](https://auth0.com/docs/api/management/v2/actions/post-deploy-action) endpoint: + +```curl +POST https://YOUR_AUTH0_DOMAIN/api/v2/actions/actions/YOUR_ACTION_ID/deploy +Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN +``` + +## Bind the Action to the Login trigger + +1. Make a `PATCH` request to the [Update trigger bindings](https://auth0.com/docs/api/management/v2/actions/patch-bindings) endpoint: + +```curl +PATCH https://YOUR_AUTH0_DOMAIN/api/v2/actions/triggers/post-login/bindings +Content-Type: application/json +Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN + +{ + "bindings": [ + { + "ref": { + "type": "action_id", + "value": "YOUR_ACTION_ID" + }, + "display_name": "Set session_expiry claim" + } + ] +} +``` + + + +The `PATCH /api/v2/actions/triggers/post-login/bindings` request replaces all existing bindings. To preserve existing Actions in your Login flow, first retrieve your current bindings with `GET /api/v2/actions/triggers/post-login/bindings`, then include those bindings alongside the new one in your `PATCH` request. + + + +Replace the placeholder values: + +* **`YOUR_AUTH0_DOMAIN`**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. +* **`YOUR_MANAGEMENT_API_TOKEN`**: A Management API token with `create:actions`, `read:actions`, and `update:actions` scopes. +* **`YOUR_ACTION_ID`**: The `id` returned in the Create Action response. + + + + ## SDK behavior If you use [Auth0 SDKs](/docs/libraries), session expiry is enforced automatically with no changes to your application code. The SDK reads `session_expiry` at login, persists it with the session, and treats the session as expired once the current time reaches or passes `session_expiry`: @@ -159,26 +264,6 @@ credentialsManager.credentials { result in Do not persist the `session_expiry` value in a long-lived store, such as a cookie or `localStorage`, without re-validating it on each read. The value is only meaningful relative to the current wall-clock time. -## Customize session behavior with Post-Login Actions - -A [Post-Login Action](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) can read the upstream IdP's `session_expiry` value and use it to control session and token behavior. If you need to enforce a stricter expiry than the IdP asserts, you can set the session to expire sooner. However, the Action-set value is capped by the IdP's `session_expiry` and the session cannot extend beyond what the IdP permits. - -```javascript -exports.onExecutePostLogin = async (event, api) => { - const idpExpiry = event.authentication?.session_expiry; - if (idpExpiry) { - // Bind the Auth0 session to the IdP's session_expiry value. - api.session.setExpiresAt(idpExpiry); - // Ensure the claim appears in the ID Token. - api.idToken.setCustomClaim("session_expiry", idpExpiry); - } -}; -``` - -To enforce a shorter session, pass an earlier timestamp to `setExpiresAt`. For example, if you want to enforce an 8 hour session regardless of the IdP's session Passing a value later than `idpExpiry` has no effect; the IdP's value remains the ceiling. - -To learn more about the `api.session` methods available in Post-Login Actions, read [Configure Session Lifetime](/docs/manage-users/sessions/configure-session-lifetime). - ## Verify in tenant logs After enabling session expiry enforcement, verify the feature is working by checking [tenant logs](/docs/deploy-monitor/logs). @@ -195,7 +280,7 @@ Navigate to [**Auth0 Dashboard > Monitoring > Logs**](https://manage.auth0.com/# } ``` -If `idp_session_expiry` is absent from the `s` log, the upstream IdP either did not assert a `session_expiry` claim or its value exceeds the tenant's configured maximum — in which case the tenant's own absolute session lifetime is the ceiling. +If the IdP did not send a `session_expiry` claim and you enable the feature, login fails with an error message: `The upstream Identity Provider did not return a session_expiry claim`. ## Disable session expiry enforcement @@ -214,7 +299,7 @@ If `idp_session_expiry` is absent from the `s` log, the upstream IdP either did Set `id_token_session_expiry_supported` to `false` in your connection options: ```curl -PATCH https://YOUR_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID +PATCH https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN From f46591a1547292d5a3c9e99baebea111a909da65 Mon Sep 17 00:00:00 2001 From: amanda-vanscoy Date: Fri, 26 Jun 2026 10:23:35 -0400 Subject: [PATCH 05/11] fix: correct idp_session_expiry log example to seconds and update review feedback - Change idp_session_expiry log example from milliseconds (1748566800000) to seconds (1782472241) per kereslas review comment - Update description text from "milliseconds" to "seconds" to match - Address additional review feedback: Warning to Callout, heading fixes, domain placeholder corrections, H2 nesting in tabs Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../session-expiry-enterprise-connections.mdx | 79 ++++++++++--------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index 392a32477a..c03b473489 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -1,15 +1,18 @@ --- -description: Learn how to enforce upstream identity provider session expiry using the IPSIE `session_expiry` claim for Okta and OIDC Enterprise connections. title: Configure Session Expiry for Enterprise Connections (IPSIE) +description: Learn how to enforce upstream Identity Provider session expiry using the IPSIE `session_expiry` claim for Okta and OIDC Enterprise connections. +validatedOn: 2026-06-25 --- - + -Session Expiry is supported for **Okta and OIDC Enterprise connections only**. It is not available for Microsoft Entra ID (Azure AD) connections. Microsoft does not include the `session_expiry` claim in Entra ID Tokens. +Session Expiry is supported for Okta and OIDC Enterprise connections and is not available for Microsoft Entra ID (Azure AD) connections. Microsoft does not include the `session_expiry` claim in Entra ID Tokens. - + -Auth0 supports the `session_expiry` claim based on the [Interoperability Profile for Secure Identity in the Enterprise (IPSIE) standard](https://openid.net/specs/ipsie-openid-connect-sl1-profile-1_0.html) for Okta and OIDC Enterprise connections. When enabled, Auth0 captures the `session_expiry` (represented in seconds as a Unix timestamp) from the upstream Identity Provider (IdP) and includes the ID Token issued to your application. Auth0 consumes the `session_expiry` claim and syncronizes the local Auth0 session with the upstream IdP's session lifecycle, and ensure when a user's session expires at the enterprise IdP, their Auth0 session also terminates. +Auth0 supports the `session_expiry` claim based on the [Interoperability Profile for Secure Identity in the Enterprise (IPSIE) standard](https://openid.net/specs/ipsie-openid-connect-sl1-profile-1_0.html) for Okta and OIDC Enterprise connections. When enabled, Auth0 captures the `session_expiry` (represented in seconds as a Unix timestamp) from the upstream Identity Provider (IdP) and includes it in the ID Token issued to your application. + +Auth0 consumes the `session_expiry` claim and synchronizes the local Auth0 session with the upstream IdP's session lifecycle. This ensures when a user's session expires at the Enterprise IdP, their Auth0 session also terminates. The customer is responsible for processing the received `session_expiry` claim and to terminate and manage user sessions in their applications. @@ -28,18 +31,18 @@ Before enabling session expiry enforcement: When a user authenticates through a `session_expiry`-enabled Enterprise connection, Auth0: -1. Auth0 captures the `session_expiry` claim from the upstream IdP's ID Token. -2. Auth0 calculates session expiration by evaluating specific parameters and sets the final Auth0 sessions expiration to the minimum (earliest) value of the following factors: - * The IdP `session_expiry` claim: The absolute timestamp in an ID Token from the upstream Identity Provider. - * Your Auth0 tenant's default Absolute Expiration setting: The session lifetime limit you configure in Auth0 Dashboard or Management API. To learn more, read [Configure Session Lifetime Settings](/docs/manage-users/sessions/configure-session-lifetime-settings). - *Auth0 Actions [`setExpiresAt`]: Any custom expiration timestamp programmatically set during the login transaction with the Post-Login Action [`api.session.setExpiresAt()`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object#api-session-setexpiresat-absolute) method. -3. The final evaluated session expiration passes to your application by injecting it as a [custom claim](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object#api-idtoken-setcustomclaim-key-value) into the Auth0-issued ID Token with a Post-Login Action you configure during enablement. +1. Captures the `session_expiry` claim from the upstream IdP's ID Token. +2. Calculates session expiration by evaluating specific parameters and sets the final Auth0 sessions expiration to the minimum (earliest) value of the following factors: + * The IdP `session_expiry` claim: The absolute timestamp in an ID Token from the upstream Identity Provider. + * Your Auth0 tenant's default Absolute Expiration setting: The session lifetime limit you configure in Auth0 Dashboard or Management API. To learn more, read [Configure Session Lifetime Settings](/docs/manage-users/sessions/configure-session-lifetime-settings). + * Auth0 Actions [`setExpiresAt`]: Any custom expiration timestamp programmatically set during the login transaction with the Post-Login Action [`api.session.setExpiresAt()`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object#api-session-setexpiresat-absolute) method. +3. Uses a Post-Login Action you configure during enablement to pass the final evaluated session expiration to your application by injecting it as a [custom claim](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object#api-idtoken-setcustomclaim-key-value) into the Auth0-issued ID Token. The `session_expiry` claim is a [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds representing the absolute expiration limit for the user's session: ```json { - "iss": "https://YOUR_AUTH0_DOMAIN.auth0.com/", + "iss": "https://YOUR_DOMAIN.auth0.com/", "aud": "YOUR_CLIENT_ID", "sub": "oidc|username@domain.com", "iat": 1748534400, @@ -51,8 +54,7 @@ The `session_expiry` claim is a [UNIX timestamp](https://en.wikipedia.org/wiki/U | Claim | What it represents | Scope | | --- | --- | --- | | `exp` | ID Token lifetime (typically minutes) | Token validation | -| `session_expiry` | Application session ceiling (hours or days) | Session management | -| Idle timeout | Inactivity limit | Separate, configured in tenant settings | +| `session_expiry` | Absolute expiration (seconds) | Session management | The `session_expiry` claim is not a replacement for `exp`. The ID Token's own `exp` remains short-lived and unchanged. `session_expiry` is a session-level limit included with the token claims. @@ -84,8 +86,8 @@ To use the Management API, you need a [Management API access token](/docs/secure Make a `PATCH` request to the [Update a connection](https://auth0.com/docs/api/management/v2/connections/patch-connections-by-id) endpoint: -```curl -PATCH https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID +```http +PATCH https://YOUR_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN @@ -98,7 +100,7 @@ Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN Replace the placeholder values: -* **`YOUR_AUTH0_DOMAIN`**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. +* **`YOUR_DOMAIN`**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. * **`YOUR_CONNECTION_ID`**: The ID of your Okta or OIDC Enterprise connection. * **`YOUR_MANAGEMENT_API_TOKEN`**: A Management API token with `update:connections` scope. @@ -111,11 +113,9 @@ If you `PATCH` the `options` parameter, the entire `options` object is overridde -### Send the session_expiry claim to your application - -While Auth0 uses the calculated session expiration to manage its own session layer, your downstream applications may also need to know this absolute expiration time to enforce local session limits simultaneously. +## Send session expiration to your application -You can pass the final, evaluated session expiration to your application by injecting it as a custom claim into the Auth0-issued ID Token using a Post-Login Action. +While Auth0 uses the calculated session expiration to manage its own session layer, your downstream applications may also need to know this absolute expiration time to enforce local session limits. Configure a Post-Login Action to inject the final, evaluated session expiration in an Auth0-issued ID Token and pass the token to your application. @@ -136,21 +136,22 @@ exports.onExecutePostLogin = async (event, api) => { }; ``` -4. Select **Deploy**. -5. Navigate to [**Actions > Flows**](https://manage.auth0.com/#/actions/flows) and select **Login**. -6. In the **Add Action** panel, locate your Action and drag it into the Login flow. Select **Apply**. +4. Under the Test panel, select **Run** and review results. +5. Select **Deploy**. +6. Navigate to [**Actions > Flows**](https://manage.auth0.com/#/actions/flows) and select **Login**. +7. In the **Add Action** panel, locate your Action and drag it into the Login flow. Select **Apply**. Configuring the Action via the Management API requires three steps: create the Action, deploy it, then bind it to the Login trigger. You need a [Management API access token](/docs/secure/tokens/access-tokens/management-api-access-tokens) with `create:actions`, `read:actions`, and `update:actions` scopes. -## Create the Action +### Create the Action 1. Make a `POST` request to the [Create an action](https://auth0.com/docs/api/management/v2/actions/post-action) endpoint: ```curl - POST https://YOUR_AUTH0_DOMAIN/api/v2/actions/actions + POST https://YOUR_DOMAIN/api/v2/actions/actions Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN @@ -165,21 +166,21 @@ Configuring the Action via the Management API requires three steps: create the A Note the `id` value in the response since you need it in the following steps. -## Deploy the Action +### Deploy the Action 1. Make a `POST` request to the [Deploy an action](https://auth0.com/docs/api/management/v2/actions/post-deploy-action) endpoint: ```curl -POST https://YOUR_AUTH0_DOMAIN/api/v2/actions/actions/YOUR_ACTION_ID/deploy +POST https://YOUR_DOMAIN/api/v2/actions/actions/YOUR_ACTION_ID/deploy Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN ``` -## Bind the Action to the Login trigger +### Bind the Action to the Login trigger 1. Make a `PATCH` request to the [Update trigger bindings](https://auth0.com/docs/api/management/v2/actions/patch-bindings) endpoint: ```curl -PATCH https://YOUR_AUTH0_DOMAIN/api/v2/actions/triggers/post-login/bindings +PATCH https://YOUR_DOMAIN/api/v2/actions/triggers/post-login/bindings Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN @@ -204,14 +205,14 @@ The `PATCH /api/v2/actions/triggers/post-login/bindings` request replaces all ex Replace the placeholder values: -* **`YOUR_AUTH0_DOMAIN`**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. +* **`YOUR_DOMAIN`**: Your Auth0 tenant domain. Example: `travel0.us.auth0.com`. * **`YOUR_MANAGEMENT_API_TOKEN`**: A Management API token with `create:actions`, `read:actions`, and `update:actions` scopes. * **`YOUR_ACTION_ID`**: The `id` returned in the Create Action response. -## SDK behavior +## Use session expiry with Auth0 SDKs If you use [Auth0 SDKs](/docs/libraries), session expiry is enforced automatically with no changes to your application code. The SDK reads `session_expiry` at login, persists it with the session, and treats the session as expired once the current time reaches or passes `session_expiry`: @@ -221,11 +222,11 @@ If you use [Auth0 SDKs](/docs/libraries), session expiry is enforced automatical | **Single-Page App** (React, Angular, Vue) | `getTokenSilently()` / `getAccessTokenSilently()` rejects and triggers re-login with `prompt=login` | | **Mobile** (iOS/Swift, Android/Kotlin) | `CredentialsManager.credentials()` returns `noCredentials` and the app's existing login path handles re-authentication | -When a session expires due to the`session_expiry` claim, the SDK behaves the same as it would for any other session expiry: the user is redirected to log in. No additional error handling is required. +When a session expires due to the `session_expiry` claim, you must create a Post-Login Action to pass the `session_expiry` claim to your application. -## Session expiry value in your app (optional) +## Add session expiry values to your application -Your application can read `session_expiry` to show users a session-expiring warning or to bind your application's own session lifetime to the upstream IdP's value. +An optional step is to add session expiration values to your application. For example, your application can read `session_expiry` to show users a session-expiring warning or you can bind your application's own session lifetime to the upstream IdP's value. @@ -266,16 +267,16 @@ Do not persist the `session_expiry` value in a long-lived store, such as a cooki ## Verify in tenant logs -After enabling session expiry enforcement, verify the feature is working by checking [tenant logs](/docs/deploy-monitor/logs). +After enabling session expiry enforcement, verify session expiry is working by checking [tenant logs](/docs/deploy-monitor/logs). -Navigate to [**Auth0 Dashboard > Monitoring > Logs**](https://manage.auth0.com/#/logs) and look for a successful login (`s`) event for a user authenticating through the configured Enterprise connection. When the upstream IdP's `session_expiry` is less than or equal to your tenant's configured absolute session lifetime, the log entry includes the `idp_session_expiry` field (a Unix timestamp in milliseconds): +Navigate to [**Auth0 Dashboard > Monitoring > Logs**](https://manage.auth0.com/#/logs) and look for a successful login (`s`) event for a user authenticating through the configured Enterprise connection. When the upstream IdP's `session_expiry` is less than or equal to your tenant's configured absolute session lifetime, the log entry includes the `idp_session_expiry` field (a Unix timestamp in seconds): ```json { "type": "s", "description": "Success Login", "details": { - "idp_session_expiry": 1748566800000 + "idp_session_expiry": 1782472241 } } ``` @@ -299,7 +300,7 @@ If the IdP did not send a `session_expiry` claim and you enable the feature, log Set `id_token_session_expiry_supported` to `false` in your connection options: ```curl -PATCH https://YOUR_AUTH0_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID +PATCH https://YOUR_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN From 24152d682c5e28afff3dd033905513d6a5e779f2 Mon Sep 17 00:00:00 2001 From: amanda-vanscoy Date: Fri, 26 Jun 2026 10:34:49 -0400 Subject: [PATCH 06/11] fix: address remaining PR review feedback - Clarify SDK section: Action is required prerequisite for session_expiry enforcement; SDKs enforce automatically once claim is in the ID Token - Replace incorrect sentence about Action requirement in SDK behavior section - Change remaining curl code fences to http Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../session-expiry-enterprise-connections.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index c03b473489..91a5988024 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -150,7 +150,7 @@ Configuring the Action via the Management API requires three steps: create the A 1. Make a `POST` request to the [Create an action](https://auth0.com/docs/api/management/v2/actions/post-action) endpoint: - ```curl + ```http POST https://YOUR_DOMAIN/api/v2/actions/actions Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN @@ -170,7 +170,7 @@ Note the `id` value in the response since you need it in the following steps. 1. Make a `POST` request to the [Deploy an action](https://auth0.com/docs/api/management/v2/actions/post-deploy-action) endpoint: -```curl +```http POST https://YOUR_DOMAIN/api/v2/actions/actions/YOUR_ACTION_ID/deploy Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN ``` @@ -179,7 +179,7 @@ Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN 1. Make a `PATCH` request to the [Update trigger bindings](https://auth0.com/docs/api/management/v2/actions/patch-bindings) endpoint: -```curl +```http PATCH https://YOUR_DOMAIN/api/v2/actions/triggers/post-login/bindings Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN @@ -214,7 +214,7 @@ Replace the placeholder values: ## Use session expiry with Auth0 SDKs -If you use [Auth0 SDKs](/docs/libraries), session expiry is enforced automatically with no changes to your application code. The SDK reads `session_expiry` at login, persists it with the session, and treats the session as expired once the current time reaches or passes `session_expiry`: +If you use [Auth0 SDKs](/docs/libraries) and have configured the Post-Login Action described above, session expiry is enforced automatically. The SDK reads `session_expiry` from the ID Token at login, persists it with the session, and treats the session as expired once the current time reaches or passes `session_expiry`: | SDK type | How expiry is enforced | | --- | --- | @@ -222,7 +222,7 @@ If you use [Auth0 SDKs](/docs/libraries), session expiry is enforced automatical | **Single-Page App** (React, Angular, Vue) | `getTokenSilently()` / `getAccessTokenSilently()` rejects and triggers re-login with `prompt=login` | | **Mobile** (iOS/Swift, Android/Kotlin) | `CredentialsManager.credentials()` returns `noCredentials` and the app's existing login path handles re-authentication | -When a session expires due to the `session_expiry` claim, you must create a Post-Login Action to pass the `session_expiry` claim to your application. +The Post-Login Action is required to inject the `session_expiry` claim into the ID Token. Once set, when a session expires, the SDK behaves the same as any other session expiry: the user is redirected to log in. No additional error handling is required. ## Add session expiry values to your application @@ -299,7 +299,7 @@ If the IdP did not send a `session_expiry` claim and you enable the feature, log Set `id_token_session_expiry_supported` to `false` in your connection options: -```curl +```http PATCH https://YOUR_DOMAIN/api/v2/connections/YOUR_CONNECTION_ID Content-Type: application/json Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN From 7e2b8cb4c824c13d74128447a37e6e24d642e9b5 Mon Sep 17 00:00:00 2001 From: amanda-vanscoy Date: Wed, 1 Jul 2026 16:48:17 -0400 Subject: [PATCH 07/11] Updated setting title --- .../session-expiry-enterprise-connections.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index 91a5988024..43a135d83d 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -76,7 +76,7 @@ Configure session expiry enforcement on your Enterprise connection using the Aut 1. Navigate to [**Authentication > Enterprise**](https://manage.auth0.com/#/connections/enterprise) in the Auth0 Dashboard. 2. Select the Okta or OIDC Enterprise connection you want to configure. 3. Select the **Settings** tab. -4. Enable **Enforce upstream session expiry (IPSIE)**. +4. Enable **Use ID Token for Session Expiry**. 5. Select **Save**. @@ -291,7 +291,7 @@ If the IdP did not send a `session_expiry` claim and you enable the feature, log 1. Navigate to [**Authentication > Enterprise**](https://manage.auth0.com/#/connections/enterprise) in the Auth0 Dashboard. 2. Select the connection you want to configure. 3. Select the **Settings** tab. -4. Disable **Enforce upstream session expiry (IPSIE)**. +4. Disable **Use ID Token for Session Expiry**. 5. Select **Save**. From 54327df3dd8cbc33d363d951e4ecbc5840ba319f Mon Sep 17 00:00:00 2001 From: Amanda VS Date: Thu, 2 Jul 2026 09:44:26 -0400 Subject: [PATCH 08/11] Update main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx Co-authored-by: Carlos Fung --- .../session-expiry-enterprise-connections.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index 43a135d83d..d9e8cd956a 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -29,7 +29,7 @@ Before enabling session expiry enforcement: ## How it works -When a user authenticates through a `session_expiry`-enabled Enterprise connection, Auth0: +When a user authenticates through a `session_expiry` enabled Enterprise connection, Auth0: 1. Captures the `session_expiry` claim from the upstream IdP's ID Token. 2. Calculates session expiration by evaluating specific parameters and sets the final Auth0 sessions expiration to the minimum (earliest) value of the following factors: From 71eb5acb39bc1e4e89140413e24131e7a52fab68 Mon Sep 17 00:00:00 2001 From: Amanda VS Date: Thu, 2 Jul 2026 09:51:47 -0400 Subject: [PATCH 09/11] Apply suggestion from @BcnCarlos Co-authored-by: Carlos Fung --- .../session-expiry-enterprise-connections.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index d9e8cd956a..a7167ab0fd 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -32,7 +32,7 @@ Before enabling session expiry enforcement: When a user authenticates through a `session_expiry` enabled Enterprise connection, Auth0: 1. Captures the `session_expiry` claim from the upstream IdP's ID Token. -2. Calculates session expiration by evaluating specific parameters and sets the final Auth0 sessions expiration to the minimum (earliest) value of the following factors: +2. Calculates session expiration by evaluating specific parameters and sets the final Auth0 session's expiration to the minimum (earliest) value of the following factors: * The IdP `session_expiry` claim: The absolute timestamp in an ID Token from the upstream Identity Provider. * Your Auth0 tenant's default Absolute Expiration setting: The session lifetime limit you configure in Auth0 Dashboard or Management API. To learn more, read [Configure Session Lifetime Settings](/docs/manage-users/sessions/configure-session-lifetime-settings). * Auth0 Actions [`setExpiresAt`]: Any custom expiration timestamp programmatically set during the login transaction with the Post-Login Action [`api.session.setExpiresAt()`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object#api-session-setexpiresat-absolute) method. From 2a1d910a31cf884e38168b91e2298421f499fea8 Mon Sep 17 00:00:00 2001 From: amanda-vanscoy Date: Thu, 2 Jul 2026 10:17:43 -0400 Subject: [PATCH 10/11] Update inaccurate Dashboard instructions --- .../session-expiry-enterprise-connections.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index a7167ab0fd..df2bc58aa5 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -73,10 +73,10 @@ Configure session expiry enforcement on your Enterprise connection using the Aut -1. Navigate to [**Authentication > Enterprise**](https://manage.auth0.com/#/connections/enterprise) in the Auth0 Dashboard. -2. Select the Okta or OIDC Enterprise connection you want to configure. -3. Select the **Settings** tab. -4. Enable **Use ID Token for Session Expiry**. +1. Navigate to [Auth0 Dashboard > Authentication > Enterprise](https://manage.auth0.com/#/connections/enterprise) in the Auth0 Dashboard. +2. Find the Okta or OpenID Connect Enterprise connection and select **Browse**. +3. Choose the connection you want to configure. +4. Under Settings, enable **Use ID Token for Session Expiry**. 5. Select **Save**. @@ -120,7 +120,7 @@ While Auth0 uses the calculated session expiration to manage its own session lay -1. Navigate to [**Actions > Library**](https://manage.auth0.com/#/actions/library) in the Auth0 Dashboard and select **Build Custom**. +1. Navigate to [**Auth0 Dashboard > Actions > Library**](https://manage.auth0.com/#/actions/library) in the Auth0 Dashboard and select **Build Custom Action**. 2. Enter a name for the Action, select **Login / Post Login** as the trigger, and select **Create**. 3. Add the following code to your Action: @@ -138,8 +138,8 @@ exports.onExecutePostLogin = async (event, api) => { 4. Under the Test panel, select **Run** and review results. 5. Select **Deploy**. -6. Navigate to [**Actions > Flows**](https://manage.auth0.com/#/actions/flows) and select **Login**. -7. In the **Add Action** panel, locate your Action and drag it into the Login flow. Select **Apply**. +6. Navigate to [**Actions > Triggers**](https://manage.auth0.com/#/actions/flows) and select **Post-Login**. +7. Locate your Action and drag it into the Login flow. Select **Apply**. From 671a69d6ad68b466b3bac21131ec7ca7a6e9b0d6 Mon Sep 17 00:00:00 2001 From: Amanda VS Date: Thu, 2 Jul 2026 10:29:53 -0400 Subject: [PATCH 11/11] Apply suggestions from code review Co-authored-by: Carlos Fung --- .../session-expiry-enterprise-connections.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx index df2bc58aa5..ed709b5afe 100644 --- a/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx +++ b/main/docs/authenticate/enterprise-connections/session-expiry-enterprise-connections.mdx @@ -138,7 +138,7 @@ exports.onExecutePostLogin = async (event, api) => { 4. Under the Test panel, select **Run** and review results. 5. Select **Deploy**. -6. Navigate to [**Actions > Triggers**](https://manage.auth0.com/#/actions/flows) and select **Post-Login**. +6. Navigate to [**Actions > Triggers**](https://manage.auth0.com/#/actions/triggers) and select **Post-Login**. 7. Locate your Action and drag it into the Login flow. Select **Apply**.