Step-Up Authentication
Step-up gates sensitive operations behind re-authentication. When a protected endpoint returns 403 step_up_required, complete the flow to receive a short-lived elevated token.
Endpoints
POST /api/auth/step-up/challenge
Request a challenge. Auth:Authorization: Bearer <jwt>.Input: ~~~json { "method": "totp" } ~~~
Methods: totp, magic_link, password.
Output: ~~~json { "challenge_id": "chal-uuid", "method": "totp", "expires_at": "2026-05-11T10:15:00Z" } ~~~
POST /api/auth/step-up/verify
Submit challenge response.Input (TOTP): { "challenge_id": "chal-uuid", "code": "123456" }
Output: ~~~json { "elevated_token": "eyJ...", "expires_in": 900 } ~~~
Use elevated_token as the Authorization: Bearer header for the protected endpoint. Valid 15 minutes.
GET /api/auth/step-up/status
Check if current token has step-up elevation. Response:{ "elevated": true, "expires_at": "..." }.Endpoint Summary
| Method | Path | Purpose |
|---|---|---|
| POST | /api/auth/step-up/challenge | Request a step-up challenge |
| POST | /api/auth/step-up/verify | Submit challenge response |
| GET | /api/auth/step-up/status | Check elevation status |
Endpoints Requiring Step-Up
Deleting an org, rotating root signing keys, bulk session revocation, issuing SVIDs, KMS key rotation.
SDK Examples
Python
~~~python
Complete step-up flow
resp = client.auth_step_up("totp-code")client.api_key is auto-replaced with the elevated token
~~~Node.js / TypeScript
~~~typescript // Complete step-up flow const resp = await client.authStepUp('totp-code'); // apiKey is auto-replaced with the elevated token ~~~
Go
~~~go // Complete step-up flow resp, err := client.AuthStepUp(ctx, "totp-code", false) // client.APIKey is auto-replaced with the elevated token ~~~
Rust
~~~rust // Complete step-up flow let resp = client.auth_step_up(&serde_json::json!({ "code": "totp-code", "method": "totp" })).await?; // Use the elevated token for subsequent requests ~~~
Error Reference
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_code | TOTP code incorrect |
| 400 | expired_challenge | Challenge TTL elapsed |
| 403 | step_up_required | Endpoint requires step-up but token is not elevated |
| 410 | challenge_gone | Challenge already consumed |
| 429 | too_many_attempts | Locked 5 min after 5 failures |