Outcome
Claim one actor/target-bound setup token and conditionally enable only disabled MFA; later storage failure may consume the token.
These examples prove local handler behavior with real isolated JWT/TOTP/envelope/SQL and explicitly synthetic identity/key dependencies.
Before you start
-
Verify pinned identity and exact target authority. Cookie identity precedes Bearer identity; self sub/userId or exact management authority is required. An authenticated denial is not proof of expired OAuth.
-
Use a deliberate private human enrollment/recovery journey. CLI/stdio MCP protects setup secret/token and embedded QR URI, and SDK 0.23.2 protects each backup-code array item separately through a configured protected store. Do not extract protected material, log live codes, use fixture values on real accounts or claim agent credential delivery is proven.
-
Review exact plans/effects before approval. Stored MFA flags, authenticator enrollment, backup-code delivery/use, session state and notifications are separate outcomes. Tokens are actor/target bound and can be consumed before storage fails; already-enabled state and conditional SQL prevent overwriting active MFA.
Discover the target
topolo whoami --json
topolo apps --json
topolo actions get app_topolo_auth.user_mfa.verify --detail --json
Resolve the actual authenticated self or authorized managed user and read user_security.get for that exact target. Never retrieve a secret/hash for discovery. Supply current TOTP through the intended private authenticator interface, and pass protected setup-token references unchanged.
Input fields
| Field | Required | Meaning |
|---|---|---|
userId | Yes | Existing Auth user from credential-scoped discovery. Self identity may use sub or userId; another target requires exact management authority over its organization. Cookie identity precedes Bearer identity for these handlers. A valid administrator credential cannot manage a foreign target. |
token | Yes | Current six-digit TOTP supplied privately by the intended authenticator user. It must match the pending setup secret within the supported current/adjacent 30-second windows. Never copy a fixture code, generate a real code from an extracted secret, log it or retain it as recovery material. |
setupToken | Yes | Unexpired setup token returned by user_mfa.setup for exactly this user and the same initiating actor. Pass a protected CLI/stdio MCP reference unchanged; do not decode or extract its secret/backup codes. Its jti can be claimed once and a storage failure after claim still consumes it. Releasing a local reference does not revoke an unconsumed server token. |
Effects
-
Claims setup token once before the protected core write; later failure can leave the token consumed.
-
Enables only a disabled MFA configuration with conditional SQL and hash-only backup codes; does not overwrite a competing active configuration.
Interpret the response
Requires valid setup signature/expiry/type, matching target, exact initiating actor, jti and correct TOTP. An already-enabled target is refused before claim. Correct verification claims jti in session SQL before enabling protected MFA and hash-only backup codes.
The conditional core SQL transition requires mfa_enabled = 0, so a competing enable cannot replace the winning secret/code set. The losing token may already be claimed. If protected storage fails after claim, MFA can remain disabled while the token is consumed; read current status and begin fresh setup rather than retrying the same token.
The successful data identifies userId and mfaEnabled true, without secrets. Require userId to match the reviewed target and verify it through user_security.get, then separately complete a normal intended sign-in challenge. Lifecycle notification and audit are nonfatal; acknowledgment is not delivered notification or actual sign-in proof.
Worked examples
These are complete raw target-handler responses from isolated fixtures, not live or CLI/gateway envelopes. All identifiers, seeds, backup codes and signing keys are synthetic; captured tokens have only a local fixture signature and a fixed already-past lifetime. Never use them for live enrollment. CLI/MCP payloads show the declared request shape and require discovery, private recipient interaction and a reviewed approved plan. SDK 0.23.2 protects each backup-code array item separately through a configured protected store; hosts without one redact sensitive items. Local published-SDK tests do not prove live CLI/MCP or private recipient delivery. A protected setup-token reference must be passed unchanged; no secret extraction or QR reconstruction is authorized by this guide.
Correct TOTP claims one setup token and stores protected MFA plus hash-only backup codes
Input · payload.json:
{
"userId": "usr_self",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9zZWxmIiwiYWN0b3IiOiJ1c3Jfc2VsZiIsInNlY3JldCI6IkpCU1dZM0RQRUhQSzNQWFBKQlNXWTNEUEVIUEszUFhQIiwiYmFja3VwQ29kZXMiOlsiMDAwMDAwMGEiLCIwMDAwMDAwYiIsIjAwMDAwMDBjIiwiMDAwMDAwMGQiLCIwMDAwMDAwZSIsIjAwMDAwMDBmIiwiMDAwMDAwMTAiLCIwMDAwMDAxMSIsIjAwMDAwMDEyIiwiMDAwMDAwMTMiXSwiaWF0IjoxNzkwODk5MjAwLCJleHAiOjE3OTA5MDAxMDAsInR5cGUiOiJtZmFfc2V0dXAiLCJqdGkiOiJiOTNmNDNkYi01ZDFjLTRjODktYjA1NS1hNGQ4MDRkZmIyYjAifQ.4QO9W68TJGEPL7WahVV-Cm1-6hkTN7AdSU0m3XrP9OI"
}
CLI:
topolo actions validate app_topolo_auth.user_mfa.verify --data @payload.json --json
topolo actions plan app_topolo_auth.user_mfa.verify --data @payload.json --confirm --json
topolo actions call app_topolo_auth.user_mfa.verify --data @payload.json --confirm --json
MCP call after validation and plan review:
{
"tool": "topolo_call_action",
"arguments": {
"actionId": "app_topolo_auth.user_mfa.verify",
"input": {
"userId": "usr_self",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9zZWxmIiwiYWN0b3IiOiJ1c3Jfc2VsZiIsInNlY3JldCI6IkpCU1dZM0RQRUhQSzNQWFBKQlNXWTNEUEVIUEszUFhQIiwiYmFja3VwQ29kZXMiOlsiMDAwMDAwMGEiLCIwMDAwMDAwYiIsIjAwMDAwMDBjIiwiMDAwMDAwMGQiLCIwMDAwMDAwZSIsIjAwMDAwMDBmIiwiMDAwMDAwMTAiLCIwMDAwMDAxMSIsIjAwMDAwMDEyIiwiMDAwMDAwMTMiXSwiaWF0IjoxNzkwODk5MjAwLCJleHAiOjE3OTA5MDAxMDAsInR5cGUiOiJtZmFfc2V0dXAiLCJqdGkiOiJiOTNmNDNkYi01ZDFjLTRjODktYjA1NS1hNGQ4MDRkZmIyYjAifQ.4QO9W68TJGEPL7WahVV-Cm1-6hkTN7AdSU0m3XrP9OI"
},
"confirm": true
}
}
Captured local handler response · HTTP 200:
{
"success": true,
"message": "MFA enabled successfully",
"data": {
"userId": "usr_self",
"mfaEnabled": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
Managing actor completes only its own managed-user setup token
Input · payload.json:
{
"userId": "usr_managed",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9tYW5hZ2VkIiwiYWN0b3IiOiJ1c3JfYWRtaW4iLCJzZWNyZXQiOiJKQlNXWTNEUEVIUEszUFhQSkJTV1kzRFBFSFBLM1BYUCIsImJhY2t1cENvZGVzIjpbIjAwMDAwMDBhIiwiMDAwMDAwMGIiLCIwMDAwMDAwYyIsIjAwMDAwMDBkIiwiMDAwMDAwMGUiLCIwMDAwMDAwZiIsIjAwMDAwMDEwIiwiMDAwMDAwMTEiLCIwMDAwMDAxMiIsIjAwMDAwMDEzIl0sImlhdCI6MTc5MDg5OTIwMCwiZXhwIjoxNzkwODk5MzIwLCJ0eXBlIjoibWZhX3NldHVwIiwianRpIjoiMmJiZmI5MzUtZWNlOS00NzM0LWFmZDUtZmRlYTljM2RmZmY1In0.WsxzlnY5hfgU4jdoUam5y9_gndYyK4LUKq8SfPybsW8"
}
CLI:
topolo actions validate app_topolo_auth.user_mfa.verify --data @payload.json --json
topolo actions plan app_topolo_auth.user_mfa.verify --data @payload.json --confirm --json
topolo actions call app_topolo_auth.user_mfa.verify --data @payload.json --confirm --json
MCP call after validation and plan review:
{
"tool": "topolo_call_action",
"arguments": {
"actionId": "app_topolo_auth.user_mfa.verify",
"input": {
"userId": "usr_managed",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9tYW5hZ2VkIiwiYWN0b3IiOiJ1c3JfYWRtaW4iLCJzZWNyZXQiOiJKQlNXWTNEUEVIUEszUFhQSkJTV1kzRFBFSFBLM1BYUCIsImJhY2t1cENvZGVzIjpbIjAwMDAwMDBhIiwiMDAwMDAwMGIiLCIwMDAwMDAwYyIsIjAwMDAwMDBkIiwiMDAwMDAwMGUiLCIwMDAwMDAwZiIsIjAwMDAwMDEwIiwiMDAwMDAwMTEiLCIwMDAwMDAxMiIsIjAwMDAwMDEzIl0sImlhdCI6MTc5MDg5OTIwMCwiZXhwIjoxNzkwODk5MzIwLCJ0eXBlIjoibWZhX3NldHVwIiwianRpIjoiMmJiZmI5MzUtZWNlOS00NzM0LWFmZDUtZmRlYTljM2RmZmY1In0.WsxzlnY5hfgU4jdoUam5y9_gndYyK4LUKq8SfPybsW8"
},
"confirm": true
}
}
Captured local handler response · HTTP 200:
{
"success": true,
"message": "MFA enabled successfully",
"data": {
"userId": "usr_managed",
"mfaEnabled": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
Verify the result
-
Keep the exact userId from the reviewed input/plan and read user_security.get for that same authorized user. Compare mfa_enabled and has_backup_codes; never retrieve or log secret/hash material.
-
Stored status is separate from private authenticator enrollment, normal MFA/backup-code sign-in, physical device entries, session invalidation and notification delivery. Verify the intended human journey independently; synthetic local cryptographic fixtures prove none of these live outcomes.
Errors and recovery
Anonymous MFA operation is refused
Captured local refusal · HTTP 401:
{
"input": {
"userId": "usr_self",
"token": "000000",
"setupToken": "unusable-fixture-setup"
},
"response": {
"success": false,
"error": {
"message": "Access token required",
"code": "AUTH_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Ordinary user cannot manage another MFA target
Captured local refusal · HTTP 401:
{
"input": {
"userId": "usr_managed",
"token": "000000",
"setupToken": "unusable-fixture-setup"
},
"response": {
"success": false,
"error": {
"message": "Access denied: You can only verify MFA for yourself",
"code": "AUTH_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Organization administrator cannot manage a foreign target
Captured local refusal · HTTP 401:
{
"input": {
"userId": "usr_foreign",
"token": "000000",
"setupToken": "unusable-fixture-setup"
},
"response": {
"success": false,
"error": {
"message": "Access denied: You can only verify MFA for yourself",
"code": "AUTH_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Missing target user is not provisioned
Captured local refusal · HTTP 404:
{
"input": {
"userId": "usr_missing",
"token": "000000",
"setupToken": "unusable-fixture-setup"
},
"response": {
"success": false,
"error": {
"message": "User not found",
"code": "NOT_FOUND",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Unknown setup signature is refused without claiming a token
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_self",
"token": "845544",
"setupToken": "unusable-fixture-setup"
},
"response": {
"success": false,
"error": {
"message": "Invalid or expired setup token",
"code": "VALIDATION_ERROR",
"details": {
"setupToken": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Incorrect TOTP preserves setup-token usability
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_self",
"token": "000000",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9zZWxmIiwiYWN0b3IiOiJ1c3Jfc2VsZiIsInNlY3JldCI6IkpCU1dZM0RQRUhQSzNQWFBKQlNXWTNEUEVIUEszUFhQIiwiYmFja3VwQ29kZXMiOlsiMDAwMDAwMGEiLCIwMDAwMDAwYiIsIjAwMDAwMDBjIiwiMDAwMDAwMGQiLCIwMDAwMDAwZSIsIjAwMDAwMDBmIiwiMDAwMDAwMTAiLCIwMDAwMDAxMSIsIjAwMDAwMDEyIiwiMDAwMDAwMTMiXSwiaWF0IjoxNzkwODk5MjAwLCJleHAiOjE3OTA5MDAxMDAsInR5cGUiOiJtZmFfc2V0dXAiLCJqdGkiOiJiOTNmNDNkYi01ZDFjLTRjODktYjA1NS1hNGQ4MDRkZmIyYjAifQ.4QO9W68TJGEPL7WahVV-Cm1-6hkTN7AdSU0m3XrP9OI"
},
"response": {
"success": false,
"error": {
"message": "Invalid verification code",
"code": "VALIDATION_ERROR",
"details": {
"token": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Setup token cannot transfer from self actor to managing administrator
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_self",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9zZWxmIiwiYWN0b3IiOiJ1c3Jfc2VsZiIsInNlY3JldCI6IkpCU1dZM0RQRUhQSzNQWFBKQlNXWTNEUEVIUEszUFhQIiwiYmFja3VwQ29kZXMiOlsiMDAwMDAwMGEiLCIwMDAwMDAwYiIsIjAwMDAwMDBjIiwiMDAwMDAwMGQiLCIwMDAwMDAwZSIsIjAwMDAwMDBmIiwiMDAwMDAwMTAiLCIwMDAwMDAxMSIsIjAwMDAwMDEyIiwiMDAwMDAwMTMiXSwiaWF0IjoxNzkwODk5MjAwLCJleHAiOjE3OTA5MDAxMDAsInR5cGUiOiJtZmFfc2V0dXAiLCJqdGkiOiJiOTNmNDNkYi01ZDFjLTRjODktYjA1NS1hNGQ4MDRkZmIyYjAifQ.4QO9W68TJGEPL7WahVV-Cm1-6hkTN7AdSU0m3XrP9OI"
},
"response": {
"success": false,
"error": {
"message": "Setup token does not match caller",
"code": "VALIDATION_ERROR",
"details": {
"setupToken": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Consumed setup token is refused even when its signature and TOTP remain valid
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_self",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9zZWxmIiwiYWN0b3IiOiJ1c3Jfc2VsZiIsInNlY3JldCI6IkpCU1dZM0RQRUhQSzNQWFBKQlNXWTNEUEVIUEszUFhQIiwiYmFja3VwQ29kZXMiOlsiMDAwMDAwMGEiLCIwMDAwMDAwYiIsIjAwMDAwMDBjIiwiMDAwMDAwMGQiLCIwMDAwMDAwZSIsIjAwMDAwMDBmIiwiMDAwMDAwMTAiLCIwMDAwMDAxMSIsIjAwMDAwMDEyIiwiMDAwMDAwMTMiXSwiaWF0IjoxNzkwODk5MjAwLCJleHAiOjE3OTA5MDAxMDAsInR5cGUiOiJtZmFfc2V0dXAiLCJqdGkiOiJiOTNmNDNkYi01ZDFjLTRjODktYjA1NS1hNGQ4MDRkZmIyYjAifQ.4QO9W68TJGEPL7WahVV-Cm1-6hkTN7AdSU0m3XrP9OI"
},
"response": {
"success": false,
"error": {
"message": "MFA is already enabled for this user",
"code": "VALIDATION_ERROR",
"details": {
"mfa": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Another pending token is refused after MFA is enabled and cannot restore old backup codes
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_self",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9zZWxmIiwiYWN0b3IiOiJ1c3Jfc2VsZiIsInNlY3JldCI6IkpCU1dZM0RQRUhQSzNQWFBKQlNXWTNEUEVIUEszUFhQIiwiYmFja3VwQ29kZXMiOlsiMDAwMDAwMGEiLCIwMDAwMDAwYiIsIjAwMDAwMDBjIiwiMDAwMDAwMGQiLCIwMDAwMDAwZSIsIjAwMDAwMDBmIiwiMDAwMDAwMTAiLCIwMDAwMDAxMSIsIjAwMDAwMDEyIiwiMDAwMDAwMTMiXSwiaWF0IjoxNzkwODk5MjAwLCJleHAiOjE3OTA5MDAxMDAsInR5cGUiOiJtZmFfc2V0dXAiLCJqdGkiOiI3MmExMTJjNi03ZDExLTQ2NmEtYjc5Yy1mN2YxNDBmYTFiMzMifQ.EMKQj-qVo5fSkBm6QNu4VbMlx_e-A8Uv6SS-42t-y_I"
},
"response": {
"success": false,
"error": {
"message": "MFA is already enabled for this user",
"code": "VALIDATION_ERROR",
"details": {
"mfa": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Failure after token claim leaves MFA disabled but the setup token consumed
Captured local refusal · HTTP 500:
{
"input": {
"userId": "usr_partial",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9wYXJ0aWFsIiwiYWN0b3IiOiJ1c3JfYWRtaW4iLCJzZWNyZXQiOiJKQlNXWTNEUEVIUEszUFhQSkJTV1kzRFBFSFBLM1BYUCIsImJhY2t1cENvZGVzIjpbIjAwMDAwMTM2IiwiMDAwMDAxMzciLCIwMDAwMDEzOCIsIjAwMDAwMTM5IiwiMDAwMDAxM2EiLCIwMDAwMDEzYiIsIjAwMDAwMTNjIiwiMDAwMDAxM2QiLCIwMDAwMDEzZSIsIjAwMDAwMTNmIl0sImlhdCI6MTc5MDg5OTIwMCwiZXhwIjoxNzkwOTAwMTAwLCJ0eXBlIjoibWZhX3NldHVwIiwianRpIjoiOGVjOTVjMGQtNzE0Ni00NTE2LTk5MDctMDY0NWY2M2NjM2ZlIn0.2s4H7XhRxz5pRVlpkNlSK_6K27SQkOqXB-u_8Dp0qDc"
},
"response": {
"success": false,
"error": {
"message": "Unable to verify MFA setup. Please try again.",
"code": "SERVER_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Retrying the consumed token after failed storage is refused; begin fresh setup
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_partial",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9wYXJ0aWFsIiwiYWN0b3IiOiJ1c3JfYWRtaW4iLCJzZWNyZXQiOiJKQlNXWTNEUEVIUEszUFhQSkJTV1kzRFBFSFBLM1BYUCIsImJhY2t1cENvZGVzIjpbIjAwMDAwMTM2IiwiMDAwMDAxMzciLCIwMDAwMDEzOCIsIjAwMDAwMTM5IiwiMDAwMDAxM2EiLCIwMDAwMDEzYiIsIjAwMDAwMTNjIiwiMDAwMDAxM2QiLCIwMDAwMDEzZSIsIjAwMDAwMTNmIl0sImlhdCI6MTc5MDg5OTIwMCwiZXhwIjoxNzkwOTAwMTAwLCJ0eXBlIjoibWZhX3NldHVwIiwianRpIjoiOGVjOTVjMGQtNzE0Ni00NTE2LTk5MDctMDY0NWY2M2NjM2ZlIn0.2s4H7XhRxz5pRVlpkNlSK_6K27SQkOqXB-u_8Dp0qDc"
},
"response": {
"success": false,
"error": {
"message": "Setup token has already been used",
"code": "VALIDATION_ERROR",
"details": {
"setupToken": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Claim-store failure happens before enabling MFA
Captured local refusal · HTTP 500:
{
"input": {
"userId": "usr_claim_error",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9jbGFpbV9lcnJvciIsImFjdG9yIjoidXNyX2FkbWluIiwic2VjcmV0IjoiSkJTV1kzRFBFSFBLM1BYUEpCU1dZM0RQRUhQSzNQWFAiLCJiYWNrdXBDb2RlcyI6WyIwMDAwMDEzNiIsIjAwMDAwMTM3IiwiMDAwMDAxMzgiLCIwMDAwMDEzOSIsIjAwMDAwMTNhIiwiMDAwMDAxM2IiLCIwMDAwMDEzYyIsIjAwMDAwMTNkIiwiMDAwMDAxM2UiLCIwMDAwMDEzZiJdLCJpYXQiOjE3OTA4OTkyMDAsImV4cCI6MTc5MDkwMDEwMCwidHlwZSI6Im1mYV9zZXR1cCIsImp0aSI6ImU0ZDdmYzhiLTg1YzMtNDI5MS1hYWRkLWE3OTAwNGM5OWJkZiJ9.VBy3fE_RTkwG5hDCTd8m4F2ZWNNs88smumYJMusyXdQ"
},
"response": {
"success": false,
"error": {
"message": "Failed to claim setup token",
"code": "SERVER_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Conditional SQL refuses a competing MFA enable after claim and preserves the winning backup-code set
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_claim_error",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9jbGFpbV9lcnJvciIsImFjdG9yIjoidXNyX2FkbWluIiwic2VjcmV0IjoiSkJTV1kzRFBFSFBLM1BYUEpCU1dZM0RQRUhQSzNQWFAiLCJiYWNrdXBDb2RlcyI6WyIwMDAwMDEzNiIsIjAwMDAwMTM3IiwiMDAwMDAxMzgiLCIwMDAwMDEzOSIsIjAwMDAwMTNhIiwiMDAwMDAxM2IiLCIwMDAwMDEzYyIsIjAwMDAwMTNkIiwiMDAwMDAxM2UiLCIwMDAwMDEzZiJdLCJpYXQiOjE3OTA4OTkyMDAsImV4cCI6MTc5MDkwMDEwMCwidHlwZSI6Im1mYV9zZXR1cCIsImp0aSI6ImI5YmUxYjZkLWNmZTktNDc2My1iZmFiLWJlOTVmMWUwMzkzNSJ9.3v1M-oxM9WLC1VRejIRqI07wf6oAiEBIf5K5UBcgKxE"
},
"response": {
"success": false,
"error": {
"message": "MFA is already enabled for this user",
"code": "VALIDATION_ERROR",
"details": {
"mfa": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Expired setup token is refused
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_self",
"token": "845544",
"setupToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ0b3BvbG8tYXV0aCIsImF1ZCI6InRvcG9sby1zZXJ2aWNlcyIsInN1YiI6InVzcl9zZWxmIiwiYWN0b3IiOiJ1c3Jfc2VsZiIsInNlY3JldCI6IkpCU1dZM0RQRUhQSzNQWFBKQlNXWTNEUEVIUEszUFhQIiwiYmFja3VwQ29kZXMiOlsiMDAwMDAwMGEiLCIwMDAwMDAwYiIsIjAwMDAwMDBjIiwiMDAwMDAwMGQiLCIwMDAwMDAwZSIsIjAwMDAwMDBmIiwiMDAwMDAwMTAiLCIwMDAwMDAxMSIsIjAwMDAwMDEyIiwiMDAwMDAwMTMiXSwiaWF0IjoxNzkwODk5MjAwLCJleHAiOjE3OTA4OTkyMDEsInR5cGUiOiJtZmFfc2V0dXAiLCJqdGkiOiJleHBpcmVkLWZpeHR1cmUtY2xhaW0ifQ.rBr9PZ0fer4CvnjvZ_htg0J3LKnGfislmXZj7I_UASI"
},
"response": {
"success": false,
"error": {
"message": "Invalid or expired setup token",
"code": "VALIDATION_ERROR",
"details": {
"setupToken": true
},
"timestamp": "2026-10-02T00:00:02.000Z"
}
}
}
Published recovery guidance
-
state_conflict(HTTP 409): Read the current resource state, reconcile the intended change, and retry only if still valid. -
AUTH_ERROR(HTTP 401): Verify pinned identity and cookie/Bearer consistency. Respect target organization authority; an authenticated refusal is not proof of expired OAuth. -
NOT_FOUND(HTTP 404): Resolve an existing authorized user through published discovery; these actions do not provision users. -
VALIDATION_ERROR(HTTP 400): Read current target security state. Do not reuse a consumed/expired token, transfer it to another actor, overwrite enabled MFA or infer a backup-code set from status. When disabled after a consumed setup attempt, separately approve a fresh setup; code regeneration requires enabled MFA. -
SERVER_ERROR(HTTP 500): Preserve the sanitized result/request id and read exact-target state before retry. A verify failure may follow token claim; a successful acknowledgment identifies its user but cannot prove live sign-in or delivery. Do not extract secrets or guess a repair endpoint.
Recovery boundaries
After any unknown outcome read exact-target status. An already-enabled result is not permission to disable it; inspect the intended human journey. If disabled after token claim/storage failure, separately approve fresh setup. Consumed claims are not restored, and secret/backup codes must not be retained as rollback material.
Discovery and evidence
This record belongs to app_topolo_auth. Local captures use real controller authority, JWT signature/expiry, TOTP, envelope encryption, hash-only backup-code storage and canonical core/session SQL with simulated access-token identity, fixed synthetic credential generation and isolated keys. Lifecycle notification is unconfigured. No live user, authenticator, MFA configuration, code delivery or OAuth state was changed. Stored local state and cryptographic behavior do not prove protected gateway handoff, sign-in, recipient delivery or production completion.