MFA
TOTP enrollment, verification, login challenge, and recovery codes. Wraps /api/v1/auth/mfa/*.
The Python SDK ships a stdlib-only compute_totp(secret) helper so you can drive enroll → verify end-to-end without pyotp. The TypeScript SDK ships the equivalent computeTotp(secret).
Setup
The MFA client expects an authenticated session. Build it on top of an already-logged-in AuthClient.
Enroll
Returns a fresh secret plus an otpauth:// provisioning URI (also exposed as qr_uri).
Show the QR code to the user via the qr_uri. Call verify with the first valid code to confirm enrollment.
Verify (confirm enrollment)
Recovery codes are shown exactly once. Persist them on the user's side immediately.
Challenge (on login)
When login returns {"mfaRequired": true}, the session is partial. Submit a TOTP code to upgrade.
Disable
Wraps DELETE /api/v1/auth/mfa (the SDK adapts the unusual verb-with-body shape).
Regenerate recovery codes
Wraps GET /recovery-codes (yes, GET — the SDK matches the backend's chosen verb).
TOTP helper
RFC 6238, HMAC-SHA1, 30-second step. The TS implementation falls back to Node crypto.createHmac when crypto.subtle does not expose SHA-1 (some browsers).
Admin: reset MFA for a locked-out user
If a user loses their authenticator, an admin can clear their MFA without requiring the current code:
Limitations (pre-launch)
acr/amrclaim emission absent from token-exchange path. Real MFA step-up enforcement on agent tokens is not yet wired (backend gap).sessions.mfa_atfreshness column missing —mfa_passedis a sticky bool only.- Per-vault
requires_mfaflag absent — no per-action step-up gating yet.
These are server-side gaps documented in sdk/HANDOFF.md. The SDK methods will start enforcing step-up automatically once the server emits the claims.