From 8fa075cc5d30069595ee30b3da743b4bbbe41f2b Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 14:25:59 +0100 Subject: [PATCH 01/10] Create use-cases.mdx --- .../refresh-token-metadata/use-cases.mdx | 400 ++++++++++++++++++ 1 file changed, 400 insertions(+) create mode 100644 main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx new file mode 100644 index 0000000000..aca6660943 --- /dev/null +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -0,0 +1,400 @@ +--- +description: Explore a variety of examples of implementations using refresh token metadata and session metadata +title: Refresh token metadata and session metadata Use Cases +validatedOn: 2026-03-06 +--- + +[Refresh token metadata](/docs/secure/tokens/refresh-tokens/refresh-token-metadata) and [Session metadata](/docs/manage-users/sessions/session-metadata) together allows you to create and store persistent data throughout a user’s Auth0 session lifecycle to among other things: + +* Create persistent custom claims +* Create a unique session ID +* Propagate tenant identifiers +* Manage transient data from upstream identity providers (IDPs) +* Enhance security and fraud detection + +To learn more, read [A guide to Auth0 Session and Refresh token metadata](https://auth0.com/blog/auth0-session-refresh-token-metadata-guide/). + + +Auth0 Session metadata is not a secure data store and should not be used to store sensitive information. This includes secrets and high-risk PII like social security numbers or credit card numbers, etc. Auth0 customers are strongly encouraged to evaluate the data stored in metadata and only store that which is necessary for identity and access management purposes. To learn more, read [Auth0 General Data Protection Regulation Compliance](/docs/secure/data-privacy-and-compliance/gdpr). + + +## Create persistent custom claims + +Refresh token metadata and Session metadata together lets you create persistent custom claims to extend information contained within [ID](/docs/secure/tokens#id-tokens) and [access](/docs/secure/tokens/access-tokens) tokens. + +Using persistent custom claims, you can access application specific data, such as: + + * User roles + * Permissions + * Tenant IDs + * And other attributes necessary for authorization and personalization across refresh token exchanges. + +Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) [Action](/docs/customize/actions) trigger to create persistent custom claims and assign them to refresh token metadata using the `api.refreshToken.setMetadata()` object. + +During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. + +```javascript lines +/** + * @param {Event} event - Details about the user and the authentication transaction. + * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. + */ +exports.onExecutePostLogin = async (event, api) => { + let customClaimValue1; + let customClaimValue2; + + // --- Helper function to simulate custom claim calculation --- + // In a real scenario, this function would perform complex logic + // based on user data, external APIs, etc. + const calculateCustomClaims = (user) => { + // After doing your calculations return + return { claim1: value1, claim2: value2 }; + }; + + // --- Determine if this is an initial login or a refresh token exchange --- + // If event.request.body.grant_type is not 'refresh_token', it's likely an initial interactive login + const isRefreshTokenGrant = event.request.body.grant_type === 'refresh_token'; + + if (!isRefreshTokenGrant) { + // --- Initial Login (e.g., pwd, social, MFA-OOB) --- + // Calculate the custom claim values + const calculatedClaims = calculateCustomClaims(event.user); + customClaimValue1 = calculatedClaims.claim1; + customClaimValue2 = calculatedClaims.claim2; + + // Store these calculated values into Refresh Token Metadata for persistence + // Check if we will issue a refresh token and if so add metadata +if (event.transaction.requested_scopes.indexOf('offline_access') > -1) { +api.refreshToken.setMetadata('customClaim1', customClaimValue1); +api.refreshToken.setMetadata('customClaim2', customClaimValue2); +} + + } else { + // --- Refresh Token Exchange --- + // Use the custom claim values from Refresh Token Metadata + customClaimValue1 = event.refresh_token?.metadata?.customClaim1; + customClaimValue2 = event.refresh_token?.metadata?.customClaim2; + + } + // --- Finally, add the determined values as custom claims to the tokens --- + api.idToken.setCustomClaim('custom_claim_1', customClaimValue1); + api.accessToken.setCustomClaim('custom_claim_1', customClaimValue1); + + api.idToken.setCustomClaim('custom_claim_2', customClaimValue2); + api.accessToken.setCustomClaim('custom_claim_2', customClaimValue2); +}; +``` + + +* A single `post-login` Action can handle different `grant_type` scenarios using the `event.request.body.grant_type` object to manage claim persistence. +* The `event.refresh_token` object is only read available during refresh token exchanges. + + +You can use the Auth0 [Management API](/docs/api/management/v2/introduction) `GET` [/api/v2/refresh-tokens/{id} endpoint](/docs/api/management/v2/refresh-tokens/get-refresh-token) to retrieve the persistent custom claims stored in the refresh token's metadata. + +The response includes the `metadata` field, containing the persistent custom claim: + +```json lines +{ + "id": "object_id", + "metadata": { + "customClaim1": "customClaimValue1" + } +} +``` + +## Create a unique session ID + +Refresh token metadata and Session metadata together lets you create a unique session ID to implement a persistent session identifier that is carried across the entire lifespan of a user's session, including [refresh token rotations](docs/secure/tokens/refresh-tokens/refresh-token-rotation), [ID](/docs/secure/tokens/id-tokens/update-id-token-lifetime) and [access](/docs/secure/tokens/access-tokens/update-access-token-lifetime) tokens lifetimes. + +Using unique session IDs, you can: + +* Accurately log a user’s session for debugging and auditing purposes. +* Provide a mechanism for applications to track internal session state. +* Enable [APIs](/docs/get-started/apis#apis) to provide granular logging, rate limiting, and contextual authorization decisions. +* Apply consistent UX experiences that span multiple token lifecycles. + +Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to create a unique session ID and assign it to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects. Add the unique session ID, as a custom claim to the ID and access tokens, using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. +During a refresh token exchange, a subsequent post-login Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. + +```javascript lines +/** + * @param {Event} event - Details about the user and the authentication transaction. + * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. + */ +exports.onExecutePostLogin = async (event, api) => { + let sessionId; + + // 1) Check if a session metadata key called 'ses_id' already exists. + if (event.session && event.session.metadata && event.session.metadata.ses_id) { + sessionId = event.session.metadata.ses_id; + } + // If not found in session metadata, check if it's available in the refresh token metadata. + // This is specifically relevant for ROPG flows where there was no actual session. + else if (event.refresh_token && event.refresh_token.metadata && event.refresh_token.metadata.ses_id) { + sessionId = event.refreshToken.metadata.ses_id; + } + + // If a 'ses_id' doesn't exist, generate a new one + if (!sessionId) { + sessionId = generateSesId(); // Your own helper function to generate a UUID + + // Store the newly generated 'ses_id' in session metadata + // Only do this if a session is actually being issued/present in the event. + if (event.session) { + api.session.setMetadata('ses_id', sessionId); + } + + // Store the 'ses_id' in refresh token metadata. + // Only do this if a refresh token is actually being issued/present in the event. + if (event.refresh_token) { + api.refreshToken.setMetadata('ses_id', sessionId); + } + } else { + // Also, ensure the refresh token metadata has the ses_id, in case it was missing + // or updated elsewhere. This could happen if the user did not request offline_access at first but added it later. + if (event.refresh_token && event.refresh_token.metadata && !event.refresh_token.metadata.ses_id) { + api.refreshToken.setMetadata('ses_id', sessionId); + } + } + + + // 2) Add this 'ses_id' as a custom claim to both the ID Token and Access Token. + api.idToken.setCustomClaim('ses_id', sessionId); + api.accessToken.setCustomClaim('ses_id', sessionId); +}; +``` + +You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the unique session ID stored in the refresh token's or session’s metadata. + +The response includes the `metadata` field, containing the unique session ID: + +```json lines +{ + "id": "object_id", + "metadata": { + "ses_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" + } +} +``` + +## Create a tenant identifier + +Refresh token metadata and Session metadata together lets you create a persistent tenant identifier to manage multi-tenant applications, where a single instance of an application serves multiple customer organizations, that is carried across the entire lifespan of a user's session, including refresh token rotations, ID and access tokens lifetimes. + +Using a persistent tenant identifier, you can: + +* Add dynamic access control to easily enforce tenant-specific permissions in your applications and APIs +* Create tailored User Experience to deliver content and features relevant to the user's current tenant context +* Simplify Multi-Tenancy Logic by centralizing tenant identification and propagation within Auth0 +* Enhance Security by preventing accidental cross-tenant data exposure by ensuring consistent tenant context in all tokens +* Improve Scalability by reducing the need for repeated database queries or complex logic to determine tenant context on every API call or token refresh + +Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify the user’s active tenant either by querying the application for an `ext-tenantId` value provided during the authentication request, infer the tenant using geo-location, or by prompting the user to select their desired tenant. +Once the tenant is identified, assign the tenant identifier value to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add it as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. +During a refresh token exchange, a subsequent `post-login` Action can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. + +```javascript lines +/** + * @param {Event} event - Details about the user and the authentication transaction. + * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. + */ +exports.onExecutePostLogin = async (event, api) => { + let tenantId; + + // 1) Check if a session metadata key called 'tenant_id' already exists. + if (event.session && event.session.metadata && event.session.metadata.tenant_id) { + tenantId = event.session.metadata.tenant_id; + } + // If not found in session metadata, check if it's available in the refresh token metadata. + // This is specifically relevant for ROPG flows where there was no actual session. + else if (event.refresh_token && event.refresh_token.metadata && event.refresh_token.metadata.tenant_id) { + tenantId = event.refreshToken.metadata.tenant_id; + } + + // If we don't know yet the 'tenant_id' we figure it out + if (!tenantId) { + // Assume tenant_id came as an ext- parameter + tenantId = event.request.query['ext-tenantId']; + + // It could also come from geo location in event + // or from forms. If using forms you'd open the form + // now and run the rest of the code in the + // onContinuePostLogin function + + // Store the newly generated 'tenant_id' in session metadata + // Only do this if a session is actually being issued/present in the event. + if (event.session) { + api.session.setMetadata('tenant_id', tenantId); + } + + // Store the 'tenant_id' in refresh token metadata. + // Only do this if a refresh token is actually being issued/present in the event. + if (event.refresh_token) { + api.refreshToken.setMetadata('tenant_id', tenantId); + } + } else { + // Also, ensure the refresh token metadata has the tenant_id, in case it was missing + // or updated elsewhere. This could happen if the user did not request offline_access at first but added it later. + if (event.refresh_token && event.refresh_token.metadata && !event.refresh_token.metadata.tenant_id) { + api.refreshToken.setMetadata('tenant_id', tenantId); + } + } + + + // 2) Add this 'tenant_id' as a custom claim to both the ID Token and Access Token. + api.idToken.setCustomClaim('tenant_id', tenantId); + api.accessToken.setCustomClaim('tenant_id', tenantId); +}; +``` + +You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the `tenant_id` within a refresh token's or session’s metadata. + +The response includes the `metadata` field, containing the `tenant_id`: + +```json lines +{ + "id": "object_id", + "metadata": { + "tenant_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" + } +} +``` + +## Manage transient data from upstream identity providers (IDPs) + +Refresh token metadata and Session metadata together lets you manage transient and contextual data from upstream IDPs throughout a user's session without storing it permanently in the user's Auth0 profile. + +Using transient data, you can: + +* Maintain clean user profiles by preventing the storage of transient or session specific data +* Enhance flexibility by supporting diverse data requirements from various IDPs without forcing schema changes or data bloat in persistent user profiles +* Improve compliance by facilitating adherence to data privacy and retention policies by storing transient data only for its required lifetime +* Reduce development overhead by simplifying the process of handling transient IDP data, as Auth0 Actions and metadata manage the data lifecycle + +Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify user profile data contained in the `event.request`, `event.user`, and `event.context` objects. Determine which data is transient or contextual data and assign it to the user’s session, using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add the transient data as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. +During a refresh token exchange, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.accessToken.setCustomClaim()` object. + +```javascript lines +/** + * @param {Event} event - Details about the user and the authentication transaction. + * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. + */ +exports.onExecutePostLogin = async (event, api) => { + let deviceIdentifier; + let groups; + + // Example: Extract device info from request headers or context + // This is illustrative; actual device fingerprinting might be more complex + if (event.request.user_agent) { + deviceIdentifier = event.request.user_agent; + } else { + deviceIdentifier = 'unknown'; + } + + // Example: Extract IDP information from an upstream connection's context + // This depends heavily on the upstream IDP and how it passes info. + // Assuming a custom claim or context variable from a SAML/OIDC connection, e.g. "groups" + if (event.user.groups) { + groups = event.user.groups; + } else { + groups = []; + } + + // Store the transient data in session metadata + api.session.setMetadata('deviceIdentifier', deviceIdentifier); + api.session.setMetadata('groups', groups); + + // Store the transient data in refresh token metadata for persistence across refreshes + if (event.refreshToken) { + api.refreshToken.setMetadata('deviceIdentifier', deviceIdentifier); + api.refreshToken.setMetadata('groups', groups); + } + + // Optionally, add these as claims to access tokens if needed by APIs + // Using custom namespaces is good practice for application-specific claims. + api.accessToken.setCustomClaim('https://myapp.example.com/device_id', deviceIdentifier); + api.accessToken.setCustomClaim('https://myapp.example.com/groups', groups); + + // Example: If the upstream IDP provides a "level of assurance" for this auth event + if (event.transaction && event.transaction.acr_values) { // acr: Authentication Context Class Reference + api.session.setMetadata('authLevel', event.transaction.acr_values); + if (event.refreshToken) { + api.refreshToken.setMetadata('authLevel', event.transaction.acr_values); + } + api.accessToken.setCustomClaim('https://myapp.example.com/auth_level', event.transaction.acr_values); + } +}; +``` + +You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the transient data within a refresh token's or session’s metadata. + +The response includes the `metadata` field, containing the transient data: + +```json lines +{ + "id": "object_id", + "metadata": { + "deviceIdentifier": "deviceIdentifier" + } +} +``` + +## Enhance security and fraud detection + +Refresh token metadata and Session metadata together lets you implement adaptive security by enabling the tracking and comparison of contextual information throughout a user's session including refresh token rotations and [silent authentication](/docs/authenticate/login/configure-silent-authentication) requests. + +By implementing adaptive security you can: + +*Create proactive threat detection by automatically identifying and responding to suspicious changes in user context data, reducing the risk of session hijacking and unauthorized access. +* Reduce friction for legitimate users by only prompts for MFA or additional verification when a genuine anomaly is detected, improving the user experience compared to blanket MFA requirements. + + +Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify contextual user data that can include device fingerprint, geographic location, network attributes, and behavioral attributes. Store the contextual data for comparison in the user’s session, using the `api.session.setMetadata()` object. +During a refresh token exchange or silent authentication, a subsequent `post-login Action` trigger can apply risk assessment and adaptive responses. + +```javascript lines +/** + * @param {Event} event - Details about the user and the authentication transaction. + * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. + */ +exports.onExecutePostLogin = async (event, api) => { + // --- Capture current contextual data --- + // Use the ja3/ja4 fingerprints provided by Auth0 + const {ja3, ja4} = event.security_context; + // Add ja3/ja4 to metadata if it is not there yet + // (first login does not have metadata set) + if (event.session && !event.session.metadata) { + api.session.setMetadata('ja3', ja3); + api.session.setMetadata('ja4', ja4); + } else { + // Compare the stored fingerprint with the incoming fingerprint + if(ja3 != event.session?.metadata?.ja3 || ja4 != event.session?.metadata?.ja4) { + // If fingerprints differ, challenge for MFA + api.authentication.challengeWith( + { type: 'otp'}, + { additionalFactors: [ + { type: 'push-notification'}, { type: 'phone' } + ]} + ); + } + } +}; +``` + +You can use the Management API `GET` [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoint to retrieve the contextual data stored in a session’s metadata. + +The response includes the `metadata` field, containing the contextual data: + +```json lines +{ + "id": "object_id", + + "metadata": { + "ja3": "ja3" + } +} +``` + +To learn more about these Actions objects, review: +* [Event object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object): Learn about the session Event object and properties. +* [API object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object): Learn about the session API object and methods. From 1b23650a055bdced91cacfea8afe6f23e78b7ff6 Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 14:29:01 +0100 Subject: [PATCH 02/10] Update docs.json --- main/docs.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/docs.json b/main/docs.json index 11b47197a8..79cd023656 100644 --- a/main/docs.json +++ b/main/docs.json @@ -2032,7 +2032,8 @@ "group": "Refresh Token Metadata", "pages": [ "docs/secure/tokens/refresh-tokens/refresh-token-metadata", - "docs/secure/tokens/refresh-tokens/refresh-token-metadata/configure-refresh-token-metadata" + "docs/secure/tokens/refresh-tokens/refresh-token-metadata/configure-refresh-token-metadata", + "docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases" ] }, { From f8e0df1072f3a98452c30447b929a3bd24ada529 Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 14:39:02 +0100 Subject: [PATCH 03/10] Update use-cases.mdx --- .../refresh-token-metadata/use-cases.mdx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx index aca6660943..629d340292 100644 --- a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -33,7 +33,7 @@ Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-log During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript lines +```javascript expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -116,7 +116,7 @@ Using unique session IDs, you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to create a unique session ID and assign it to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects. Add the unique session ID, as a custom claim to the ID and access tokens, using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. During a refresh token exchange, a subsequent post-login Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript lines +```javascript expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -193,7 +193,7 @@ Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-log Once the tenant is identified, assign the tenant identifier value to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add it as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. During a refresh token exchange, a subsequent `post-login` Action can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript lines +```javascript expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -274,7 +274,7 @@ Using transient data, you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify user profile data contained in the `event.request`, `event.user`, and `event.context` objects. Determine which data is transient or contextual data and assign it to the user’s session, using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add the transient data as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. During a refresh token exchange, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.accessToken.setCustomClaim()` object. -```javascript lines +```javascript expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -352,7 +352,7 @@ By implementing adaptive security you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify contextual user data that can include device fingerprint, geographic location, network attributes, and behavioral attributes. Store the contextual data for comparison in the user’s session, using the `api.session.setMetadata()` object. During a refresh token exchange or silent authentication, a subsequent `post-login Action` trigger can apply risk assessment and adaptive responses. -```javascript lines +```javascript expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -388,7 +388,6 @@ The response includes the `metadata` field, containing the contextual data: ```json lines { "id": "object_id", - "metadata": { "ja3": "ja3" } From 1e31b56a0d480f1a675dde2234b6a5b4cb8f6a2b Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 14:47:31 +0100 Subject: [PATCH 04/10] Update use-cases.mdx --- .../refresh-token-metadata/use-cases.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx index 629d340292..74e80eb9e6 100644 --- a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -33,7 +33,7 @@ Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-log During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript expandable +```javascript custom claim Action expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -116,7 +116,7 @@ Using unique session IDs, you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to create a unique session ID and assign it to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects. Add the unique session ID, as a custom claim to the ID and access tokens, using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. During a refresh token exchange, a subsequent post-login Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript expandable +```javascript unique Session ID Action expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -193,7 +193,7 @@ Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-log Once the tenant is identified, assign the tenant identifier value to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add it as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. During a refresh token exchange, a subsequent `post-login` Action can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript expandable +```javascript tenant identifier Action expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -274,7 +274,7 @@ Using transient data, you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify user profile data contained in the `event.request`, `event.user`, and `event.context` objects. Determine which data is transient or contextual data and assign it to the user’s session, using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add the transient data as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. During a refresh token exchange, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.accessToken.setCustomClaim()` object. -```javascript expandable +```javascript transient data Action expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -352,7 +352,7 @@ By implementing adaptive security you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify contextual user data that can include device fingerprint, geographic location, network attributes, and behavioral attributes. Store the contextual data for comparison in the user’s session, using the `api.session.setMetadata()` object. During a refresh token exchange or silent authentication, a subsequent `post-login Action` trigger can apply risk assessment and adaptive responses. -```javascript expandable +```javascript security detection Action expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -395,5 +395,5 @@ The response includes the `metadata` field, containing the contextual data: ``` To learn more about these Actions objects, review: -* [Event object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object): Learn about the session Event object and properties. +* [Event object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object): Learn about the session Event object and properties. * [API object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object): Learn about the session API object and methods. From eb6215391edbc21067717745af54eaab51c48f6b Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 16:57:20 +0100 Subject: [PATCH 05/10] Update use-cases.mdx --- .../refresh-token-metadata/use-cases.mdx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx index 74e80eb9e6..e5a8f4d84a 100644 --- a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -31,8 +31,6 @@ Using persistent custom claims, you can access application specific data, such a Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) [Action](/docs/customize/actions) trigger to create persistent custom claims and assign them to refresh token metadata using the `api.refreshToken.setMetadata()` object. -During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. - ```javascript custom claim Action expandable /** * @param {Event} event - Details about the user and the authentication transaction. @@ -83,6 +81,7 @@ api.refreshToken.setMetadata('customClaim2', customClaimValue2); api.accessToken.setCustomClaim('custom_claim_2', customClaimValue2); }; ``` +During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. * A single `post-login` Action can handle different `grant_type` scenarios using the `event.request.body.grant_type` object to manage claim persistence. @@ -114,7 +113,6 @@ Using unique session IDs, you can: * Apply consistent UX experiences that span multiple token lifecycles. Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to create a unique session ID and assign it to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects. Add the unique session ID, as a custom claim to the ID and access tokens, using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -During a refresh token exchange, a subsequent post-login Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. ```javascript unique Session ID Action expandable /** @@ -163,6 +161,7 @@ exports.onExecutePostLogin = async (event, api) => { api.accessToken.setCustomClaim('ses_id', sessionId); }; ``` +During a refresh token exchange, a subsequent post-login Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the unique session ID stored in the refresh token's or session’s metadata. @@ -191,7 +190,6 @@ Using a persistent tenant identifier, you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify the user’s active tenant either by querying the application for an `ext-tenantId` value provided during the authentication request, infer the tenant using geo-location, or by prompting the user to select their desired tenant. Once the tenant is identified, assign the tenant identifier value to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add it as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -During a refresh token exchange, a subsequent `post-login` Action can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. ```javascript tenant identifier Action expandable /** @@ -246,6 +244,7 @@ exports.onExecutePostLogin = async (event, api) => { api.accessToken.setCustomClaim('tenant_id', tenantId); }; ``` +During a refresh token exchange, a subsequent `post-login` Action can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the `tenant_id` within a refresh token's or session’s metadata. @@ -272,7 +271,6 @@ Using transient data, you can: * Reduce development overhead by simplifying the process of handling transient IDP data, as Auth0 Actions and metadata manage the data lifecycle Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify user profile data contained in the `event.request`, `event.user`, and `event.context` objects. Determine which data is transient or contextual data and assign it to the user’s session, using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add the transient data as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -During a refresh token exchange, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.accessToken.setCustomClaim()` object. ```javascript transient data Action expandable /** @@ -325,6 +323,7 @@ exports.onExecutePostLogin = async (event, api) => { } }; ``` +During a refresh token exchange, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.accessToken.setCustomClaim()` object. You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the transient data within a refresh token's or session’s metadata. @@ -345,12 +344,10 @@ Refresh token metadata and Session metadata together lets you implement adaptive By implementing adaptive security you can: -*Create proactive threat detection by automatically identifying and responding to suspicious changes in user context data, reducing the risk of session hijacking and unauthorized access. +* Create proactive threat detection by automatically identifying and responding to suspicious changes in user context data, reducing the risk of session hijacking and unauthorized access. * Reduce friction for legitimate users by only prompts for MFA or additional verification when a genuine anomaly is detected, improving the user experience compared to blanket MFA requirements. - Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify contextual user data that can include device fingerprint, geographic location, network attributes, and behavioral attributes. Store the contextual data for comparison in the user’s session, using the `api.session.setMetadata()` object. -During a refresh token exchange or silent authentication, a subsequent `post-login Action` trigger can apply risk assessment and adaptive responses. ```javascript security detection Action expandable /** @@ -380,6 +377,7 @@ exports.onExecutePostLogin = async (event, api) => { } }; ``` +During a refresh token exchange or silent authentication, a subsequent `post-login Action` trigger can apply risk assessment and adaptive responses. You can use the Management API `GET` [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoint to retrieve the contextual data stored in a session’s metadata. @@ -394,6 +392,8 @@ The response includes the `metadata` field, containing the contextual data: } ``` -To learn more about these Actions objects, review: -* [Event object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object): Learn about the session Event object and properties. -* [API object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object): Learn about the session API object and methods. +Learn more: +* [Refresh tokens](/docs/secure/tokens/refresh-tokens) +* [Sessions](/docs/manage-users/sessions) +* [Actions Event objects](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object): Learn about the session Event object and properties. +* [Actions API object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object): Learn about the session API object and methods. From eacce1cc56a92f30cd286deb72a9a4723ab07c5b Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 17:47:46 +0100 Subject: [PATCH 06/10] Update use-cases.mdx --- .../refresh-token-metadata/use-cases.mdx | 118 +++++------------- 1 file changed, 34 insertions(+), 84 deletions(-) diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx index e5a8f4d84a..7236fbfff1 100644 --- a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -1,26 +1,26 @@ --- -description: Explore a variety of examples of implementations using refresh token metadata and session metadata +description: Explore example implementations of use cases for refresh token metadata and session metadata. title: Refresh token metadata and session metadata Use Cases validatedOn: 2026-03-06 --- -[Refresh token metadata](/docs/secure/tokens/refresh-tokens/refresh-token-metadata) and [Session metadata](/docs/manage-users/sessions/session-metadata) together allows you to create and store persistent data throughout a user’s Auth0 session lifecycle to among other things: +[Refresh token metadata](/docs/secure/tokens/refresh-tokens/refresh-token-metadata) and [session metadata](/docs/manage-users/sessions/session-metadata) together allow you to create and store data that persists throughout a user’s Auth0 session lifecycle. This article includes examples for the following use cases: -* Create persistent custom claims -* Create a unique session ID -* Propagate tenant identifiers -* Manage transient data from upstream identity providers (IDPs) -* Enhance security and fraud detection +* [Creating persistent custom claims](/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases#create-persistent-custom-claims) +* [Creating a unique session ID](/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases#create-a-unique-session-id) +* [Propagating tenant identifiers](/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases#create-a-tenant-identifier) +* [Managing transient data from upstream identity providers (IDPs)](/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases#manage-transient-data-from-upstream-identity-providers-idps) +* [Enhancing security and fraud detection](/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases#enhance-security-and-fraud-detection) -To learn more, read [A guide to Auth0 Session and Refresh token metadata](https://auth0.com/blog/auth0-session-refresh-token-metadata-guide/). +To learn more, read [A guide to Auth0 Session and Refresh Token Metadata](https://auth0.com/blog/auth0-session-refresh-token-metadata-guide/). -Auth0 Session metadata is not a secure data store and should not be used to store sensitive information. This includes secrets and high-risk PII like social security numbers or credit card numbers, etc. Auth0 customers are strongly encouraged to evaluate the data stored in metadata and only store that which is necessary for identity and access management purposes. To learn more, read [Auth0 General Data Protection Regulation Compliance](/docs/secure/data-privacy-and-compliance/gdpr). +Auth0 session metadata is not a secure data store and should not be used to store sensitive information. This includes secrets and high-risk PII like social security numbers or credit card numbers, etc. Auth0 customers are strongly encouraged to evaluate the data stored in metadata and only store that which is necessary for identity and access management purposes. To learn more, read [Auth0 General Data Protection Regulation Compliance](/docs/secure/data-privacy-and-compliance/gdpr). ## Create persistent custom claims -Refresh token metadata and Session metadata together lets you create persistent custom claims to extend information contained within [ID](/docs/secure/tokens#id-tokens) and [access](/docs/secure/tokens/access-tokens) tokens. +Refresh token metadata and session metadata together lets you create persistent custom claims to extend information contained within [ID](/docs/secure/tokens#id-tokens) and [access](/docs/secure/tokens/access-tokens) tokens. Using persistent custom claims, you can access application specific data, such as: @@ -81,29 +81,15 @@ api.refreshToken.setMetadata('customClaim2', customClaimValue2); api.accessToken.setCustomClaim('custom_claim_2', customClaimValue2); }; ``` -During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. +During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -* A single `post-login` Action can handle different `grant_type` scenarios using the `event.request.body.grant_type` object to manage claim persistence. -* The `event.refresh_token` object is only read available during refresh token exchanges. +A single `post-login` Action can handle different `grant_type` scenarios using the `event.request.body.grant_type` object to manage claim persistence. The `event.refresh_token` object is only read available during refresh token exchanges. -You can use the Auth0 [Management API](/docs/api/management/v2/introduction) `GET` [/api/v2/refresh-tokens/{id} endpoint](/docs/api/management/v2/refresh-tokens/get-refresh-token) to retrieve the persistent custom claims stored in the refresh token's metadata. - -The response includes the `metadata` field, containing the persistent custom claim: - -```json lines -{ - "id": "object_id", - "metadata": { - "customClaim1": "customClaimValue1" - } -} -``` - ## Create a unique session ID -Refresh token metadata and Session metadata together lets you create a unique session ID to implement a persistent session identifier that is carried across the entire lifespan of a user's session, including [refresh token rotations](docs/secure/tokens/refresh-tokens/refresh-token-rotation), [ID](/docs/secure/tokens/id-tokens/update-id-token-lifetime) and [access](/docs/secure/tokens/access-tokens/update-access-token-lifetime) tokens lifetimes. +Refresh token metadata and Session metadata together let you create a unique session ID to implement a persistent session identifier that is carried across the entire lifespan of a user's session, including during [refresh token rotations](docs/secure/tokens/refresh-tokens/refresh-token-rotation). Using unique session IDs, you can: @@ -161,35 +147,22 @@ exports.onExecutePostLogin = async (event, api) => { api.accessToken.setCustomClaim('ses_id', sessionId); }; ``` -During a refresh token exchange, a subsequent post-login Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. - -You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the unique session ID stored in the refresh token's or session’s metadata. - -The response includes the `metadata` field, containing the unique session ID: - -```json lines -{ - "id": "object_id", - "metadata": { - "ses_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" - } -} -``` +During a refresh token exchange, a subsequent post-login Action trigger can access these custom claims using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. ## Create a tenant identifier -Refresh token metadata and Session metadata together lets you create a persistent tenant identifier to manage multi-tenant applications, where a single instance of an application serves multiple customer organizations, that is carried across the entire lifespan of a user's session, including refresh token rotations, ID and access tokens lifetimes. +Refresh token metadata and session metadata together let you create a persistent tenant identifier to manage multi-tenant applications, where a single instance of an application serves multiple customer organizations, that is carried across the entire lifespan of a user's session. Using a persistent tenant identifier, you can: * Add dynamic access control to easily enforce tenant-specific permissions in your applications and APIs -* Create tailored User Experience to deliver content and features relevant to the user's current tenant context -* Simplify Multi-Tenancy Logic by centralizing tenant identification and propagation within Auth0 -* Enhance Security by preventing accidental cross-tenant data exposure by ensuring consistent tenant context in all tokens -* Improve Scalability by reducing the need for repeated database queries or complex logic to determine tenant context on every API call or token refresh +* Create a tailored user experience to deliver content and features relevant to the user's current tenant context +* Simplify multi-tenancy logic by centralizing tenant identification and propagation within Auth0 +* Enhance security by preventing accidental cross-tenant data exposure by ensuring consistent tenant context in all tokens +* Improve scalability by reducing the need for repeated database queries or complex logic to determine tenant context on every API call or token refresh Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify the user’s active tenant either by querying the application for an `ext-tenantId` value provided during the authentication request, infer the tenant using geo-location, or by prompting the user to select their desired tenant. -Once the tenant is identified, assign the tenant identifier value to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add it as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. +Once the tenant is identified, assign the tenant identifier value to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, and add it as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. ```javascript tenant identifier Action expandable /** @@ -246,22 +219,9 @@ exports.onExecutePostLogin = async (event, api) => { ``` During a refresh token exchange, a subsequent `post-login` Action can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the `tenant_id` within a refresh token's or session’s metadata. - -The response includes the `metadata` field, containing the `tenant_id`: - -```json lines -{ - "id": "object_id", - "metadata": { - "tenant_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" - } -} -``` - ## Manage transient data from upstream identity providers (IDPs) -Refresh token metadata and Session metadata together lets you manage transient and contextual data from upstream IDPs throughout a user's session without storing it permanently in the user's Auth0 profile. +Refresh token metadata and session metadata together let you manage transient and contextual data from upstream IDPs throughout a user's session without storing it permanently in the user's Auth0 profile. Using transient data, you can: @@ -325,22 +285,9 @@ exports.onExecutePostLogin = async (event, api) => { ``` During a refresh token exchange, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object, and apply them to newly issued refresh tokens using the `api.accessToken.setCustomClaim()` object. -You can use the Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the transient data within a refresh token's or session’s metadata. - -The response includes the `metadata` field, containing the transient data: - -```json lines -{ - "id": "object_id", - "metadata": { - "deviceIdentifier": "deviceIdentifier" - } -} -``` - ## Enhance security and fraud detection -Refresh token metadata and Session metadata together lets you implement adaptive security by enabling the tracking and comparison of contextual information throughout a user's session including refresh token rotations and [silent authentication](/docs/authenticate/login/configure-silent-authentication) requests. +Refresh token metadata and session metadata together let you implement adaptive security by enabling the tracking and comparison of contextual information throughout a user's session including refresh token rotations and [silent authentication](/docs/authenticate/login/configure-silent-authentication) requests. By implementing adaptive security you can: @@ -379,21 +326,24 @@ exports.onExecutePostLogin = async (event, api) => { ``` During a refresh token exchange or silent authentication, a subsequent `post-login Action` trigger can apply risk assessment and adaptive responses. -You can use the Management API `GET` [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoint to retrieve the contextual data stored in a session’s metadata. +## Access Metadata with the Management API -The response includes the `metadata` field, containing the contextual data: +You can use the Auth0 Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the stored data in either a refresh token or session’s metadata. -```json lines +The response includes the `metadata` field containing the stored data: +```json { "id": "object_id", "metadata": { - "ja3": "ja3" + "deviceIdentifier": "deviceIdentifier" } } + ``` -Learn more: -* [Refresh tokens](/docs/secure/tokens/refresh-tokens) -* [Sessions](/docs/manage-users/sessions) -* [Actions Event objects](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object): Learn about the session Event object and properties. -* [Actions API object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object): Learn about the session API object and methods. +## Learn more: + +* [Refresh tokens](/docs/secure/tokens/refresh-tokens): Learn about Refresh tokens. +* [Sessions](/docs/manage-users/sessions): Learn about Sessions. +* [Actions Event objects](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object): Learn about the `post-login` event object and properties. +* [Actions API object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object): Learn about the `post-login` API object and methods. From 63338cd89a716ccfe0f96f450c76dadec3f682ce Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 18:15:10 +0100 Subject: [PATCH 07/10] Update use-cases.mdx --- .../refresh-token-metadata/use-cases.mdx | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx index 7236fbfff1..83297e56ba 100644 --- a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -12,7 +12,7 @@ validatedOn: 2026-03-06 * [Managing transient data from upstream identity providers (IDPs)](/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases#manage-transient-data-from-upstream-identity-providers-idps) * [Enhancing security and fraud detection](/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases#enhance-security-and-fraud-detection) -To learn more, read [A guide to Auth0 Session and Refresh Token Metadata](https://auth0.com/blog/auth0-session-refresh-token-metadata-guide/). +To learn more, read [A guide to Auth0 Session and Refresh Token Metadata](https://auth0.com/blog/auth0-session-refresh-token-metadata-guide). Auth0 session metadata is not a secure data store and should not be used to store sensitive information. This includes secrets and high-risk PII like social security numbers or credit card numbers, etc. Auth0 customers are strongly encouraged to evaluate the data stored in metadata and only store that which is necessary for identity and access management purposes. To learn more, read [Auth0 General Data Protection Regulation Compliance](/docs/secure/data-privacy-and-compliance/gdpr). @@ -31,7 +31,7 @@ Using persistent custom claims, you can access application specific data, such a Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) [Action](/docs/customize/actions) trigger to create persistent custom claims and assign them to refresh token metadata using the `api.refreshToken.setMetadata()` object. -```javascript custom claim Action expandable +```javascript custom claim Action example expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -81,7 +81,7 @@ api.refreshToken.setMetadata('customClaim2', customClaimValue2); api.accessToken.setCustomClaim('custom_claim_2', customClaimValue2); }; ``` -During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens, a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. +During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens), a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. A single `post-login` Action can handle different `grant_type` scenarios using the `event.request.body.grant_type` object to manage claim persistence. The `event.refresh_token` object is only read available during refresh token exchanges. @@ -98,9 +98,10 @@ Using unique session IDs, you can: * Enable [APIs](/docs/get-started/apis#apis) to provide granular logging, rate limiting, and contextual authorization decisions. * Apply consistent UX experiences that span multiple token lifecycles. -Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to create a unique session ID and assign it to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects. Add the unique session ID, as a custom claim to the ID and access tokens, using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. +Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to create a unique session ID and assign it to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects. +Add the unique session ID, as a custom claim to the ID and access tokens, using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript unique Session ID Action expandable +```javascript unique session ID Action example expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -164,7 +165,7 @@ Using a persistent tenant identifier, you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify the user’s active tenant either by querying the application for an `ext-tenantId` value provided during the authentication request, infer the tenant using geo-location, or by prompting the user to select their desired tenant. Once the tenant is identified, assign the tenant identifier value to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, and add it as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript tenant identifier Action expandable +```javascript tenant identifier Action example expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -230,9 +231,10 @@ Using transient data, you can: * Improve compliance by facilitating adherence to data privacy and retention policies by storing transient data only for its required lifetime * Reduce development overhead by simplifying the process of handling transient IDP data, as Auth0 Actions and metadata manage the data lifecycle -Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify user profile data contained in the `event.request`, `event.user`, and `event.context` objects. Determine which data is transient or contextual data and assign it to the user’s session, using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add the transient data as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. +Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify user profile data contained in the `event.request`, `event.user`, and `event.context` objects. +Determine which data is transient or contextual data and assign it to the user’s session, using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add the transient data as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -```javascript transient data Action expandable +```javascript transient data Action example expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -296,7 +298,7 @@ By implementing adaptive security you can: Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify contextual user data that can include device fingerprint, geographic location, network attributes, and behavioral attributes. Store the contextual data for comparison in the user’s session, using the `api.session.setMetadata()` object. -```javascript security detection Action expandable +```javascript security detection Action example expandable /** * @param {Event} event - Details about the user and the authentication transaction. * @param {PostLoginActionAPI} api - Interface to modify the completed auth transaction. @@ -328,7 +330,7 @@ During a refresh token exchange or silent authentication, a subsequent `post-log ## Access Metadata with the Management API -You can use the Auth0 Management API `GET` [/api/v2/refresh-tokens/{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the stored data in either a refresh token or session’s metadata. +You can use the Auth0 Management API `GET` [/api/v2/refresh-tokens/\{id}](/docs/api/management/v2/refresh-tokens/get-refresh-token) and [/api/v2/sessions/\{id}](/docs/api/management/v2/sessions/get-session) endpoints to retrieve the stored data in either a refresh token or session’s metadata. The response includes the `metadata` field containing the stored data: ```json @@ -338,7 +340,6 @@ The response includes the `metadata` field containing the stored data: "deviceIdentifier": "deviceIdentifier" } } - ``` ## Learn more: From c947e968f2154efd8f83c2797d36d43706572454 Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 18:21:51 +0100 Subject: [PATCH 08/10] Update use-cases.mdx --- .../refresh-tokens/refresh-token-metadata/use-cases.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx index 83297e56ba..cbdc57a642 100644 --- a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -99,6 +99,8 @@ Using unique session IDs, you can: * Apply consistent UX experiences that span multiple token lifecycles. Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to create a unique session ID and assign it to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects. + + Add the unique session ID, as a custom claim to the ID and access tokens, using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. ```javascript unique session ID Action example expandable @@ -163,6 +165,8 @@ Using a persistent tenant identifier, you can: * Improve scalability by reducing the need for repeated database queries or complex logic to determine tenant context on every API call or token refresh Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify the user’s active tenant either by querying the application for an `ext-tenantId` value provided during the authentication request, infer the tenant using geo-location, or by prompting the user to select their desired tenant. + + Once the tenant is identified, assign the tenant identifier value to the user’s session using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, and add it as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. ```javascript tenant identifier Action example expandable @@ -232,6 +236,8 @@ Using transient data, you can: * Reduce development overhead by simplifying the process of handling transient IDP data, as Auth0 Actions and metadata manage the data lifecycle Configure a [post-login](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger#login-/-post-login) Action trigger to identify user profile data contained in the `event.request`, `event.user`, and `event.context` objects. + + Determine which data is transient or contextual data and assign it to the user’s session, using the `api.session.setMetadata()` and `api.refreshToken.setMetadata()` objects, add the transient data as a custom claim to the ID and access tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. ```javascript transient data Action example expandable From 03da01fc60b728c9b2adabec7181cfbbabee5686 Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Fri, 6 Mar 2026 18:31:03 +0100 Subject: [PATCH 09/10] Update use-cases.mdx --- .../tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx index cbdc57a642..e6079c64a0 100644 --- a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -84,7 +84,7 @@ api.refreshToken.setMetadata('customClaim2', customClaimValue2); During a [refresh token exchange](/docs/secure/tokens/refresh-tokens/use-refresh-tokens#use-refresh-tokens), a subsequent `post-login` Action trigger can access these custom claims, using the `event.refresh_token.metadata` object and apply them to newly issued refresh tokens using the `api.idToken.setCustomClaim()` and `api.accessToken.setCustomClaim()` objects. -A single `post-login` Action can handle different `grant_type` scenarios using the `event.request.body.grant_type` object to manage claim persistence. The `event.refresh_token` object is only read available during refresh token exchanges. +A single `post-login` Action can handle different `grant_type` scenarios using the `event.request.body.grant_type` object to manage claim persistence. The `event.refresh_token` object is read-only available during refresh token exchanges. ## Create a unique session ID From 2912ffed51880989580e57694369f21428395fa4 Mon Sep 17 00:00:00 2001 From: Carlos Fung Date: Tue, 17 Mar 2026 17:27:10 +0100 Subject: [PATCH 10/10] Update use-cases.mdx --- .../tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx index e6079c64a0..db3ade74f7 100644 --- a/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx +++ b/main/docs/secure/tokens/refresh-tokens/refresh-token-metadata/use-cases.mdx @@ -348,7 +348,7 @@ The response includes the `metadata` field containing the stored data: } ``` -## Learn more: +## Learn more * [Refresh tokens](/docs/secure/tokens/refresh-tokens): Learn about Refresh tokens. * [Sessions](/docs/manage-users/sessions): Learn about Sessions.