Skip to content

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 productionSecurityError; HTTPS is mandatory. localhost exception is development-only
  • Inconsistent RP ID → Define rpId as 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