Skip to main content
The twoFactor() plugin adds TOTP (time-based one-time password) support compatible with Google Authenticator, Authy, 1Password, and any RFC 6238 app. Users enroll once by scanning a QR code, then provide a 6-digit code on every sign-in.

Setup

1

Install

2

Add the plugin

lib/kavach.ts
twoFactor() works with any primary auth method. Pair it with OAuth providers or magic link as well as email/password.

Enrollment flow

All enrollment endpoints require an active session.
1

Generate a TOTP secret

POST /auth/2fa/enroll
Render qrCodeUrl as a QR code image in your UI. The user scans it with their authenticator app. Show backupCodes once at this point, they cannot be retrieved again.
2

Confirm with the first code

Ask the user to enter the code their authenticator app shows to confirm enrollment:POST /auth/2fa/verify
A successful response activates 2FA on the account.

Login verification

When a user with 2FA enabled signs in, the primary auth endpoint returns a partial response instead of a session:
Submit the TOTP code along with the challenge token to complete sign-in: POST /auth/2fa/verify
On success, a session cookie is set.

Backup codes

Ten single-use backup codes are generated at enrollment. Each is a 10-character alphanumeric string. A backup code can be submitted in place of a TOTP code at the verify endpoint, useful when the user has lost access to their authenticator app.

Regenerate backup codes

POST /auth/2fa/backup-codes This invalidates all existing backup codes and issues a new set. Requires an active session.

Disabling 2FA

POST /auth/2fa/disable Requires the user’s current TOTP code as confirmation:

Check enrollment status

GET /auth/2fa/status

Endpoints

All endpoints require an authenticated session unless noted.

Options

Last modified on April 29, 2026