Phone MFA - Reset Password Flow

Hello,

According to the auth0 documentation, you cannot use phone as an MFA factor in the reset password flow:
Factor Allowed values: otp, email, webauthn-platform, webauthn-roaming, recovery-code
I was just wondering why this was. I was also wondering what we should do about a user who only has phone enrolled. The forgot password flow prompts an email OTP and then we wanted to do a second MFA factor in the reset password / post Challenge action. I don’t want to prompt email twice.

Edit - I was also wondering what the purpose of reset-password-mfa-sms-challenge/phone/voice was.

You are asking why phone is not supported as an MFA factor in the Auth0 reset password flow, and what to do about users who only have phone enrolled. You also want to understand the purpose of reset-password-mfa-sms-challenge and related phone/voice factors.

Phone (SMS and voice) is not supported in the reset password flow because the reset password flow is designed to be accessible without requiring a user to have pre-enrolled MFA factors. The reset password flow uses email as the primary verification method to ensure users can always reset their password even if they lose access to their phone. The supported factors in the reset password flow are: otp, email, webauthn-platform, webauthn-roaming, and recovery-code. For users who only have phone enrolled, you must use email as the first factor in the reset password flow, then optionally challenge with a second factor after they verify their email.

[Root Cause]

The reset password flow has different constraints than the login flow:

  1. Email is the primary verification method β€” The reset password flow uses email to verify the user's identity because email is the most reliable way to reach users who may have lost access to their phone or other devices. This ensures users can always reset their password.
  2. Phone is not available in reset password flow β€” SMS and voice factors are not supported because:
    • Users may not have access to their phone (lost, stolen, changed number)
    • The reset password flow is designed to be accessible without pre-enrolled MFA factors
    • Email is the fallback verification method that works for all users
  3. Supported factors are limited β€” Only factors that don't require pre-enrollment or external devices are supported:
    • email β€” Uses verified email address
    • otp β€” Uses authenticator app (user has device)
    • webauthn-platform β€” Uses platform authenticator (biometric/PIN)
    • webauthn-roaming β€” Uses security key
    • recovery-code β€” Uses recovery codes generated during MFA enrollment
  4. Email factor behavior β€” Email is not a standalone MFA factor. Users must have a primary factor (SMS, OTP, WebAuthn, etc.) enrolled first. Email can only be used as a secondary option after a primary factor is set.

Solution: Handle Users with Only Phone Enrolled

Option 1: Challenge with Email in Reset Password Flow (Recommended)

For users who only have phone enrolled, use the reset password flow with email as the second factor:

Step 1: Email Verification

The reset password flow automatically sends an email verification link. User clicks the link and is redirected to the password reset page.

Step 2: Optional Second Factor Challenge

In the Post-Password-Reset Action, you can optionally challenge with a second factor. However, since phone is not supported, you have these options:

1. Challenge with email OTP β€” If the user has a verified email (which they do, since they clicked the email link):

exports.onExecutePostPasswordReset = async (event, api) => {
  // Challenge with email OTP as second factor
  api.authentication.challengeWith({
    type: 'email'
  });
};

2. Challenge with OTP β€” If the user has an authenticator app enrolled:

exports.onExecutePostPasswordReset = async (event, api) => {
  // Challenge with OTP if available
  if (event.user.multifactor && event.user.multifactor.includes('google-authenticator')) {
    api.authentication.challengeWith({
      type: 'otp'
    });
  }
};

3. Challenge with recovery code β€” If the user has recovery codes:

exports.onExecutePostPasswordReset = async (event, api) => {
  // Challenge with recovery code if available
  api.authentication.challengeWith({
    type: 'recovery-code'
  });
};

Option 2: Encourage Users to Enroll Additional Factors

Since phone-only users cannot use phone in the reset password flow, encourage them to enroll a secondary factor:

  1. During MFA enrollment β€” Suggest users enroll both phone and an authenticator app
  2. In user settings β€” Provide a UI to add backup factors like OTP or WebAuthn
  3. Recovery codes β€” Ensure users save their recovery codes as a backup

Option 3: Custom Reset Password Flow

If you need to support phone verification in the reset password flow, you can build a custom reset password experience:

  1. Use the Management API β€” Call the Management API to verify the user's identity
  2. Send SMS OTP β€” Send an OTP to the user's phone
  3. Verify OTP β€” Verify the OTP before allowing password reset
  4. Update password β€” Call the Management API to update the password

However, this requires building custom UI and is not part of Auth0's standard reset password flow.

About reset-password-mfa-sms-challenge and Phone/Voice Factors:

The reset-password-mfa-sms-challenge, reset-password-mfa-phone, and reset-password-mfa-voice factors you mentioned are not documented in the current Auth0 documentation. These may be:

  1. Legacy factors β€” From older versions of Auth0 that are no longer supported
  2. Undocumented features β€” Internal factors that are not officially supported
  3. Deprecated β€” Removed in favor of the current factor list

The current official supported factors in the reset password flow are:

  • otp β€” Authenticator app
  • email β€” Email OTP
  • webauthn-platform β€” Platform authenticator (biometric/PIN)
  • webauthn-roaming β€” Security key
  • recovery-code β€” Recovery codes

Best Practice for Reset Password with MFA:

  1. Use email as the primary verification β€” All users have verified email after clicking the reset link
  2. Challenge with a secondary factor β€” Optionally challenge with OTP, WebAuthn, or recovery code
  3. Avoid phone in reset password β€” Phone is not supported and users may not have access to it
  4. Encourage factor diversity β€” Recommend users enroll multiple factors (phone + OTP + WebAuthn)
  5. Provide recovery codes β€” Ensure users have recovery codes as a backup

Example: Reset Password Flow with Email + OTP

exports.onExecutePostPasswordReset = async (event, api) => {
  // User has already verified email by clicking the link
  // Now challenge with OTP if available
  
  if (event.user.multifactor && event.user.multifactor.length > 0) {
    // User has MFA enrolled, challenge with OTP
    api.authentication.challengeWith({
      type: 'otp'
    });
  } else {
    // User has no MFA enrolled, allow password reset
    // No additional challenge needed
  }
};

Phone is not supported in the reset password flow because email is the reliable fallback verification method. For users with only phone enrolled, use email OTP or encourage them to enroll additional factors like OTP or WebAuthn.

Kind Regards,
Nik