Passkeys: Practical Lessons

Hands‑on learnings from building passkeybot: how authenticators, attestation, JS integrity and emerging APIs shape security, privacy and UX for passkey deployments.

Passkeys: Practical Lessons
Passkeys: Practical Lessons
Passkeys simplify sign‑in — but hardware, attestation and your JS are where real risks and choices live. I built passkeybot and pulled together the practical tradeoffs you must know.

Hands‑on learnings from building passkeybot: how authenticators, attestation, JS integrity and emerging APIs shape security, privacy and UX for passkey deployments.

Source: enzo.dev

Highlights

Metric Value Notes
Secure Enclave (SEP) Apple devices use a Secure Enclave processor that stores secrets which never leave the enclave and signs data on request.
User Presence vs User Verification Presence = a tap (can be faked by anyone with an unlocked device); Verification = biometric or passcode re‑auth required by the authenticator.
Hardware attestation Attestation proves the hardware that created a key and runs only at key creation; Apple disables attestation by default unless enterprise device management is enabled.
Immediate mediation API navigator.credentials.get({mediation: "immediate"}) lets JS get an immediate result about local passkeys (0, 1, or >1) and decide next steps.
Related Origin Requests (ROR) Domains can declare other domains allowed to create passkeys via /.well-known/webauthn; RORs require HTTPS and are not supported on iOS 18 or Firefox.
PublicKeyCredential Signal API Signal methods include signalUnknownCredential, signalAllAcceptedCredentials and signalCurrentUserDetails for asynchronous hints about passkey state.

Key points

  • Authenticators (SEP, YubiKey, etc.) hold key pairs and the browser normalizes diverse authenticator APIs behind the JS passkey API.
  • Passkeys sign a challenge unique to each auth flow — they are for authentication, not arbitrary transaction signing.
  • If site JS is compromised an attacker can trick a user into signing forged challenges; Subresource Integrity and current mitigations have limitations.
  • Hardware attestation enables device allow‑lists but leaks device fingerprinting and only applies at key creation, complicating synced keys.
  • The authenticator usage counter is a heuristic for clones and often ignored due to legitimate counter drift scenarios.
  • You can use BLE to sign in on a public device by using your nearby device as the authenticator; private keys never leave the device.
  • PKCE prevents token theft by tying token redemption to a per‑flow secret; crypto.subtle.generateKey can create non‑extractable keys similar to passkeys.

Why this matters

Passkeys materially improve authentication UX and security, but deployment choices—attestation, JS integrity, enterprise controls and protocol design (PKCE, signals, immediate mediation)—determine privacy, resiliency and manageability. Teams must balance stronger device guarantees against fingerprinting and support flows for synced devices, compromised JS risks, and evolving browser APIs.