Lesson 17 / 25

Passkeys and WebAuthn

Public-key credentials bound to the site.

How WebAuthn works

WebAuthn (a W3C standard, used with FIDO2/CTAP authenticators) replaces shared secrets with public-key cryptography. At registration, the authenticator (platform authenticator such as a phone or laptop, or a hardware security key) creates a key pair scoped to your relying party ID (your domain); the server stores the public key and credential ID. At authentication, the server sends a random challenge; the authenticator signs it after user verification (biometric or PIN, checked locally), and the server verifies the signature with the stored public key. The browser includes the origin in what is signed, so a phishing domain cannot get a usable signature, and the server holds no secret worth stealing. Passkeys are discoverable WebAuthn credentials, often synced across a user's devices by the platform's credential manager.

Requesting a passkey sign-in in the browser

Options come from your server; verify the result server-side with a WebAuthn library.

// options fetched from POST /webauthn/login/options (server generated the challenge)
const options = await fetch('/webauthn/login/options', { method: 'POST' }).then((r) => r.json());

const credential = (await navigator.credentials.get({
  publicKey: {
    challenge: base64urlToBuffer(options.challenge), // random, single use, short-lived
    rpId: 'example.com',
    userVerification: 'preferred',
    timeout: 60000,
  },
})) as PublicKeyCredential;

// send to the server, which checks challenge, origin, rpId, signature and counter
await fetch('/webauthn/login/verify', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify(serializeCredential(credential)),
});

A signet ring that only fits one door

A passkey is like a personal seal that never leaves your hand. You press it onto a fresh challenge each time, and the impression is only accepted at the exact door it was made for, so a fake door gets nothing useful.

Quick check: Why are passkeys resistant to phishing?

  • The server stores the private key securely
  • The user types a longer code
  • Signatures are scoped to the relying party and origin, so a look-alike site cannot use them
  • They are sent by SMS
Answer

Signatures are scoped to the relying party and origin, so a look-alike site cannot use them — The private key stays on the authenticator and is bound to your domain.