Accepting the minimum version in your dashboard settings will enforce step-up authentication for all sensitive operations. You can start integrating step-up flows on V4, but we recommend not accepting the minimum version until you have upgraded to V5.
Overview
Step-up authentication requires users to re-verify their identity before performing sensitive actions — exporting a private key, linking a new credential, deleting a passkey, etc. After successful verification, the user receives an elevated access token: a short-lived, scope-bound JWT that authorizes the specific operation. Step-up authentication encompasses both re-authentication and MFA:- Re-authentication — Email OTP, SMS OTP, OAuth (social), or external wallet signature. The user proves control of an existing credential. Embedded wallets cannot be used for step-up verification.
- MFA (multi-factor authentication) — Passkey, TOTP, or recovery code. The user proves possession of a registered second factor.
For MFA-specific setup (enrollment, session-based MFA, device management), see Multi-Factor Authentication (MFA). If your users have MFA enabled, the SDK automatically routes step-up verification through MFA.
Enabling step-up authentication
Step-up authentication is enforced once you accept the minimum version via the Developers > SDK & API Keys page in your dashboard. This confirms that your integration is compatible with step-up enforcement. Until the minimum version is accepted, the backend will not require elevated access tokens on any endpoints. You can start integrating step-up flows on V4, but we recommend upgrading to V5 before accepting the minimum version. New environments have step-up authentication enforced by default and cannot downgrade. Only existing environments created before step-up was introduced need to opt in via the minimum version setting.After enabling, step-up is enforced server-side — even if a client sends requests without an elevated token, the backend will reject them with a
403. Make sure your integration handles the step-up flow before enabling enforcement.When is step-up authentication required?
When step-up authentication is enabled for your environment, the backend enforces it on sensitive operations. The user must present a valid elevated access token or the request is rejected with a403.
| Action | Required scope | Enforced |
|---|---|---|
| Export a wallet private key | wallet:export | Always |
| Sign a message or transaction | wallet:sign | Only if configured |
| Link a new credential (wallet, email, phone, social) | credential:link | Always |
| Unlink a credential (wallet, email, phone, social, passkey, MFA device) | credential:unlink | Always |
- Initial sign-in and sign-up flows
- Reading user data or wallet balances
- Signing transactions with an embedded wallet (unless
wallet:signis configured)
How it works
- Check — Before a sensitive action, the SDK checks whether the user already has a valid elevated access token for the required scope.
- Verify — If no valid token exists, the user is prompted to verify. The SDK automatically selects MFA or re-authentication based on the user’s configuration.
- Use — After successful verification, the token is stored in SDK state. The SDK automatically attaches it to the relevant API calls — no manual token handling is needed.
Supported verification methods
| Method | Type | Description |
|---|---|---|
| Email OTP | Re-auth | One-time code sent to the user’s verified email |
| SMS OTP | Re-auth | One-time code sent to the user’s verified phone number |
| Wallet signature | Re-auth | Sign a message with a connected wallet |
| Social (OAuth) | Re-auth | Re-authenticate with a linked social account (Google, GitHub, etc.) |
| Passkey | MFA | Authenticate with a registered passkey (WebAuthn) |
| TOTP | MFA | Enter a code from an authenticator app |
| Recovery codes | MFA | Use a backup recovery code |
Scopes
Elevated access tokens are bound to specific scopes. When requesting step-up authentication, specify which scopes you need viarequestedScopes. The table below shows each scope, which SDK operations require it, and the underlying API endpoints that enforce it.
Exclusive scopes must be requested alone — they cannot be combined with other scopes in a single requestedScopes request. Non-exclusive scopes can be freely combined (e.g., ['credential:link', 'credential:unlink']).
Wallet operations
| Scope | SDK operation | API endpoint | Single-use | Exclusive |
|---|---|---|---|---|
wallet:export | Export a wallet’s private key or seed phrase | POST .../waas/{walletId}/privateKey/export | Yes | Yes |
wallet:sign | Sign a message or transaction with an embedded wallet | POST .../waas/{walletId}/delegatedAccess/signMessage | Configurable | Yes |
Credential operations
| Scope | SDK operation | API endpoint | Single-use | Exclusive |
|---|---|---|---|---|
credential:link | Link a wallet | POST .../verify/link | No | No |
| Verify a wallet (linking) | POST .../wallets/verify | |||
| Link an OAuth social account | POST .../providers/{providerType}/verify | |||
| Verify email OTP (linking) | POST .../emailVerifications/verify | |||
| Verify SMS OTP (linking) | POST .../smsVerifications/verify | |||
| Register a passkey MFA device | POST .../users/mfa/passkey | |||
| Register a TOTP MFA device | POST .../users/mfa/totp | |||
credential:unlink | Unlink a credential | POST .../verify/unlink | No | No |
| Delete a passkey | DELETE .../users/passkeys | |||
| Delete an MFA device (TOTP) | DELETE .../users/mfa/{mfaDeviceId} |
Single-use scopes (like
wallet:export) are consumed after the SDK uses them for the first qualifying API call. The user must re-verify to perform the action again.The
credential:link scope is required on verification endpoints (email, SMS, OAuth, wallet) only when the request includes requestedScopes — meaning the caller is performing step-up reauthentication. Normal sign-in and sign-up flows through these same endpoints do not require an elevated token.Token lifecycle
| Property | Single-use tokens | Multi-use tokens |
|---|---|---|
| Expiration | 5 minutes | 10 minutes |
| Consumed after use | Yes — removed from state after the SDK uses it for the first qualifying API call | No — remains valid until expiration |
| Can combine scopes | No — must be the only scope requested | Yes — multiple scopes in one request |
| Scope-bound | Yes | Yes |
| Automatic cleanup | Expired tokens are filtered out automatically | Same |
Dynamic’s built-in UI
When using Dynamic’s built-in UI (available in the React SDK), step-up authentication is handled automatically for Dynamic’s own operations:- Wallet export — The export flow prompts for step-up before showing the private key.
- Credential linking/unlinking — Linking a new wallet, social account, or email/phone prompts for step-up in the widget UI.
- Passkey/TOTP deletion — The MFA management views prompt for step-up before deletion.
Migration from MFA tokens
createMfaToken (deprecated) | requestedScopes (recommended) | |
|---|---|---|
| Token type | Unscoped MFA token | Scoped elevated access token (JWT) |
| Expiration | Single-use, no time limit | Time-limited (5 or 10 min) |
| Scope | None — accepted for any action | Bound to specific scopes |
| Storage | Manual handling required | Automatically stored and applied by SDK |
| MFA enforcement | Not enforced for non-MFA methods | Enforced when MFA is enabled |
SDK implementation guides
JavaScript SDK
Headless implementation with direct function calls. Use this for vanilla JS, Vue, Svelte, Angular, or any non-React framework.
React SDK
Hooks with automatic routing, Dynamic UI prompts, and headless React patterns.
React Native SDK
Built-in UI prompts and headless verification for React Native mobile apps.
Flutter SDK
Step-up auth module with built-in UI prompts and individual verification methods.