Changelog
Examples

Enable and disable two-factor authentication

Turn authenticator 2FA on or off with CSRF and ReAuth.

Manage authenticator 2FA for a signed-in user. Paths are under /identity/manage/2fa. POST requires authorization, CSRF (RequestVerificationToken), and ReAuth. Body shape is Identity TwoFactorRequest.

Assume cookie session (credentials: "include") and a fresh CSRF token from GET /identity/csrfToken.

Read status

  1. Sign in.
  2. GET /identity/manage/2fa.
  3. Response includes isTwoFactorEnabled.

Enable

  1. Complete step-up: Complete step-up (ReAuth) (password, 2FA, or passkey proof).
  2. Mint or refresh the authenticator shared key with POST /identity/manage/2fa and body {} (plus CSRF). When no key exists, the response includes sharedKey.
  3. Show the shared key (or QR) in the authenticator app.
  4. Complete ReAuth again if the ReAuth cookie expired (5 minutes).
  5. POST /identity/manage/2fa with { "enable": true, "twoFactorCode": "<6-digit TOTP>" } and CSRF.
  6. On 200, store recoveryCodes from the response when present. isTwoFactorEnabled is true.

Do not send enable: true together with resetSharedKey: true. That combination returns a validation problem.

Disable

  1. Complete ReAuth.
  2. POST /identity/manage/2fa with { "enable": false } and CSRF.
  3. On 200, isTwoFactorEnabled is false.

To rotate the authenticator key, set resetSharedKey: true (this also disables 2FA until you enable again with a code from the new key).

Optional flags on POST

FieldEffect
resetRecoveryCodesIssues a new set of recovery codes
forgetMachineClears the two-factor remember-client cookie

Sign in after 2FA is enabled

Password cookie login: POST /identity/login with email, password, and either twoFactorCode or twoFactorRecoveryCode when Identity requires 2FA. Login does not require CSRF. See Cookie auth.