WebAuthn and Passkeys

Web Authentication (WebAuthn) and Passkeys

WebAuthn (Baseline Widely available) replaces passwords with key pairs. An authenticator (phone, password manager or security key) keeps the private key and signs server challenges after a biometric or PIN check. The signed data includes the origin, so a phishing domain's signatures fail. A passkey is a discoverable credential synced by iCloud Keychain, Google Password Manager or another manager.

Passkey registration and sign-in: only public keys and signatures reach the server
Passkey registration and sign-in: only public keys and signatures reach the server
Registering a passkey, then offering it in username autofillJavaScript
const getJSON = async (url) => (await fetch(url)).json();
const post = (url, data) => fetch(url, { method: 'POST', body: JSON.stringify(data) });  // toJSON()
const created = await navigator.credentials.create({  // run from a "Create passkey" click
  publicKey: PublicKeyCredential.parseCreationOptionsFromJSON(await getJSON('/passkey/new')) });
await post('/passkey/new', created);
// Sign-in page: <input name="username" autocomplete="username webauthn">
if ((await PublicKeyCredential.getClientCapabilities()).conditionalGet) {
  const assertion = await navigator.credentials.get({ mediation: 'conditional',
    publicKey: PublicKeyCredential.parseRequestOptionsFromJSON(await getJSON('/passkey/login')) });
  await post('/passkey/login', assertion);
}

Let SimpleWebAuthn 2,358 (https://github.com/MasterKale/SimpleWebAuthn 2,358 ) (MIT, npm 2,036 install @simplewebauthn/server) build options (residentKey: 'required' makes a passkey) and verify responses. A person must approve each ceremony, so this cannot run headless. Autofill sign-in works in Chrome 108 1 +, Safari 16.1 10 + and Firefox 122 555 + on desktop (passkeys.dev (https://passkeys.dev/device-support/)). When you delete a credential, PublicKeyCredential.signalUnknownCredential() (Chrome 132, Safari 26) tells password managers.