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.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
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)