enroll()
Creates a new biometric credential and enrolls the user. Attempts PRF (Pseudo-Random Function) enrollment first, with automatic fallback to rawId-HKDF (V1) if the platform authenticator doesn’t support PRF.Parameters
Unique identifier for the user.
- With
serverUrl: Required. Used to associate the credential with a user account on your backend. - Without
serverUrl: Optional. If omitted, a random 16-byte identifier is generated.
Returns
The enrolled identity object containing:
Hex-encoded 256-bit public key derived from the biometric credential.
Hex-encoded credential ID (rawId) from WebAuthn.
16-character device fingerprint derived from browser/system characteristics.
Unix timestamp (milliseconds) when enrollment occurred.
Enrollment method used:
'prf': Modern PRF extension (preferred)'rawid': Legacy rawId-HKDF fallback
Example
Behavior
- Generates a random 32-byte challenge
- Creates a WebAuthn credential using the platform authenticator
- Attempts to use PRF extension for key derivation
- Falls back to rawId-HKDF if PRF is not supported
- Stores identity in
localStorage - If
serverUrlis configured anduserIdprovided, registers the credential with the backend
Error Conditions
- User cancels biometric prompt
- No platform authenticator available
- WebAuthn not supported in browser
- Network error during server registration (enrollment still succeeds locally)
authenticate()
Authenticates the user with their previously enrolled biometric credential. Re-derives the cryptographic key and validates it matches the stored public key.Parameters
User identifier for server-backed authentication.
- With
serverUrl: Required. Used to fetch a challenge from the server and verify the authentication result. - Without
serverUrl: Optional. Authentication is performed client-side only.
Returns
Example
Behavior
- Retrieves stored identity from
localStorage - Fetches challenge from server (if
serverUrlconfigured) or generates one locally - Requests WebAuthn assertion using the stored credential ID
- Re-derives the public key using PRF or rawId-HKDF (based on enrollment method)
- Validates derived key matches the stored public key
- Performs server-side verification if
serverUrlis configured
Error Conditions
Thrown when
getIdentity() returns null. User must enroll first.Thrown when re-derived PRF key doesn’t match stored public key.
Thrown when re-derived rawId-HKDF key doesn’t match stored public key.
Thrown when backend server rejects the authentication attempt.
Thrown when server-side public key doesn’t match expected key.
getIdentity()
Retrieves the currently stored identity fromlocalStorage.
Returns
Returns the stored identity object or
null if no enrollment exists.See the Identity type for object structure.Example
Use Cases
- Check if user has enrolled before prompting authentication
- Display enrollment status in UI
- Access stored credential information
- Validate enrollment state before operations
clearIdentity()
Removes the stored identity fromlocalStorage. Does not revoke the WebAuthn credential itself.
Returns
This method does not return a value.
Example
Notes
- This method only removes the local storage entry
- The underlying WebAuthn credential remains registered with the platform authenticator
- User can re-enroll to create a new credential
- Does not communicate with the server or revoke server-side registrations
_serverVerify()
Internal method for server-side authentication verification. Not intended for direct use.Parameters
User identifier to verify.
Original challenge buffer used for authentication.
Hex-encoded public key that should match server records.
Returns
Resolves if verification succeeds, throws if it fails.
Behavior
- Converts challenge buffer to hex string
- Sends POST request to
{serverUrl}/verifywithuserIdandchallenge - Validates response indicates
verified: true - Confirms server’s
publicKeymatchesexpectedKey
Error Conditions
- Network request fails
- Server returns
verified: false - Public key mismatch between client and server
Note
This method is called automatically byauthenticate() when serverUrl is configured. You should not need to call it directly.