Overview
Passkey MFA lets you require users to verify their identity with a passkey after their primary login factor completes — whether that’s email OTP or OAuth. The passkey acts as a second factor using the device’s biometric sensor (fingerprint, Face ID) or PIN, providing phishing-resistant security on top of the primary authentication method. When a user has both TOTP MFA and passkey MFA enabled, they can choose which method to use at login time. Recovery codes are issued at enrollment so users can regain access if they lose their device.Compatibility
Passkey MFA is supported for the
loginWithEmailOTP and OAuth flows. It
requires the Passkey extension
and is available on the Web SDK only.Setup
1. Enable in the dashboard
Enable Passkey MFA in your Magic dashboard before calling any MFA methods. Users will not be able to enroll until this setting is turned on.2. Register a passkey
The user must have at least one passkey registered before they can enable passkey MFA. UseregisterNewUser for new users or addPasskey for existing logged-in users.
3. Enable passkey MFA
CallenablePasskeyMfa() while the user has an active session. On success, Magic returns a set of one-time recovery codes — display these to the user immediately, as they cannot be retrieved again.
JavaScript
TypeScript
Login with passkey MFA
Magic-hosted UI (default)
No additional code is required. Magic automatically presents the passkey verification step after the primary factor completes — whether that’s email OTP or an OAuth redirect.Custom UI
When you control the UI, passshowUI: false (email OTP) or showMfaModal: false (OAuth) to handle the MFA step yourself. The MFA events are the same for both flows.
Email OTP
Add MFA events to your existing email OTP event handler:JavaScript
OAuth
PassshowMfaModal: false to getRedirectResult and attach the same MFA events:
JavaScript
| Event | Direction | Description |
|---|---|---|
MfaEventOnReceived.SelectMfaType | Received | Emitted when the user has both TOTP and passkey MFA — they must choose one |
MfaEventEmit.SelectedMfaType | Emit | Send "passkey" or "totp" to select the MFA method |
MfaEventOnReceived.MfaSentHandle | Received | Passkey challenge is active — browser shows the WebAuthn prompt automatically |
MfaEventEmit.LostDevice | Emit | Signal that the user cannot use their passkey — initiates recovery code flow |
Disable passkey MFA
CalldisablePasskeyMfa() while the user has an active session.
JavaScript
Account recovery
When a user cannot access their passkey, they can use a recovery code to complete login. Recovery codes are single-use and are issued when the user first callsenablePasskeyMfa(). Make sure your UI prompts users to save them at enrollment time.
After a recovery code is used, the user’s passkey MFA is deactivated. They can re-enroll by calling enablePasskeyMfa() again.
If a user loses both their passkey and their recovery codes, you can disable MFA on their behalf from the Users section of the Magic dashboard.