Step-up MFA for sensitive actions

Some write calls need you to have completed multi-factor authentication recently, not just at some point in this session. Holding a valid token is not enough: the API checks how fresh your MFA is and refuses the call if it is stale or absent. When that happens it returns HTTP 403 with error: step_up_required. You clear it by signing in again with MFA and retrying the call.

This applies to interactive callers — people signed in with the device-code or PKCE flow. Service accounts using the client-credentials grant are never asked to step up, because there is no person to complete an MFA challenge. See Service account and M2M authentication.

Which actions require step-up

Reads never require step-up. Among the write endpoints, these do today:

  • Create a machine-to-machine credentialPOST https://api.cybersentriq.com/iam/m2m-credentials
  • Revoke a machine-to-machine credentialDELETE https://api.cybersentriq.com/iam/m2m-credentials/{credentialId}
  • Rotate a credential secretPOST https://api.cybersentriq.com/iam/m2m-credentials/{credentialId}/rotate-secret

Each of these carries a Step-up MFA badge in the API reference. The API makes the decision at call time from your organization's policy, so treat any write as potentially step-up-gated: handle the 403 rather than hard-coding this list.

The claims that drive it

Two claims on your token describe the freshness check. You do not compute anything from them — the API does the check for you — but reading them lets you warn the user before you make the call:

  • https://cybersentriq.com/mfa_at — when you last completed MFA in this session.
  • https://cybersentriq.com/mfa_max_age — how long, in seconds, MFA stays fresh. It is an org-level policy: when it is 0 or absent, your organization has no step-up requirement, so it is not enforced.

How you detect it

When an action needs fresher MFA than your token carries, the API responds with HTTP 403 and a JSON body whose error is step_up_required:

JSON
{
  "error": "step_up_required",
  "error_description": "This action requires recent identity verification.",
  "max_age": 300
}

max_age is the freshness window, in seconds, that your next sign-in has to satisfy. Detect this case by the 403 status together with error === "step_up_required".

A 403 is not always step-up. The same status is returned when your token simply lacks the permission the call needs. Branch on the error field: step_up_required means re-authenticate; anything else means you are missing a permission, and re-authenticating will not help. Keep both distinct from a plain 401 (an expired or missing token), which you fix by refreshing, not by re-authenticating.

How you satisfy it

Sign in again with MFA, then retry the original call with the new token. There is nothing to send on the failed request: you obtain a fresher token and repeat the call.

That means re-running the device-code (or PKCE) sign-in you used the first time:

Shell
# 1. Re-authenticate: run the device-code or PKCE flow again,
#    completing the MFA challenge when prompted.
# 2. Store the new access token (it now carries a fresh mfa_at).
# 3. Retry the request that returned 403 — unchanged — against https://api.cybersentriq.com.

On success you now hold a token with a fresh mfa_at, and the action goes through. See User and device-code authentication for the sign-in flows.

Next