Add TOTP, SMS, or passkey verification in one call

Protect the actions that you choose with TOTP, SMS, email, or passkey verification. Auth enrolls each user and generates the QR code and the backup codes that go with it.

Ask for a second factor at sign-in and before sensitive actions

A user can add an authenticator app, a phone number for SMS codes, an email address, or a phishing-resistant passkey as a second factor. On top of the check at sign-in, your code can ask Auth for a fresh verification before a password change, an admin action, or any other step that you mark as sensitive.

The second factors and recovery options in Auth

TOTP authenticator apps

Auth generates a QR code that Google Authenticator, Authy, or any other TOTP app can scan. When the user types the six-digit code from the app, Auth allows for a small difference between the clock on the phone and the clock on the server.

SMS verification

Auth texts a verification code, valid for the period that you configure, to the phone number on the account.

Email verification

Auth emails the user a verification code or a magic link. You can use that email as the only sign-in step in a passwordless flow.

Passkey authentication

Auth supports WebAuthn passkeys, which a user unlocks with a fingerprint, a face scan, or a hardware security key. The user's device keeps the private key while Auth stores only the public key, so a phishing page has no shared secret to capture.

Backup codes

Auth generates a set of one-time backup codes when a user turns on MFA. If the user loses the phone with the authenticator app on it, they can sign in with one of those codes.

On-demand verification

Your code can request a second-factor check at any point in your application, such as before a data export or a change of email address. The user answers the check with one of the methods on their account.

Recovery flows

When a user loses a device, an administrator can reset MFA on the account, after which the user can enroll a new factor.

Trusted devices

A user can mark a device as trusted and skip the second factor on it for a period that you configure. You can revoke that trust at any time, after which Auth asks for the second factor again at the next sign-in from that device.

30s
TOTP window

How long each authenticator code stays valid

TOTP to passkeys
MFA methods

TOTP, SMS, email, passkeys, backup codes

< 100ms
Verification time

Time that Auth takes to check a code

Build faster with solutions designed for real-world needs

Let a user forget every trusted device after they lose a phone

Auth skips the second factor when a user signs in from a trusted device, until the trust period of that device ends. The revokeAll method of the trusted devices API removes that trust from every device on an account in one call and returns the number of devices that it revokes as revoked_count.

Impact

The Harrowgate Clinics security page in the sample calls a server action, which passes the account ID that auth() returns to revokeAll. The page then displays revoked_count, which is the number of devices where Auth will ask for the second factor at the next sign-in.

Prompt for a coding agent: Add a button that makes every trusted device ask for the second factor again.

Conjoin IDE

Select a file to view its contents

Show users the passkeys on their account and when they last used each one

The list method of the passkeys API returns each passkey on an account with its credential ID, its status, the date that the user added it, and the time of its last use. A Server Component can call that method with the account ID from auth(), so your server renders the list into the HTML that it sends to the browser.

Impact

The Pinecrest Ledger page in the sample redirects a signed-out visitor to /sign-in. For a signed-in user, the page shows each passkey that list returns with the date that the user added it and the date of its last use, or the words not used yet when last_used_at is null. Each entry also shows its status, because Auth disables a passkey when a sign-in with it fails with a signature counter that is behind the stored count, which can mean that someone copied the passkey.

Prompt for a coding agent: Show users their passkeys, with the date they added each one and the date they last used it.

Conjoin IDE

Select a file to view its contents

Enroll a phone number for SMS codes through Conjoin Messaging

Auth sends SMS codes through Conjoin Messaging Verifications, which validates the phone number before enrollment and reports whether the carrier delivers each message. Auth also rate-limits code requests, which blocks bursts of abuse while still allowing a user who misses a code to ask for another.

Impact

Your code enrolls the number, asks Auth to text the activation code to it, and activates the number with the code that the user receives. Conjoin sends the texts over its own carrier connections, so your team signs no carrier contract.

Prompt for a coding agent: Let users add a phone number for SMS codes, and activate it with the code that they receive.

Conjoin IDE

Select a file to view its contents

Ask for an authenticator code before a user changes their password

The operation_id of a step-up check names one of Auth's own sensitive operations, such as auth.password.rotate. When the startPasswordChange action requests a challenge for that operation on the current session, Auth returns the challenge ID with the methods available for it. Once the user types a code from their authenticator app, changePassword sends that code to stepUps.verify and passes the step-up token from Auth to rotatePassword with the current password and the new one.

Impact

In the sample, startPasswordChange continues only when available_methods includes totp, since changePassword verifies authenticator codes alone. Auth checks the current password that changePassword sends, which Auth requires whenever step-up is off in the MFA settings of your app. Once the password changes, Auth signs the account out of every session except the one whose session_id the action passes.

Prompt for a coding agent: Ask for an authenticator code before a user can change their password.

Conjoin IDE

Select a file to view its contents

Ask for a second factor again before a wire transfer

Before a high-risk operation such as a billing update or a wire transfer, your server sends the TOTP code that the user enters to Auth, which checks it against the authenticator on their account. Your code continues with the operation only when Auth accepts the code.

Impact

In the sample, the Brackish Capital app asks Yuki Ozawa for a TOTP code before it sends their wire transfer and blocks the transfer with an error when Auth rejects the code. For everything else in the app, their normal session is enough, so they see the extra step only before the transfer.

Prompt for a coding agent: Ask for an authenticator code before each wire transfer, and block the transfer on a wrong code.

Conjoin IDE

Select a file to view its contents

Build your next app on Conjoin

Conjoin will open with a free Build tier, while the pricing page already lists the launch prices for Pro and Business. If you tell us what you're building, we'll talk you through early access.