Skip to content

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

Draft
subhankarmaiti wants to merge 7 commits intomainfrom
feat/mfa-api
Draft

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

Conversation

@subhankarmaiti
Copy link
Contributor

Adds full MFA API support to auth0-server-python, enabling developers to integrate multi-factor authentication flows into their applications.

New Features

MfaClient — accessible via server_client.mfa

  • list_authenticators(options) — List enrolled authenticators for a user (OTP, OOB/SMS, OOB/Email).
  • enroll_authenticator(options) — Enroll a new authenticator (OTP, SMS, or Email).
  • delete_authenticator(options) — Remove an enrolled authenticator.
  • challenge_authenticator(options) — Trigger an MFA challenge (e.g., send an SMS code).
  • verify(options) — Verify an MFA challenge using OTP, OOB, or a recovery code.
  • encrypt_mfa_token(...) / decrypt_mfa_token(...) — Securely encrypt/decrypt the mfa_token for safe round-tripping through the client (JWE with TTL expiry).

Automatic mfa_required Detection

  • get_access_token() and get_token_by_refresh_token() now detect mfa_required responses from Auth0 and raise MfaRequiredError with an encrypted mfa_token, enabling seamless step-up authentication flows.

Usage Example

from auth0_server_python import ServerClient

client = ServerClient(domain="...", client_id="...", client_secret="...", secret="...")

# MFA is triggered automatically during token retrieval
try:
    token = await client.get_access_token()
except MfaRequiredError as e:
    # e.mfa_token is encrypted and safe to pass to the frontend
    mfa_token = e.mfa_token

# Challenge + verify flow
challenge = await client.mfa.challenge_authenticator({
    "mfa_token": raw_token,
    "challenge_type": "oob",
    "authenticator_id": "auth|123"
})

result = await client.mfa.verify({
    "mfa_token": raw_token,
    "oob_code": challenge.oob_code,
    "binding_code": user_input
})
# result.access_token is now available

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.

1 participant