Step-up authentication asks for stronger proof only when an action's risk earns it. How it works, when to trigger it, and how it extends to AI agents.
A user signed in this morning with a password and a one-time code. Six hours later, a request arrives on that same session to change the bank account attached to a pending payout. The session is valid. The token has not expired. Nothing in the access check says no.
Step-up authentication is the control that catches this. It requires a user to prove their identity again, more strongly, at the moment they attempt a sensitive action, rather than trusting the assurance established at login to cover everything they do afterwards. Login answers "who is this?" once. Step-up asks a harder question continuously: does this specific action, right now, deserve the level of confidence this session actually carries?
That question is getting louder, because a growing share of sensitive actions are no longer taken by a person at a keyboard. AI agents now hold credentials, call APIs, and move money on a user's behalf. The rest of this guide covers how step-up authentication works at the protocol level, how to decide what should trigger it, and what changes when the thing being challenged is an agent rather than a human. Between those challenges, what the agent holds should be an ephemeral credential scoped to a single action. Deciding whether the agent may take that action at all is agent authorization.
Step-up authentication is a security mechanism that requires additional or stronger identity verification before a specific high-risk action proceeds, while leaving lower-risk activity in the same session untouched. The user keeps their session. They are challenged only at the boundary where the stakes change.
Every implementation has the same three parts:
It helps to be precise about what step-up authentication is not. It is not a second login. It is not multi-factor authentication applied to everyone all the time. And it is not an access-control decision: authorization answers whether this identity is permitted to perform the action at all, while step-up answers whether the system is confident enough about who is asking. A user with the right role and a six-hour-old session can pass authorization and still fail the assurance test.
Authentication decays. The moment a session is established, the evidence behind it starts aging: the device may change networks, the laptop may be left unlocked, the token may be lifted, the user may hand the machine to a colleague. None of that invalidates the session, and none of it is visible to a permission check that only asks whether a valid token is present.
The standards bodies treat this as a first-class problem rather than an edge case. NIST SP 800-63B defines three Authenticator Assurance Levels and attaches explicit reauthentication intervals to each, precisely because assurance is understood to be time-bounded rather than permanent.
The second argument is blast radius. Most actions in a product are cheap to undo. A few are not. Rotating an API key, changing a payout destination, exporting a customer table, granting an admin role, deleting a production dataset: these are the actions an attacker with a stolen session actually wants, and they are a small fraction of total traffic. Challenging all traffic to protect that fraction trains users to click through prompts without reading them. Challenging only that fraction preserves the signal.
That is the entire design thesis of step-up authentication. Spend friction where it buys something.
The mechanism is specified, not improvised. The IETF published RFC 9470, the OAuth 2.0 Step Up Authentication Challenge Protocol, and it defines the round trip precisely. Understanding the five steps below is what separates a step-up implementation that holds up from a modal dialog that a determined client can skip.
insufficient_user_authentication along with what would be sufficient: an acr_values parameter naming the required authentication strength, a max_age parameter naming how recently the user must have authenticated, or both.acr claim stating which authentication context class was satisfied, and an auth_time claim stating exactly when the user authenticated. Both claims are defined in OpenID Connect Core.Two properties make this design strong. The requirement is declared by the resource server, which is the only component that actually knows how sensitive the operation is, and the proof travels in verifiable token claims rather than in application state a client could forge. Frontegg's step-up implementation follows exactly this shape, using the standard acr, amr and auth_time claims to decide whether a user needs additional verification or genuinely fresh authentication.
"Stronger authentication" is meaningless without a scale. NIST supplies one, and it is the vocabulary worth adopting, because it turns a vague policy ("require MFA for sensitive things") into a testable requirement mapped to an acr value.
| Level | What it proves | Typical authenticators | Reauthentication requirement |
|---|---|---|---|
| AAL1 | Some assurance that the claimant controls an authenticator bound to the account | Single factor: password, or a single-factor OTP device | At least once every 30 days during an extended session, regardless of activity |
| AAL2 | High confidence in control of the bound authenticators | Two distinct factors, or one multi-factor authenticator, using approved cryptography | At least once every 12 hours, and after 30 minutes of inactivity |
| AAL3 | Very high confidence, with verifier impersonation resistance | Hardware-based authenticator proving control of two distinct factors cryptographically | At least once every 12 hours, after 15 minutes of inactivity, and reauthentication must use both factors |
Read that last column as a floor, not a target. It describes when a session must be refreshed anyway. A step-up policy sits on top: even a session that is compliant at AAL2 can be told that this particular action demands AAL3 evidence issued in the last five minutes.
Most guidance on this topic offers a list of examples. Examples do not generalize. What an engineering team needs is a rule it can apply to an action it has not seen before, and two properties do almost all the work: how hard the action is to reverse, and how sensitive the data it touches.
The same decision as a table, which is the form worth putting in a policy document:
| Irreversibility | Data sensitivity | Policy | Examples |
|---|---|---|---|
| High | High | Always challenge, with a short freshness window | Payout destination change, API key rotation, admin grant |
| High | Low | Challenge | Deleting a workspace, changing SSO configuration |
| Low | High | Challenge, or return masked data and challenge to unmask | Bulk customer export, viewing full payment details |
| Low | Low | No challenge | Reading a dashboard, editing a draft |
The matrix sets the baseline per action. Risk signals modulate it per request, lowering the threshold when the context looks wrong:
Scoring these signals is the same exercise as scoring any other agentic or human risk surface. If you are building the scoring model from scratch, the method in our guide to mapping and scoring AI agent risk transfers directly: enumerate the actions, rate impact and reversibility, then attach a control to each band. Step-up is one control in that set, and it composes with the preventive checks described in AI guardrails, which constrain what can be attempted before assurance is ever evaluated.
A challenge that succeeded an hour ago is not evidence about the request happening now. Every step-up policy needs an explicit freshness window, expressed as max_age in seconds, and the right value is a function of consequence rather than convenience. A practical starting set:
Bind the challenge to the transaction wherever the action is irreversible. If the elevated credential is good for fifteen minutes and covers any action of that class, an attacker who wins one challenge wins the window.
A frequent implementation mistake is to treat the outcome of step-up as a boolean stored in the session: stepped_up = true. That flag is invisible to every other service, unverifiable by any resource server, and it survives long after the risk that justified it.
The outcome should instead be a credential with three properties, which is what practitioners mean by scoped tokens:
scope parameter for exactly this purpose since the original OAuth 2.0 specification.Transaction binding is what stops the substitution attack, where a user approves a $50 transfer and an attacker swaps the recipient before the request lands. If the approved amount and destination are inside the credential, swapping either invalidates it.
Scoped credentials only hold if something enforces them at the point of call. In agent architectures that enforcement point is usually the gateway, which is the same place tool-level policy lives; our guide to MCP access control covers how those checks are applied to individual tool invocations.
These four terms are routinely used as synonyms, and they are not. They differ on when the check happens and on what decides it.
| Approach | When it runs | What decides | What it optimizes |
|---|---|---|---|
| Multi-factor authentication | At login | A static policy for the user or tenant | Baseline account security |
| Adaptive authentication | At login | Risk signals evaluated at sign-in | Reducing friction for low-risk logins |
| Step-up authentication | Mid-session, at the action | The sensitivity of the requested operation, plus risk signals | Assurance proportional to consequence |
| Continuous authentication | Constantly, in the background | Passive behavioural and device telemetry | Detecting session takeover |
They compose rather than compete. A mature deployment uses MFA to set the floor, adaptive policy to decide how hard login should be, continuous signals as an input, and step-up as the enforcement point where a specific action meets a specific assurance requirement. The common failure is picking one and calling it done: MFA at login alone leaves every mid-session action covered by evidence that may be twelve hours old.
Every model above assumes a human who can be interrupted. That assumption is now wrong for a meaningful share of production traffic. Autonomous AI agents hold credentials, plan multi-step work, and call APIs without a person watching each call. When such an agent attempts the exact action a step-up policy exists to catch, there is nobody in the session to challenge.
Answering "challenge the agent" does not work, and it is worth being precise about why. An agent can supply any credential it holds. If it holds the second factor, the factor is not a second factor, it is just another secret in the same trust boundary. And the agent's stated intent is not trustworthy evidence either, because instructions reaching an agent can be attacker-controlled: prompt injection is the mechanism by which an agent comes to sincerely believe it should move the money.
The workable model is on behalf of authentication. The agent is a distinct identity with its own credentials, and it acts under authority delegated by a named human principal. When the action crosses the step-up threshold, the challenge is routed not to the agent but to that principal, out of band. That routing is one implementation of human in the loop AI, where a named person clears the action before it executes.
Read the two columns row by row. For a human, the challenge lands in the session and produces an elevated session. For an agent, the challenge leaves the session entirely, lands with the owner through a channel the agent does not control, and produces a credential valid for one operation. That last difference matters most: an agent that receives an elevated session will keep using it.
Teams usually arrive at human in the loop approval from the safety side and at step-up authentication from the security side, then build them twice. They are the same control. Both pause an action at a risk threshold and require a named human to supply proof before it proceeds. Treating them as one mechanism means the approval inherits everything the authentication stack already provides: a verified identity, a real second factor, a signed record, and a token the resource server can check.
The practical design is tiered, and the tiers are the same ones the matrix above produces:
The failure mode to design against is approval fatigue, which is prompt fatigue wearing a different hat. If tier three fires on twenty actions an hour, owners will approve without reading, and the control becomes a rubber stamp that generates an audit trail of rubber stamps. Tier three should be rare by construction.
Agent consent means something specific: the human principal understood and approved the scope of authority the agent holds, and that approval is recorded in a form that can be produced later. It is not the agent asserting that its user would have wanted this.
Useful consent records answer four questions: which agent, acting for which principal, authorized to take which class of actions, until when. Granting an agent a broad, open-ended grant at onboarding and treating every subsequent action as consented is the pattern that turns a compromised agent into an authorized one. Scope the grant to action classes, bound it in time, and require a fresh approval when the agent asks to exceed it. Agents are non-human identities, and they need the same lifecycle discipline as any other machine credential: issued, scoped, rotated, revoked.
An approval that cannot be reconstructed afterwards is not a control, it is a hope. The chain has to be explicit in the token itself, and OAuth 2.0 Token Exchange already provides the vocabulary: the act claim names the actor operating on behalf of the subject, so a resource server can see both the human principal and the agent acting for them.
Record five fields per elevated agent action: the agent identity, the principal who delegated, the approver who answered the challenge, the exact operation and parameters approved, and the timestamp of the approval. That record is what turns an incident review from speculation into a reconstruction. Our guide to auditing AI systems and autonomous agents covers what else belongs in that trail, and if your agents reach tools over the Model Context Protocol, MCP authentication explains how identity is carried on those calls in the first place.
An honest account of the control includes how it fails, because most of these failures are design choices rather than surprises.
acr values and max_age seconds, not as adjectives.insufficient_user_authentication with the required parameters. Never rely on the client to decide it should challenge.Step-up authentication requires a user to verify their identity again, more strongly, before a specific sensitive action proceeds. The user keeps their existing session for ordinary activity and is challenged only at the moment they attempt something high risk, such as moving money, rotating a key, or exporting customer data.
Multi-factor authentication runs once at login and applies the same policy to everything the session does afterwards. Step-up authentication runs mid-session, triggered by the sensitivity of a specific action. MFA sets the baseline assurance for an account; step-up raises assurance for one operation, then lets it expire.
No. Adaptive authentication decides how hard the login should be, based on risk signals evaluated at sign-in. Step-up authentication decides whether an action already inside a session needs stronger proof. They complement each other: adaptive policy sets the entry bar, step-up defends individual operations after entry.
Trigger on the action, not the user. Challenge anything that is hard to reverse or touches sensitive data: payment destination changes, key rotation, admin role grants, bulk exports, account recovery. Use risk signals such as a new device, impossible travel, or a value threshold to lower the trigger point further.
The resource server rejects the request with an insufficient_user_authentication error plus acr_values or max_age. The client sends the user to the authorization server with those parameters, the user authenticates to the required level, and a new token carrying acr and auth_time claims is issued for the retry.
Yes, but the challenge cannot go to the agent, which can supply any credential it holds. It routes out of band to the human principal who delegated authority. The owner approves the specific operation with a real factor, and the agent receives a token scoped to that single action.
Step-up is one control inside a larger discipline. The policies that decide what an agent may attempt at all sit in AI agent governance, and the risk vocabulary those policies use maps cleanly onto the NIST AI Risk Management Framework, which names human oversight as a governance function rather than an implementation detail. Read together, they answer the two halves of the same question: what should this agent be allowed to do, and how sure are we that the person behind it agreed.
Authentication stopped being a door the moment sessions outlived the decisions made inside them, and it stopped being a human problem the moment agents started acting on our behalf. Step-up authentication is how you put the decision back next to the action.
That is also where the hard part lives in agent deployments. Knowing which agent asked, on whose authority, with what approval, and being able to prove it afterwards, is the accountability layer that makes an approval meaningful rather than ceremonial. If you want to see what that looks like applied to your own agents, book a walkthrough of the Agen platform.
Keep reading
What agent authorization is, which model to use, how delegated authority travels in a token, and where the decision belongs so a prompt cannot move it.
Written by
Agen.co
What ephemeral credentials are, how they are issued, how long they should live, and how to move AI agents off static secrets without breaking production.