Skip to content

feat: add passkey signup and login with identifier verification - #174

Draft
rmad17 wants to merge 3 commits into
mainfrom
feat/passkey-identifier
Draft

rmad17 wants to merge 3 commits into
mainfrom
feat/passkey-identifier

Conversation

@rmad17

@rmad17 rmad17 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds passkey signup and login to AuthClient, including identifier verification at signup. When a database connection requires email or phone verification, the signup challenge returns verification_required and signin_with_passkey() accepts the codes the user received.

The new methods pass their arguments straight through to ServerClient in auth0-server-python, following the existing custom token exchange methods. The SDK does not mount passkey routes. Apps add their own routes, as shown in the new guide.

Changes

  • AuthClient (src/auth0_fastapi/auth/auth_client.py): three methods added at the end of the class. Each forwards every argument by keyword to ServerClient.
    • passkey_signup_challenge() accepts user_profile, connection, organization, user_metadata, delivery_method ("text" or "voice") and store_options. The response includes verification_required when the connection requires verification.
    • passkey_login_challenge() accepts connection, organization and store_options.
    • signin_with_passkey() exchanges the credential for tokens and establishes the session for both signup and login. It accepts optional verification codes, connection, organization, scope, audience, dpop_key and store_options.
  • Errors (src/auth0_fastapi/errors/__init__.py): re-exports PasskeyError and PasskeyErrorCode. auth0_exception_handler maps a PasskeyError with code too_many_requests to HTTP 429. Other PasskeyErrors keep the default 400. The response body still carries only error and message, so auth_session never appears in a generic error response.
  • Docs:
    • New examples/Passkeys.md covers:
      • signup and login
      • identifier verification: collecting codes before creating the credential, the retry loop, retryable vs terminal errors, and resending codes
      • security considerations and error-to-status mapping
    • README.md gains a Passkeys feature bullet and a Passkeys section that links to the guide.

Testing

  • test_auth_client.py: new TestPasskey class with 11 tests. They cover:
    • argument forwarding and defaults for all three methods, including a login credential
    • dpop_key passed through as the same object
    • retryable and terminal PasskeyError propagation, with auth_session and verification_required intact
    • rate-limit propagation from both challenges
    • InvalidArgumentError for an unknown verification key
  • test_errors.py (new, 3 tests): 429 mapping, the error body leaves out auth_session, an to 400.

Tested flows

# Flow Scenario
1 Happy path Passkey signup (register) and passkey login, each
2 Organization Passkey signup and login with organization set
3 Global MFA Passkey sign-in with tenant-wide MFA required
4 Step-up MFA Passkey sign-in followed by an MFA challenge for elevated access
5 DPoP Passkey sign-in with dpop_key, issuing DPoP-bound tokens

rmad17 and others added 3 commits October 12, 2026 22:58
Cover signin_with_passkey with a login assertion credential and
rate-limit error propagation from passkey_login_challenge.

Co-Authored-By: Claude <noreply@anthropic.com>
…anges

auth0-server-python removed PasskeyErrorCode.TOO_MANY_REQUESTS and now
reports rate limits through PasskeyError.status_code and retry_after. The
exception handler read the removed attribute, so every PasskeyError raised
AttributeError instead of rendering. It now maps status_code 429 to HTTP
429 and forwards retry_after as Retry-After.

The passkey wrappers forward the new client_ip argument and match the
upstream verification type. The passkey guide covers client_ip trust,
rate limit retries, verification requirements and account existence.

Co-Authored-By: Claude <noreply@anthropic.com>

This branch has not been deployed

No deployments
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