bland-coat-72070
07/11/2025, 9:37 AMbrief-egg-61061
07/11/2025, 9:37 AMbrief-egg-61061
07/11/2025, 9:37 AMemail
scope will include the user's verifiable email address as the email
and email_verified
claims. - The profile
scope will map certain traits: - identity.traits.username
→ username
claim - identity.traits.website
→ website
claim - identity.traits.name
(if an object) → given_name
and family_name
claims If identity.traits.name
is a string, it is used for the name
claim. If it is an object, traits.name.first
and traits.name.last
are mapped to given_name
and family_name
respectively. This mapping is automatic for these standard OIDC claims and scopes. For more advanced or custom mappings, you would need to implement a custom consent UI or use webhooks to inject additional claims, as the default setup does not support arbitrary trait-to-claim mapping out of the box. This is a known limitation, and for more complex use cases, a custom consent endpoint is recommended [Customize OpenID Connect scope and claims](https://www.ory.sh/docs/oauth2-oidc/openid-connect-claims-scope-custom), [Default Consent UI should be able to populate ID token from traits](https://github.com/ory/network/issues/261). In summary: Standard traits are mapped to standard OIDC claims automatically, but for custom trait-to-claim mappings in the ID token, you need to use a custom consent UI or similar workaround.bland-coat-72070
07/11/2025, 9:51 AMbrief-egg-61061
07/11/2025, 9:51 AMbrief-egg-61061
07/11/2025, 9:52 AMemail
scope The email
claim is only included if the email
scope is requested and consented to. If you do not see the email in the claims, check that the OAuth2 client (the relying party) is requesting the email
scope during the authorization flow. This is a standard OIDC behavior in Ory: > For the email
scope, the system uses the verifiable addresses of a user. The first verifiable email is used to include the email in the ID token claims. This means that both email_verified
and email
claims get set. [Customize OpenID Connect scope and claims](https://www.ory.sh/docs/oauth2-oidc/openid-connect-claims-scope-custom) 2. Only verified emails are included Only verified email addresses are included in the ID token. If the user’s email is not verified, it will not appear in the claims, even if the email
scope is requested. [Customize OpenID Connect scope and claims](https://www.ory.sh/docs/oauth2-oidc/openid-connect-claims-scope-custom) --- ### Auto-verifying emails mapped from Entra ID To auto-verify emails that are mapped in from a social sign-in provider like Entra ID (Azure AD), you need to carry over the verified status from the provider. Ory Kratos supports this by allowing you to set the verified_addresses
field in your Jsonnet data mapping snippet for the OIDC provider. For example: jsonnet local claims = { email_verified: false, } + std.extVar('claims'); { identity: { traits: { [if 'email' in claims && claims.email_verified then 'email' else null]: claims.email, // ...other traits }, verified_addresses: std.prune([ // Carry over verified status from Social Sign-In provider. if 'email' in claims && claims.email_verified then { via: 'email', value: claims.email }, ]), }, }
This will mark the email as verified in Kratos if the provider (e.g., Entra ID) asserts that the email is verified. [Carry over verified status from Social Sign-In](https://www.ory.sh/docs/kratos/self-service/flows/verify-email-account-activation#carry-over-verified-status-from-social-sign-in) Note: This only works if the verified address is present in the identity's traits and marked as a verifiable email in your identity schema. --- Summary: - Request the email
scope in your OAuth2 flow. - Only verified emails are included in the ID token. - To auto-verify emails from Entra ID, use the verified_addresses
mapping in your OIDC provider configuration in Kratos.bland-coat-72070
07/11/2025, 10:01 AMoid
trait on users which is mapped from the Entra ID token. How can I make this available as a claim in the ext
claim?brief-egg-61061
07/11/2025, 10:01 AMbrief-egg-61061
07/11/2025, 10:01 AMoid
from your Kratos identity as a claim in the ext
claim of the ID token (and thus in the Hydra token hook payload), you need to use a custom consent UI or an OAuth2 webhook to add custom claims to the token. The default Ory Account Experience only maps standard OIDC claims and does not automatically include custom traits like oid
in the ext
claim. How to add a custom claim using a webhook: You can use an OAuth2 webhook to modify the claims of the issued tokens. In your webhook handler, you can add the oid
trait from the identity to the id_token
(and it will appear in the ext
claim): json { "session": { "id_token": { "oid": "the-oid-value" } } }
This will result in the following structure in the ID token: json { // ... standard claims ... "ext": { "oid": "the-oid-value" } }
[Customizing claims with OAuth2 webhooks](https://www.ory.sh/docs/hydra/guides/claims-at-refresh#responding-to-the-webhook) Summary: - The default setup does not map custom traits like oid
to the ext
claim. - Use an OAuth2 webhook to add the oid
trait as a custom claim in the id_token
, which will then appear in the ext
claim of the token. If you need more details on how to set up the webhook or access the Kratos identity traits within the webhook, please let me know!bland-coat-72070
07/11/2025, 10:10 AMbrief-egg-61061
07/11/2025, 10:10 AMbrief-egg-61061
07/11/2025, 10:10 AMsession
field of the acceptOAuth2ConsentRequest
call. This is where you can inject user traits or other custom data you want to be available in the token webhook payload. To have specific user traits (such as your custom oid
trait) available in the session information sent to the token webhook, you must ensure that your consent app (the service handling the consent UI) retrieves the relevant traits from Kratos and includes them in the session
object when accepting the consent request. For example: js return await ory.acceptOAuth2ConsentRequest({ consentChallenge: consentChallenge, acceptOAuth2ConsentRequest: { session: { id_token: { oid: user.traits.oid, // Add your custom trait here }, // ...other claims... }, }, });
This will make the oid
trait available in the id_token
section of the session object, and it will be included in the payload sent to your token webhook. The webhook can then further process or map this value as needed. The default Ory Account Experience does not automatically include custom traits; you must explicitly add them in your custom consent app logic as shown above [Custom consent UI and custom claims for JWT access token](https://www.ory.sh/docs/oauth2-oidc/jwt-access-token#custom-consent-ui-and-custom-claims-for-jwt-access-token). If you are using the default Ory Account Experience (AX) and not a custom consent app, only standard OIDC claims are mapped, and custom traits like oid
will not be present in the session payload sent to the webhook. For more advanced mapping, a custom consent UI is required, as noted in the knowledge sources [Default Consent UI should be able to populate ID token from traits](https://github.com/ory/network/issues/261). Summary: - To have user traits in the session payload for the token webhook, you must add them in the session
object when accepting the consent request in your consent app. - The default Ory Account Experience does not include custom traits; a custom consent UI is needed for this.bland-coat-72070
07/11/2025, 10:18 AMbrief-egg-61061
07/11/2025, 10:18 AMbrief-egg-61061
07/11/2025, 10:18 AMjs async function createOAuth2ConsentRequestSession( grantScopes, consentRequest, identityApi ) { const id_token = {} if (consentRequest.subject && grantScopes.length > 0) { const identity = ( await identityApi.getIdentity({ id: consentRequest.subject }) ).data if (grantScopes.indexOf("email") > -1) { id_token.email = identity.traits["email"] || "" } if (grantScopes.indexOf("phone") > -1) { id_token.phone = identity.traits["phone"] || "" } // Add custom traits as needed, e.g.: // id_token.oid = identity.traits["oid"] || "" } return { access_token: {}, id_token, } }
In this example, you use the identityApi.getIdentity
method to fetch the user object, then map any traits you need (such as oid
) into the id_token
or access_token
session objects. This makes those traits available in the token and in the token webhook payload as well. Note: This approach requires a custom consent app. The default Ory Account Experience does not provide access to custom traits in the session object by default [Consent endpoint code example](https://www.ory.sh/docs/oauth2-oidc/custom-login-consent/flow#consent-endpoint-code-example).