Skip to content

feat: add passkeys support for signup and signin#1530

Open
subhankarmaiti wants to merge 10 commits into
masterfrom
feat/passkeys-support
Open

feat: add passkeys support for signup and signin#1530
subhankarmaiti wants to merge 10 commits into
masterfrom
feat/passkeys-support

Conversation

@subhankarmaiti
Copy link
Copy Markdown
Contributor

@subhankarmaiti subhankarmaiti commented May 11, 2026

Summary

Adds passkey authentication support, enabling passwordless biometric login via platform passkeys (Face ID, Touch ID, fingerprint). This PR provides the Auth0 challenge and token exchange methods, plus a complete example app native module demonstrating the full passkey flow end-to-end.

Methods Added

Method Description
passkeySignupChallenge Get a WebAuthn registration challenge from Auth0
passkeyLoginChallenge Get a WebAuthn assertion challenge from Auth0
passkeyExchange Exchange a passkey credential response for Auth0 tokens

Error Handling

Adds PasskeyError (extends AuthError) with PasskeyErrorCodes:

PASSKEY_CHALLENGE_FAILED, PASSKEY_EXCHANGE_FAILED, PASSKEY_USER_CANCELLED, PASSKEY_NOT_AVAILABLE, PASSKEY_UNSUPPORTED_PLATFORM

Example App — Native Passkey Module

The example app includes a native credential manager module (PasskeyModule) that wraps platform APIs to demonstrate the complete flow:

Platform Implementation
iOS AuthenticationServicesASAuthorizationPlatformPublicKeyCredentialProvider (requires iOS 16.6+)
Android androidx.credentials.CredentialManagerCreatePublicKeyCredentialRequest / GetPublicKeyCredentialOption (requires API 28+)

The module exposes two methods to JavaScript:

  • createPasskey(requestJson) — creates a new passkey (registration)
  • getPasskey(requestJson) — asserts an existing passkey (authentication)

Usage

import Auth0, { PasskeyError, PasskeyErrorCodes } from 'react-native-auth0';

const auth0 = new Auth0({ domain: 'YOUR_DOMAIN', clientId: 'YOUR_CLIENT_ID' });

// Step 1: Get challenge
const challenge = await auth0.passkeySignupChallenge({
  email: 'user@example.com',
  realm: 'Username-Password-Authentication',
});

// Step 2: Use platform credential manager (your own native module or library)
// challenge.authParamsPublicKey has the WebAuthn creation/request options
const credentialJson = await yourCredentialManager(challenge.authParamsPublicKey);

// Step 3: Exchange for Auth0 tokens
const credentials = await auth0.passkeyExchange({
  authSession: challenge.authSession,
  authResponse: credentialJson,
  realm: 'Username-Password-Authentication',
});

With Hooks

const { passkeySignupChallenge, passkeyLoginChallenge, passkeyExchange } = useAuth0();

Example App (Full Flow)

The example app demonstrates the complete flow using its built-in native module:

import { createPasskey, getPasskey } from '../passkey/PasskeyModule';

// Signup
const challenge = await passkeySignupChallenge({ email, realm });
const credentialJson = await createPasskey(challenge.authParamsPublicKey);
const credentials = await passkeyExchange({ authSession: challenge.authSession, authResponse: credentialJson, realm });

// Login
const challenge = await passkeyLoginChallenge({ realm });
const credentialJson = await getPasskey(challenge.authParamsPublicKey);
const credentials = await passkeyExchange({ authSession: challenge.authSession, authResponse: credentialJson, realm });

Platform Requirements

Platform Requirements
iOS iOS 16.6+, Associated Domains with webcredentials
Android API 28+, Digital Asset Links configured
Web Not supported (throws PasskeyError with UNSUPPORTED_PLATFORM)

Test Plan

  • npx tsc --noEmit passes
  • All 481 tests pass
  • Android build succeeds
  • iOS build succeeds
  • End-to-end passkey signup on iOS device
  • End-to-end passkey signup on Android device

@subhankarmaiti subhankarmaiti requested a review from a team as a code owner May 11, 2026 14:10
})
}

private fun performPasskeyRegistration(
Copy link
Copy Markdown
Contributor

@pmathew92 pmathew92 May 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want the SDK to handle this operation. SDK should expose the two APIs responsible for

  1. Requesting the Challenge
  2. Exchanging the token.
    and let the user handle the end to end flow. All our docs and tutorials follow the same pattern. Both the native SDKs also follow this approach . Curious to know why you went to implement this end to end flow ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated as per the native implementation

Comment thread android/build.gradle
implementation "androidx.browser:browser:1.2.0"
implementation 'com.auth0.android:auth0:3.15.0'
implementation 'com.auth0.android:auth0:3.17.0'
implementation "androidx.credentials:credentials:1.5.0"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove androidx.credentials since we are not doing the complete end to end flow

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.

2 participants