Skip to content

WebAuthn Registration

WebAuthn Registration (the navigator.credentials.create ceremony) is the strategic process of establishing a new trust relationship between a user’s hardware and your application. During this ceremony, the Authenticator generates a unique, non-exportable Public/Private key pair. The Private Key is securely locked within the device’s hardware (TPM or Secure Enclave), while the Public Key is sent to the server to act as the user’s permanent “Digital Signature” for future logins. This process ensures that the “Truth” of the user’s identity is decentralized, residing only on the device they physically control.

REGISTER

Key Generation
Core Mission
Identity Decentralization. Establishing a permanent, cryptographically verified link between an application account and a specific physical security element.
Like Setting Up a Safety Deposit Box: To start the relationship (Registration), you go to the bank (The App) and they give you a box (The Account). The bank provides a lock (The Challenge). You generate two keys: One you give to the bank (The Public Key) which allows them to recognize your box, and one you keep for yourself (The Private Key). Crucially, the bank never sees your key. To access the box later, you must bring your key to prove you are the owner who set up the box.
Passwordless Enrollment / Biometric Setup / Security Key Onboarding

The level of assurance depends on the “Attestation” requested by the server during the enrollment ceremony.

LevelMechanismStrategic GoalSecurity Profile
NoneDefault behavior.Maximum User Privacy.High (Keys are still secure).
DirectIdP receives hardware metadata.Hardware Verification.Required for Compliance.
IndirectAnonymized hardware info.Privacy-Preserving Trust.Medium.
SelfSimple signature check.Basic Key Integrity.Basic.

Registration involves a carefully orchestrated balance between the Server (RP), the Browser (UA), and the Security Hardware.

sequenceDiagram
    participant User
    participant Browser
    participant Hardware as Authenticator
    participant Server as Relying Party
    
    Server->>Browser: Send CreationOptions (Challenge, UserID)
    Browser->>Hardware: invoke create()
    Hardware->>User: "Enroll Fingerprint?"
    User-->>Hardware: User Consents
    Hardware->>Hardware: Generate ECC Keypair
    Hardware-->>Browser: Signed Attestation Object
    Browser->>Server: Deliver Public Key + CredentialID
    Server->>Server: Store Public Key against Account
1

Define Options

The server generates a `PublicKeyCredentialCreationOptions` object. This includes the `challenge`, the user's ID, and the `residentKey` requirement—specifying if the credential should be "discoverable" without a username during login.

2

Invoke & Consent

The browser calls `navigator.credentials.create()`. The user's device prompts for local authorization (FaceID/TouchID). Once approved, the hardware generates the keys and signs the challenge with its internal "Attestation Key."

3

Verify & Persist

The server receives the `AttestationObject`. It verifies the signature, confirms the challenge was correct, and extracts the `PublicKey`. This key is stored in the database, finalizing the cryptographic bond.


Implementing registration requires handling binary data (ArrayBuffers) between the client and server.

// Triggering WebAuthn Credential Creation
const credential = await navigator.credentials.create({
publicKey: {
challenge: Uint8Array.from(challengeFromServer, c => c.charCodeAt(0)),
rp: { name: "My Secure App", id: "app.example.com" },
user: {
id: Uint8Array.from("user_123", c => c.charCodeAt(0)),
name: "jane.doe@example.com",
displayName: "Jane Doe"
},
pubKeyCredParams: [{ alg: -7, type: "public-key" }], // ES256
authenticatorSelection: { userVerification: "required" }
}
});

Master the technical ceremonies of the passwordless enrollment lifecycle.