Which OpenID Connect request parameters ask a provider for a stronger or a fresher sign-in, and how do they differ?
answer
- strength and recency are two different asks
- space-separated, in order of preference
- one of the two carries a MUST
- acr_values is a preference, not a promise
- max_age forces auth_time to be returned
basics
~20 sacr_values names the authentication context class references the request prefers, in order of preference; max_age caps how many seconds may have passed since the user last actively authenticated. Strength versus recency — and only max_age carries an obligation on the provider.
solid answer
~50 s`acr_values` is a space-separated list of authentication context class references on the authentication request, in order of preference — it asks the provider to use one of them, and the context actually satisfied comes back as the `acr` claim. It is a *voluntary* request: the provider may authenticate the user some other way and return a value you did not ask for, so the relying party has to look at what came back rather than assume. `max_age` is different in kind and in force: it states an allowable elapsed time in seconds since the last active authentication, and if the elapsed time is greater the provider MUST attempt to re-authenticate. Using `max_age` also obliges the provider to include `auth_time` in the ID token. What the `acr` strings *mean* is fixed by a profile the parties agree out of band, not by OpenID Connect; a provider advertises the ones it accepts in `acr_values_supported`.
code
http · 6 linesGET /authorize?response_type=code&client_id=lab-cases
&redirect_uri=https%3A%2F%2Fcases.example%2Fcb
&scope=openid&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj
&acr_values=urn%3Aexample%3Amfa%20urn%3Aexample%3Apwd
&max_age=300 HTTP/1.1
Host: provider.examplego deeper
Recall that a request can ask for a specific kind of sign-in and can ask that it be recent, and that these are two separate parameters with two separate meanings.
Explain the difference in force: a context request is voluntary and may come back unsatisfied, while exceeding the stated maximum authentication age obliges the provider to attempt re-authentication and to report when it happened.
Demonstrate the check, not just the ask. Describe the silent failure where a successful response carries a weaker context than requested, and what your service does when the reported context falls short.
Own the mapping between business risk and requested context across an estate of providers you do not control, including what happens when a partner's strongest advertised value is weaker than your policy wants.
## Two different questions one request can ask A relying party that wants a stronger sign-in before a sensitive operation is really asking one of two questions, and OpenID Connect gives each its own parameter on the authentication request: - **"Authenticate them *this way*"** — `acr_values`. - **"Authenticate them *recently*"** — `max_age`. A dental laboratory's case-tracking site can let a practice browse its case queue on an ordinary sign-in, and demand one of these before it releases a patient's case record. They compose: a request may carry both. ## `acr_values`: which context, in order of preference `acr_values` is a **space-separated string** of authentication context class references, listed **in order of preference**. Each value is an opaque string whose meaning comes from a profile the relying party and the provider have agreed on; OpenID Connect itself defines no values, and an IANA registry exists for level-of-assurance profiles (`RFC 6711`). Grading what a level *means* — what an identity, authenticator or federation assurance grade demands — is a separate subject from the parameter that names one. The critical property is **how binding it is**. This parameter requests the `acr` claim as a **voluntary** claim: it expresses a preference, and a provider may authenticate the user some other way and return a context you never asked for. Three consequences follow: - The relying party **must read the returned `acr`** and decide for itself whether the request was satisfied. - A request that succeeds is not evidence that the requested context was used. - Making the context a hard requirement is a different mechanism — asking for `acr` as an *essential* claim through the `claims` request parameter — and even then the relying party still checks. A provider advertises the values it will accept in the `acr_values_supported` field of its configuration document, which is how an integration discovers the strings to send instead of guessing them. ## `max_age`: how recently, and with a MUST behind it `max_age` is an integer number of **seconds**: the allowable elapsed time since the end user was last actively authenticated by the provider. If the elapsed time is greater than that value, the provider **MUST attempt to actively re-authenticate** the user. That is a materially stronger obligation than `acr_values` carries. It also changes what comes back. When `max_age` is used, the ID token returned **MUST include** the `auth_time` claim — the time of that last active authentication — so the relying party can check the bound for itself rather than trusting that the provider applied it. Validating claims in the returned ID token is its own subject; what belongs here is knowing that sending `max_age` is what compels the provider to report the number you need. ## Side by side | | `acr_values` | `max_age` | |---|---|---| | What it asks for | the kind or strength of authentication | the recency of the authentication | | Value shape | space-separated context class references, in order of preference | an integer count of seconds | | Force | a request; `acr` is asked for as a voluntary claim | if elapsed time is greater, the provider MUST attempt re-authentication | | What the provider reports back | the `acr` claim, possibly not a value you sent | the `auth_time` claim, which MUST be present when `max_age` is used | | Advertised in provider metadata | `acr_values_supported` | not advertised as a capability | ## The failure this material actually produces The production failure is not a rejected request; it is a **successful** one. A site sends `acr_values`, receives a normal response, elevates the user, and releases the record — while the provider authenticated the user from an existing session with a weaker method entirely. Nothing errored. The habit that prevents it is stated once and applies to both parameters: **the request is an ask; the response is the evidence.** A second failure is subtler and comes from confusing the two axes. A user who authenticated with a strong method eight hours ago satisfies a strength request and fails a freshness one; a user who authenticated thirty seconds ago with a weak one is the reverse. Deciding which of those a given operation needs is a policy question about your own product, and where it is recorded and how long it stays true is your application's own business, not the protocol's. The protocol's contribution stops at giving you two precise ways to ask and two precise things to check in the answer. ## Practical sequence 1. Read the provider's `acr_values_supported` to learn the strings it accepts. 2. Send `acr_values`, `max_age`, or both on the authentication request for the operation that needs it. 3. When the response arrives, check the reported context and authentication time against what you asked for. 4. Treat a shortfall as a decision your service makes — not as something the successful response already settled.
- The response comes back successfully but reports a different authentication context than the one requested. What happened?Nothing went wrong on the wire. `acr_values` requests the context as a voluntary claim, so the provider may authenticate the user by another method and report that instead. The relying party compares what came back against what the operation needs and decides — refuse, ask again with a tighter request, or accept.
- How can a request make the authentication context a hard requirement rather than a preference?By asking for `acr` as an *essential* claim through the `claims` request parameter, which is the general mechanism for requesting individual claims and marking them essential. Even that does not remove the relying party's obligation to check the returned value; it only changes how strongly the request is stated.
- What exactly does `max_age` oblige the provider to do?Two things. If the elapsed time since the user was last actively authenticated is greater than the value, it MUST attempt to actively re-authenticate them. And when `max_age` is used at all, the ID token it returns MUST include `auth_time`, the time of that last active authentication, so the bound can be verified rather than assumed.
- Where do the strings in `acr_values` come from?Not from OpenID Connect, which defines none of them. They are profile-defined identifiers the two parties agree on out of band, and an IANA registry exists for level-of-assurance profiles. A provider publishes the ones it will accept in `acr_values_supported`, which is the right place to read them from rather than inventing a value.
saying these in an interview costs you the question
- Thinks the provider must authenticate with a requested acr value
- Treats a successful response as proof the context was satisfied
- Reads max_age as the lifetime of the issued token
- Believes OpenID Connect defines the standard acr strings
- Confuses asking for a context with grading what it means
- Sends acr_values as a comma-separated list