Step-up is when the platform demands MFA in the middle of a session. Even though the user signed in already (with or without MFA), specific events or conditions trigger a fresh challenge. The user completes MFA again; the session's AAL is bumped; the action proceeds.
Step-up is the dial between "MFA every sign-in" (annoying for users) and "MFA never" (insufficient for sensitive actions). It targets specifically the moments that matter.
Configure step-up policies
Section titled “Configure step-up policies”MFA → Adaptive step-up.
You define policies. Each policy has:
- Trigger — what condition / event fires the step-up.
- Required factor — which factor satisfies (any enrolled / specifically WebAuthn / specifically not SMS).
- AAL target — what AAL the session should reach after the step-up completes.
- Duration — how long the elevated AAL persists before re-prompting.
The policies stack — multiple triggers can each fire step-up; the most-restrictive applicable AAL wins.
Event-based triggers
Section titled “Event-based triggers”Specific user actions that demand step-up:
- Sensitive operations — changing primary email, deleting account, generating an API key. Configure per operation; the user-facing app or your code triggers the AAL check.
- Admin tenant actions — performing high-risk admin operations (deleting an application, force-resetting another user's MFA, exporting users). Defaults to step-up for these.
- First time accessing a resource class — first time the user opens "Payments" in the app, step up. Subsequent opens within the duration don't re-prompt.
Risk-based triggers
Section titled “Risk-based triggers”The platform's risk engine scores every sign-in attempt. Configure thresholds:
- Risk score ≥ X → demand step-up before letting the session proceed.
- From a new device → step-up on first sign-in from each new device fingerprint.
- From a new country → step-up when the user signs in from a country they haven't signed in from in the last N days.
- Geographic velocity — sign-in from one city, then sign-in from another city 5 minutes later (impossible travel) → step-up.
- Threat intel hit — the user's IP appeared in a threat feed → step-up.
The risk engine is on by default; configure scoring + thresholds in Threat intelligence.
Duration
Section titled “Duration”After step-up succeeds, the elevated AAL persists for the configured duration. Common values:
- 15 minutes — for AAL 2 in routine sensitive operations.
- 5 minutes — for AAL 3 in highly sensitive operations.
Tighter = more friction for power users doing many sensitive actions in a row. Looser = a stolen access token has a longer effectiveness window. The 15-minute default is a sensible balance.
The user experience
Section titled “The user experience”A user opens the "Change email" page in your app. Your app calls the API. The API returns 401 step_up_required with required_acr: aal2. The SDK reads this, shows the user a "Confirm your identity" prompt with their already-enrolled factor (passkey, TOTP, etc.). User confirms. SDK gets a fresh access token with the elevated AAL. Original API call retries; succeeds.
From the user's perspective, one extra "Confirm with Touch ID" tap inserted into the flow. The whole round trip is sub-2-seconds for WebAuthn; longer for TOTP or SMS.
The developer experience
Section titled “The developer experience”Your applications need to honour the step-up contract:
- Backend: check the access token's
acrclaim on sensitive endpoints. If insufficient, return 401 with the step_up_required envelope. - Frontend: catch 401s with that envelope and call the SDK's
stepUpmethod.
See Step-up authentication (developer reference) for the full integration.
Per-tenant + per-application policies
Section titled “Per-tenant + per-application policies”Step-up policies live primarily at the tenant level. Individual applications can override:
- "Tenant default: step-up on sensitive operations after 15 min."
- "Application X: step-up on EVERY sensitive operation, no AAL caching."
Override in the application's authentication policy tab.
What to tell users
Section titled “What to tell users”Step-up prompts have a friction cost. The right copy makes them feel protective rather than annoying:
- "Confirm your identity before changing your email."
- "You're signing into Finance from a new device — let's verify."
- "We need to re-verify for this sensitive action."
Avoid "for security reasons" — too vague. Specific framing of WHY the prompt is appearing makes users tolerate it (and trust the platform more).
Configure factor downgrade
Section titled “Configure factor downgrade”Some teams want "step-up via SMS is enough for low-sensitivity operations; only WebAuthn for high-sensitivity." Configure per-policy:
- "Sensitive ops" policy → required factor: any enrolled. AAL 2.
- "Highly sensitive ops" policy → required factor: WebAuthn or TOTP only (no SMS). AAL 3.
The user's existing factors determine which AAL is reachable. A user with only SMS can satisfy AAL 2 (SMS-enrolled session is AAL 2) but not AAL 3 (SMS doesn't satisfy AAL 3 by policy). The platform refuses the action; your application's frontend shows "this operation requires a stronger factor. Set up WebAuthn or TOTP to proceed."
Every step-up records:
auth.step_up_initiated— the platform triggered.auth.step_up_completed— succeeded.auth.step_up_failed— user dismissed or failed.auth.step_up_skipped— the policy didn't fire because the session already had sufficient AAL.
Filter audit on these to investigate "did step-up actually fire when it should have?" patterns.
Don't over-step-up
Section titled “Don't over-step-up”Step-up has a real cost. Reserve it for things that matter:
- Changing email or phone.
- Generating an API key.
- Payouts above a threshold.
- Modifying MFA factors.
- Admin operations on other users.
Don't step-up:
- Routine reads.
- Preference changes.
- Anything the user can undo themselves.
Over-stepping trains users to dismiss prompts reflexively, which weakens the prompt's signal when you really need it.