Implement and review Passkeys / WebAuthn (W3C Web Authentication) registration and assertion flows: RP ID, origin, challenge binding, credential store, user verification, and safe fallbacks. Use when adding or hardening passwordless/passkey login, WebAuthn MFA step-up, or credential-management APIs for first-party web or hybrid clients.
Implement and review Passkeys / WebAuthn (W3C Web Authentication) registration and assertion flows: RP ID, origin, challenge binding, credential store, user verification, and safe fallbacks. Use when adding or hardening passwordless/passkey login, WebAuthn MFA step-up, or credential-management APIs for first-party web or hybrid clients.
Passkeys / WebAuthn Basics (Implementers)
Server- and client-side basics for WebAuthn Level 2+ and passkeys
(discoverable multi-device credentials). Focus: correct ceremony binding and
lifecycle—not CTAP firmware reverse engineering or unauthorized auth bypass.
When To Use
Building or reviewing passkey enroll, login, or step-up MFA.
Code or traffic shows navigator.credentials.create / get, PublicKeyCredential,
WebAuthn options, or libs (@simplewebauthn/*, fido2-lib, Duo WebAuthn).
Need a checklist for RP ID, origin, challenge TTL, counter, and UV policy.
Server verify: clientDataJSON (type=webauthn.create, challenge, origin);
rpIdHash; flags (AT; UV if required); extract COSE key; attestation only if policy needs it.
Persist credential bound to server user id—never trust client-chosen account id alone.
POST /webauthn/register/options → { challenge, rp, user, pubKeyCredParams, ... }
POST /webauthn/register/verify → { id, rawId, response.clientDataJSON, attestationObject }
3. Authentication (get)
Identify user (username, conditional UI, or session for step-up).
Mint challenge; non-discoverable: set allowCredentials for that user.
Server: lookup credential → user; verify type=webauthn.get, challenge, origin,
rpIdHash, UP/UV flags; signature over authData || hash(clientDataJSON);
if previous and new signCount are non-zero and new ≤ old → clone-risk policy
(reject, alert, and/or force step-up).
Elevate session / mint tokens only after verify; regenerate session id.
4. Hardening (common failures)
Pitfall
Secure behavior
Challenge multi-use
One-time; consume on success/fail
Origin/RP ID wrong env
Per-env allowlist; no wildcard origins
SPA “success” flag
Server crypto verify is authoritative
Cross-account bind
Global credential id uniqueness; enroll to current user only
Weak fallback
Password/OTP must not skip required assurance (mfa-bypass-methodology)
Post-assert tokens
Set amr/acr/session server-side (api-auth-and-jwt-abuse)