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_agewas 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=loginparameter:

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_agewith 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_ageparameter 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
promptparameter and not validate that the AS actually re-authenticated. - prompt=login & max_age=999999: Include an arbitrary
max_agesuch that anauth_timeclaim 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_ageparameter. 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=loginrequest 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_timeclaim to ensureauth_timeis 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.