# Step-Up Options

Start a step-up for one action on one target: the options one of your passkeys answers.

## Overview

- `action` and its target ([The Step-Up](https://docs.aureahub.com/docs/guide-passkeys.md)): `approval.approve` or `approval.reject` with `operationId` — an approver of your tenant (`owner`, `tenantadmin`, `non_signing_admin`, `approver`), bound to the operation's newest approval request and its payload for that decision —; `policy_set.publish` or `policy_set.rollback` with `setId` — `owner`, `tenantadmin`, `non_signing_admin`, `security_admin`, on your tenant's set —; `passkey.register` with nothing, or `passkey.revoke` with `passkeyId` — your own; `bank_ramp.payout` or `bank_ramp.destination_change` with nothing — your own money out of the bank ramp, its token sent in the `x-aurea-step-up` header ([Passkeys & Step-Up](https://docs.aureahub.com/docs/guide-passkeys.md) › Where It Is Asked).
- `rpId`: your tenant's own passkey address [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md), for a step-up in your own app ([Your Own Passkey Address](https://docs.aureahub.com/docs/guide-passkeys.md)); absent, Aurea's own relying party, as before. Any other: `400` `PASSKEY_RP_NOT_ALLOWED`.
- `200` with `publicKey` — the options for `navigator.credentials.get()` in WebAuthn's JSON form (`PublicKeyCredential.parseRequestOptionsFromJSON()`, or decode `challenge` and each `allowCredentials[].id` from base64url): your active passkeys of that relying party, user verification `required`, and a challenge that commits to the action, your tenant, the target and a random value —, `ceremonyId`, `action` and `expiresAt`: used once, within 5 minutes. `Cache-Control: no-store`.
- Then [Step-Up](https://docs.aureahub.com/docs/step-up.md) with the passkey's answer.
- `400` `STEP_UP_ACTION_INVALID` when the action's target is missing (`This action needs operationId (a UUID)`); `403` `STEP_UP_ACTION_FORBIDDEN` for a role that does not take the action, with `details.action`; `404` `STEP_UP_TARGET_NOT_FOUND` for an operation with no approval request in your tenant; `503` `PASSKEYS_NOT_CONFIGURED`; `409` `STEP_UP_NO_PASSKEY` without an active passkey of that relying party. 20 requests per minute per client IP.

## Endpoint

### `POST /v1/auth/step-up/options`

Authentication: bearer token required.

Starts a step-up for one action on one target: the WebAuthn request options and the ceremony's id.

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `action` | string | yes | `approval.approve`, `approval.reject`, `policy_set.publish`, `policy_set.rollback`, `passkey.register`, `passkey.revoke`, `bank_ramp.payout` or `bank_ramp.destination_change` |
| `operationId` | string (uuid) | no | For `approval.approve` and `approval.reject`: the operation held for approval |
| `setId` | string (uuid) | no | For `policy_set.publish`: the set; for `policy_set.rollback`: the archived version |
| `passkeyId` | string (uuid) | no | For `passkey.revoke`: the passkey revoked |
| `rpId` | string | no | Your tenant's passkey address, for a step-up in your own app; absent, Aurea's own |

**Responses**

`200` OK

```json
{
  "ceremonyId": "5e9a2c71-3b8d-4f06-a4e2-7d1c9b0f3a58",
  "action": "approval.approve",
  "expiresAt": "2026-10-14T09:25:00.000Z",
  "publicKey": {
    "rpId": "…",
    "challenge": "-5LR9MtkIpGMrKdJwNwCf7R8JvV3a3JVP243INWKB90",
    "allowCredentials": [
      { "id": "AkuuQ3HZmehDc7su8X9U7g6kRKc", "transports": ["hybrid", "internal"], "type": "public-key" }
    ],
    "timeout": 300000,
    "userVerification": "required"
  }
}
```

`403` Not your action

```json
{
  "statusCode": 403,
  "error": "ForbiddenError",
  "message": "You may not approval approve here",
  "details": { "code": "STEP_UP_ACTION_FORBIDDEN", "action": "approval.approve" }
}
```

`404` No request

```json
{
  "statusCode": 404,
  "error": "NotFoundError",
  "message": "No approval request for this operation here",
  "details": { "code": "STEP_UP_TARGET_NOT_FOUND" }
}
```

`409` No passkey

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "You have no passkey to confirm with: register one first",
  "details": { "code": "STEP_UP_NO_PASSKEY" }
}
```

**Example request**

```bash
curl -X POST https://api.aureahub.com/v1/auth/step-up/options \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "action": "approval.approve", "operationId": "1d7a3c52-8e4b-4f19-a0c6-2b9e7d5f3a18" }'
```

---

Web version: https://docs.aureahub.com/#step-up-options
