prompt=login
mechanism can be subverted by simply stripping the parameter as it passes through the user agent (browser) and is only good for providing a UX hint to the provider (OP) in cases when the (RP) wants to display a link like:
“Hi Josh. Not you? Click here.”
However, you should not rely on it to validate that a fresh authentication took place. To mitigate this, the client must validate that re-authentication has taken place using the auth_time
claim if re-authentication is whymax_age
was requested. This claim will be included automatically in the when prompt-login
or max_age=0
parameters are given in the authentication request.
You need to pass the max_age
parameter to the Authorization API /authorize
endpoint. If you use Auth0.js or Lock, you can set the parameter in the appropriate options of the library.
How you implement re-authentication depends on your specific use-case. Make a distinction between simple re-authentication for sensitive operations vs. step-up (i.e. ) for sensitive operations. Both are valid security measures. The former requires the end user to re-enter their password, whereas the latter requires them to use a pre-configured means of multifactor authentication as well.
Limitations of prompt=login parameters
The OIDC spec defines theprompt=login
parameter that can be used to trigger re-authentication UI (usually a login prompt):
promptOPTIONAL: Space delimited, case sensitive list of ASCII string values that specifies whether the authorization server prompts the end-user for re-authentication and consent. The defined values are:loginThe authorization server should prompt the end-user for re-authentication. If it cannot re-authenticate the end-user, it must return an error, typically
login_required
.JSON
prompt=login
parameter and the RP doesn’t know the difference in the fields contained in the ID token.
Here’s a diagram of a simplified implicit flow using the prompt=login
parameter:

prompt=login
parameter and the re-authentication step can be skipped:

prompt=login
has actually yielded a re-authentication.
max_age authentication request parameter
Unlikeprompt=login
, the max_age
authentication request parameter provides a mechanism whereby RPs can positively confirm that re-authentication has taken place within a given time interval. The OIDC spec states:
max_ageOPTIONAL: Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the end-user was actively authenticated by the OP. If the elapsed time is greater than this value, the OP must attempt to actively re-authenticate the end-user. (The
max_age
request parameter corresponds to the OpenID 2.0 PAPE max_auth_age
request parameter.) When max_age
is used, the ID token returned must include an auth_time
claim value.max_age
is requested by the RP, an auth_time
claim must be present in the RP. This means that max_age
can be used in one of two ways:
- To enforce a minimum session freshness: If an app has a requirement that users must re-authenticate once per day, this can be enforced in the context of a much longer session by providing
max_age
with a value. These are defined in seconds. - To force an immediate re-authentication: If an app requires that a user re-authenticate prior to access, provide a value of 0 for the
max_age
parameter and the AS will force a fresh login.

auth_time
claim in the ID token to determine whether or not the max_age
parameter it requested was fulfilled. In this way, the max_age=0
parameter is impervious to the same kind of client tampering that could subvert the prompt=login
parameter.
Keep in mind that it’s solely up to the RP to validate that it is receiving an ID token with an appropriate
auth_time
. This extra validation will need to be covered by application authors and frameworks making use of the max_age
parameter.Use auth_time claims
We’ve established that the OIDC spec provides themax_age
parameter as a way to positively confirm a re-authentication has taken place, but prompt=login
does not. This does not present very secure options if you want to force a re-authentication:
- prompt=login: Only include the
prompt
parameter and not validate that the AS actually re-authenticated. - prompt=login & max_age=999999: Include an arbitrary
max_age
such that anauth_time
claim is present. You can validate a re-authentication took place, but the parameters get messy. - max_age=0: Effectively force a login prompt using only the
max_age
parameter. Note that a recent spec update further clarified this parameter, stating it is effectively the same asprompt=login
. This one is not feasible since it blends what should be a UX parameter with a session maintenance parameter.
auth_time
claim in the ID token when responding to aprompt=login
request parameter. This means that you have the option use prompt=login
AND validate that a re-authentication took place.
auth_time validation example
You must be sure to implement validation to ensure a re-authentication has taken place. You must validate that a proper
auth_time
has been returned.max_age=0
option to the Auth0OidcStrategy
:
JavaScript
max_age
parameter:
JavaScript
prompt=login
in the same context, but since the standard does not require an auth_time
to accompany the ID token response, you must handle the validation manually. So, the strategy constructor would be:
JavaScript
max_age=0
, the client must manually perform validation on the auth_time
parameter. To learn more, read Use auth_time claims.
The example above represents a simplified proof-of-concept (it must have authenticated in the last 10 seconds). Ideally, if you want to validate that a re-authentication has occurred, you would need to:
- Store the time that the initial authentication request was made.
- Upon authentication response, retrieve the time at which the request was sent.
- Compare the original authentication request time with the
auth_time
claim to ensureauth_time
is a later timestamp.
Known issues
Auth0 can only guarantee that an exchange took place with the upstream . This may be through the user actually signing in to a third-party identity provider or perhaps the user already had a session and didn’t have to sign in again. Either way, Auth0’s exchange with the upstream identity provider will result in an updatedauth_time
.
Forcing re-authentication within the upstream identity provider is not something Auth0 supports because not all providers support this.
The diagram below presents an example flow for a user who chooses to reauthenticate with a federated connection:

prompt=login
or prompt=consent
is generally a way to indicate an external (social) identity provider to reauthenticate a user, but Auth0 cannot enforce this.
Don’t rely on client-side verification (i.e. in the browser) of the ID token or
auth_time
to prevent sensitive operations.