Docs · Security

Security model

Why passkeys stop phishing, what Gatekeep stores and how, and the protections around codes, sessions, refresh tokens and recovery.

Phishing resistance

A passkey is a key pair. The private key stays on the user’s device or in their synced keychain; Gatekeep keeps only the public key. Each passkey is bound to your Gatekeep domain. The browser won’t use it anywhere else, so a lookalike site can’t get a signature, however convincing it looks. There’s no password or one-time code for anyone to type into the wrong page.

What we store, and how

ThingStored as
PasskeyPublic key and a signature counter only
Sessions, authorization codes, refresh tokens, magic linksSHA-256 hashes
Signing keysEncrypted at rest with AES-GCM
Email addressPlain, so we can send links. Lowercased for matching

Because every bearer secret is stored hashed, a copy of the database contains nothing an attacker can use to sign in or call an API.

Protections, flow by flow

  • Authorization: the client ID and redirect URI are checked before anything else. A bad redirect URI gets an error page, never a redirect.
  • Code exchange: PKCE with S256 is required. Codes last 60 seconds and work once.
  • Passkey sign-in: every challenge is single-use and expires after 5 minutes. Authenticator sign counts must increase; a passkey whose count goes backwards looks cloned, and is revoked.
  • Refresh tokens: rotated on every use. Reusing an old one revokes the whole chain. See Refresh tokens.
  • Sessions: HttpOnly, Secure, SameSite=Lax cookies that last 30 days and slide forward while in use.
  • Recovery: completing it revokes every existing passkey on the account.
  • Account enumeration: signup and recovery give the same response whether or not an address has an account.

Token signing

Tokens are signed with Ed25519 (EdDSA). Keys rotate on a schedule. The old key stays in your JWKS for 35 days after it stops signing, so no valid token stops verifying mid-rotation.

Reporting a vulnerability

Found something? Contact us and choose Security report. Please give us a chance to fix it before you publish.