Passkeys Prerequisites & Overview
When to Use
Read this section before writing any passkey code to verify your environment satisfies WebAuthn requirements, select the correct server-side verification library, and identify which implementation flow maps to each use case.
Signal API Browser Support
The WebAuthn Signal API (signalAllAcceptedCredentials, signalCurrentUserDetails, signalUnknownCredential) keeps password manager vaults synchronized with your server's credential state. It has limited availability — not supported in Firefox as of 2026. Always gate every call with feature detection:
if (PublicKeyCredential.signalUnknownCredential) {
await PublicKeyCredential.signalUnknownCredential({ rpId, credentialId });
}
Supported in: Chrome 132+, Edge 132+, Safari 26+ (Sep 2025). Not supported in Firefox. Treat the Signal API as progressive enhancement only.
Decision
| Requirement | Rule | Failure if violated |
|---|---|---|
| Secure Context | Production MUST run on https://. http://localhost is the only exception |
SecurityError on credentials.create() / credentials.get() |
| RP ID binding | rpId must equal the domain or a registrable suffix of the current origin |
SecurityError; credentials become permanently unresolvable |
| Discoverable credentials | Registration MUST set both residentKey: "required" and requireResidentKey: true |
Passkeys will not appear in autofill or username-less sign-in |
| Challenge entropy | Generate a cryptographically random challenge server-side per request | Replay attacks; signature verification must fail without verified challenge |
| Goal | Use |
|---|---|
| User explicitly creates a passkey (settings panel, post-signup) | passkey-registration |
| Silent passkey creation after password sign-in | passkey-conditional-create |
| Returning user authenticates (autofill or button) | passkey-authentication |
| User views, renames, or deletes their passkeys | passkey-management |
| Step-up re-verification before a sensitive action | passkey-reauthentication |
Pattern
import 'webauthn-polyfills';
// Gate all passkey UI on capability detection at page load
const caps = await PublicKeyCredential.getClientCapabilities();
if (!caps.passkeyPlatformAuthenticator || !caps.conditionalGet) {
showPasswordFallbackUI();
}
getClientCapabilities() — Baseline since 2025-02-06 (Chrome 133, Edge 133, Firefox 135, Safari 17.4). The polyfill handles older versions.
Server Library Matrix
| Language | Library |
|---|---|
| JavaScript / TypeScript | SimpleWebAuthn — github.com/MasterKale/SimpleWebAuthn |
| Python | py_webauthn — github.com/duo-labs/py_webauthn |
| Java | java-webauthn-server (Yubico) |
| .NET | fido2-net-lib |
| Go | go-webauthn |
| Ruby | webauthn-ruby |
| PHP | webauthn-framework — github.com/web-auth/webauthn-framework |
These libraries apply server-side only. On the client, always call native browser APIs directly.
Common Mistakes
http://in production →SecurityError; HTTPS is mandatory.localhostexception is development-only- Inconsistent RP ID → Define
rpIdas a single constant shared across endpoints; any mismatch orphans credentials permanently - Client-side WebAuthn wrapper libraries → Wrappers abstract away
mediation,AbortController, and error handling. Use native APIs; use the server library only server-side - Skipping
getClientCapabilities()before rendering passkey UI → Passkey buttons appear on browsers that cannot use them
See Also
- passkey-registration — credential creation ceremony
- passkey-authentication — sign-in flows
- authentication-best-practices — passwords, MFA, session management
- Reference: MDN Web Authentication API
- Reference: W3C WebAuthn Level 3 Spec
- Reference: webauthn-polyfills (npm)