docs: document upstream MFA carry-over for OIDC social sign-in#2507
Open
docs: document upstream MFA carry-over for OIDC social sign-in#2507
Conversation
Adds a new page describing how Ory carries over upstream OIDC `acr` and `amr` claims into the resulting Ory session. Operators can configure per-provider `aal2_acr_values` and `aal2_amr_values` allowlists to mark sessions as AAL2 when the upstream identity provider has already performed multi-factor authentication. The new page covers: - How Ory reads the upstream `acr` / `amr` claims and decides the session AAL. - A provider support matrix (Generic OIDC, Auth0, Okta, Keycloak, Microsoft Entra v1, Ping Identity, Google, Apple, and others). - Console and CLI configuration examples. - How to ask the upstream provider for a specific `acr` value via `acr_values` or `requested_claims`. - Sample `/sessions/whoami` payload showing the new `upstream_acr` / `upstream_amr` audit fields. - Troubleshooting tips for empty upstream claims and accidental AAL2 elevation. The Dynamic MFA / step-up authentication doc gains a short section that links to the new page so customers enforcing AAL2 discover the option. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
vinckr
reviewed
Apr 13, 2026
|
|
||
| ## Troubleshooting | ||
|
|
||
| **The session is still AAL1 after a successful login.** Check that the upstream provider actually emits the claim. You can inspect |
Member
There was a problem hiding this comment.
Suggested change
| **The session is still AAL1 after a successful login.** Check that the upstream provider actually emits the claim. You can inspect | |
| The session is still AAL1 after a successful login: Check that the upstream provider actually emits the claim. You can inspect |
| `std.extVar('claims').raw_claims.amr`. If the provider doesn't surface the claim, request it explicitly through `acr_values` or | ||
| `requested_claims`. | ||
|
|
||
| **The `upstream_acr` field is empty even though the upstream sent it.** Make sure your provider config has |
Member
There was a problem hiding this comment.
Suggested change
| **The `upstream_acr` field is empty even though the upstream sent it.** Make sure your provider config has | |
| The `upstream_acr` field is empty even though the upstream sent it: Make sure your provider config has |
| `claims_source: id_token` (the default) or, if you set `claims_source: userinfo`, that the userinfo endpoint also returns the | ||
| `acr` claim. Some providers only include `acr`/`amr` in the ID token. | ||
|
|
||
| **The session is AAL2 but the user never completed MFA.** Audit the configured allowlists carefully. An `acr` value such as `0` or |
Member
There was a problem hiding this comment.
Suggested change
| **The session is AAL2 but the user never completed MFA.** Audit the configured allowlists carefully. An `acr` value such as `0` or | |
| The session is AAL2 but the user never completed MFA: Audit the configured allowlists carefully. An `acr` value such as `0` or |
jonas-jonas
reviewed
Apr 17, 2026
Comment on lines
+31
to
+32
| the user is then prompted for a Kratos-managed second factor as usual. Both fields are optional; leaving them empty preserves the | ||
| current behavior of always issuing AAL1 sessions through this provider. |
Member
There was a problem hiding this comment.
Suggested change
| the user is then prompted for a Kratos-managed second factor as usual. Both fields are optional; leaving them empty preserves the | |
| current behavior of always issuing AAL1 sessions through this provider. | |
| the user is then prompted for a Kratos-managed second factor as usual. Both fields are optional; leaving them empty causes Kratos to always issue AAL1 sessions through this provider. |
Comment on lines
+38
to
+56
| ## Provider support | ||
|
|
||
| Not every OIDC provider returns `acr` or `amr`. The table below lists the providers Ory ships with and whether their ID tokens | ||
| include these claims. | ||
|
|
||
| | Provider | `acr` | `amr` | Notes | | ||
| | --------------------------------------------------------------------------------------------------------- | ------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ||
| | Generic OIDC | Yes | Yes | Works with any OIDC-compliant IdP that emits these claims (Keycloak, Microsoft Entra v1, PingFederate, Auth0 federation, Okta federation, and many others). | | ||
| | Microsoft (Entra ID / Azure AD) | v1.0 only | v1.0 only | v1.0 ID tokens include both. v2.0 tokens typically omit `acr` and `amr`. | | ||
| | Auth0 | Yes | Yes | `amr` contains `mfa` once the user completed an MFA challenge. The standard step-up `acr` value is `http://schemas.openid.net/pape/policies/2007/06/multi-factor`. | | ||
| | Okta (federation) | Yes | Yes | Predefined `acr` values such as `urn:okta:loa:1fa:any` and `urn:okta:loa:2fa:any`. `amr` values include `pwd`, `mfa`, `sms`, `hwk`, `fpt`, `face`. | | ||
| | Keycloak | Yes | Yes (recent versions) | `acr` is mapped from the Level-of-Authentication config. `amr` is populated by the dedicated AMR protocol mapper. | | ||
| | Ping Identity (PingAM, PingFederate, PingOne AIC) | Yes (opt-in) | Yes (opt-in) | Neither claim is added by default. Configure them through Authentication Journeys or "Force ACR in ID Token". | | ||
| | Google | No | No | Google's OIDC implementation does not issue `acr` or `amr`. | | ||
| | Apple (Sign in with Apple) | No | No | Not part of Apple's documented ID-token schema. | | ||
| | Facebook, GitHub, GitLab, Discord, Slack, Spotify, Amazon, LinkedIn, Yandex, VK, NetID, Dingtalk, Patreon | No | No | OAuth2-only or non-standard OIDC; no `acr` or `amr` surfaced. | | ||
|
|
||
| You can still configure the allowlist for any provider — Ory simply records the upstream values and never matches when the | ||
| provider doesn't emit them. |
Member
There was a problem hiding this comment.
This will go out of sync fast; let's remove the list and instead just mention checking the provider's documentation for the correct values.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Documents the new upstream OIDC
acr/amrcarry-over feature shipped in ory-corp/cloud#11499.When a user signs in through a social sign-in provider that already enforces MFA, Ory can now trust the upstream factor instead of asking the user to complete a second factor again. This PR adds:
docs/kratos/social-signin/93_upstream-mfa.mdx) covering:acr/amrclaims and decides the resulting session AAL.aal2_acr_valuesandaal2_amr_values.acrvalue viaacr_valuesorrequested_claims./sessions/whoamipayload showing the newupstream_acr/upstream_amraudit fields.Test plan
npx prettier --checkpasses for changed filesnpm run build) — please verify in CIRelated
🤖 Generated with Claude Code