Skip to content

WebAuthn Authentication

WebAuthn Authentication (the navigator.credentials.get ceremony) is the high-assurance process of proving a user’s identity without a password. Unlike traditional logins that rely on shared knowledge (which can be stolen or guessed), WebAuthn relies on asymmetric cryptography. The server issues a random challenge, and the user’s hardware (The Authenticator) signs that challenge using the private key generated during registration. This creates a “Cryptographic Assertion” that proves the user is physically present, in possession of the authorized device, and has successfully passed a local biometric or PIN check.

AUTHENTICATE

Assertion Check
Core Mission
Universal Assertion. Establishing a point-in-time proof of identity that is mathematically bound to the original registration and the current domain origin.
Like a Sovereign Signature Check: When you sign a check (The Authentication Request), the bank doesn't ask you for a secret password you told them years ago. They compare the signature on the check (The Cryptographic Assertion) with the official signature card they have on file (The Public Key). If the signatures match, they know it's you. The hardware authenticator is your "Permanent Pen" that only you can use to produce that specific, verifiable mark.
Single-Tap Login / Step-up Authentication / High-Assurance MFA

The level of user friction and security assurance is defined by the userVerification requirement in the authentication options.

RequirementUser ExperienceStrategic ValueSecurity Level
RequiredMust use Biometric/PIN.Proves user identity + presence.Highest.
PreferredBiometric if available.Balances security & UX flow.High.
DiscouragedSimple button tap.Proves presence only.Medium.

The authentication ceremony ensures that the server can verify the user’s assertion without the private key ever being transmitted.

sequenceDiagram
    participant User
    participant Browser
    participant Hardware as Authenticator
    participant Server as Relying Party
    
    Server->>Browser: Send GetOptions (Challenge, AllowList)
    Browser->>Hardware: invoke get()
    Hardware->>User: "Log in to App?"
    User-->>Hardware: User Verifies (FaceID/PIN)
    Hardware->>Hardware: Sign Challenge with Private Key
    Hardware-->>Browser: Signed Assertion
    Browser->>Server: Deliver Signature + ClientData
    Server->>Server: Verify Signature with Public Key
1

Issue Challenge

The server generates a `PublicKeyCredentialRequestOptions` object. This includes a fresh `challenge` to prevent replay attacks and an `allowCredentials` list containing the IDs of authenticators previously registered by the user.

2

Locate & Sign

The browser calls `navigator.credentials.get()`. The user's device identifies the correct private key, prompts the user for local verification, and signs a hash of the challenge and the domain origin (`clientDataJSON`).

3

Validate & Grant

The server receives the signature and the `authenticatorData`. It retrieves the user's public key from the database and performs a cryptographic verification. If the signature is valid and the origin matches, the user is authenticated.


Managing assertions requires handling the conversion between binary data and JSON.

Authentication Ceremony (JavaScript Example)

Section titled “Authentication Ceremony (JavaScript Example)”
// Triggering WebAuthn Authentication
const assertion = await navigator.credentials.get({
publicKey: {
challenge: Uint8Array.from(serverChallenge, c => c.charCodeAt(0)),
allowCredentials: [{
id: Uint8Array.from(credentialIdFromDb, c => c.charCodeAt(0)),
type: "public-key"
}],
userVerification: "required",
timeout: 60000
}
});

Master the technical ceremonies of the passwordless authentication lifecycle.