Skip to content

feat: Add MFA (Multi-Factor Authentication) API support#79

Open
subhankarmaiti wants to merge 14 commits intomainfrom
feat/mfa-api
Open

feat: Add MFA (Multi-Factor Authentication) API support#79
subhankarmaiti wants to merge 14 commits intomainfrom
feat/mfa-api

Conversation

@subhankarmaiti
Copy link
Copy Markdown
Contributor

@subhankarmaiti subhankarmaiti commented Feb 16, 2026

Adds MFA support to the auth0-server-python SDK via a new MfaClient (server_client.mfa) that handles the full MFA lifecycle — enrollment, challenge, and verification — for all supported factor types: OTP, SMS, Voice, Email, Push Notification (Auth0 Guardian), and Recovery Code.

What's Included

  • MfaClient with 4 methods: list_authenticators, enroll_authenticator, challenge_authenticator, verify
  • Session persistenceverify(persist=True) auto-updates the session store with new tokens
  • MFA token encryption — secure handling of mfa_token between requests
  • Push notification support — enrollment via Guardian QR code, challenge/verify via polling
  • Recovery code handlingverify() returns recovery_code on first enrollment and after recovery code use
  • New types: AuthenticatorResponse, ChallengeResponse, OtpEnrollmentResponse, OobEnrollmentResponse, MfaVerifyResponse
  • New errors: MfaRequiredError, MfaChallengeError, MfaEnrollmentError, MfaVerifyError, MfaTokenExpiredError
  • Unit tests covering all MFA operations across all factor types
  • Comprehensive docs in examples/MFA.md

Quick Example

from auth0_server_python.error import MfaRequiredError

try:
    access_token = await server_client.get_access_token()
except MfaRequiredError as error:
    mfa_token = error.mfa_token

    authenticators = await server_client.mfa.list_authenticators({"mfa_token": mfa_token})

    if not authenticators:
        enrollment = await server_client.mfa.enroll_authenticator({
            "mfa_token": mfa_token, "factor_type": "otp"
        })
    else:
        auth = authenticators[0]
        factor_type = auth.oob_channel if auth.authenticator_type == "oob" else auth.authenticator_type
        challenge = await server_client.mfa.challenge_authenticator({
            "mfa_token": mfa_token, "factor_type": factor_type, "authenticator_id": auth.id
        })

    verify_response = await server_client.mfa.verify({
        "mfa_token": mfa_token, "otp": user_code, "persist": True,
        "audience": "https://api.example.com"
    })

    if verify_response.recovery_code:
        print(f"Save this recovery code: {verify_response.recovery_code}")

@gyaneshgouraw-okta
Copy link
Copy Markdown

gyaneshgouraw-okta commented Feb 18, 2026

@subhankarmaiti please also add a corresponding example.md file for the mfa api usage in this SDK as done for other features. You can checkout spa js/next SDK example if that helps defining the structure - https://github.com/auth0/auth0-spa-js/blob/main/EXAMPLES.md#multi-factor-authentication-mfa

@subhankarmaiti subhankarmaiti marked this pull request as ready for review March 16, 2026 20:28
@subhankarmaiti subhankarmaiti requested a review from a team as a code owner March 16, 2026 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants