All pages
Every documentation page and every section within it. 7 sections, 23 pages, 447 headings. Press ⌘K anywhere for the search dialog instead.
Getting started
- Introduction
What passkify does, what it deliberately does not do, and how the pieces fit.
- Failure throws, it does not return a flag
- Challenges are single use, enforced by the store contract
- Registration will not take over an existing username
- Login does not confirm whether an account exists
- The problem it solves
- What it looks like
- What it deliberately does not do
- Design decisions worth knowing up front
- Failure throws, it does not return a flag
- Challenges are single use, enforced by the store contract
- Registration will not take over an existing username
- Login does not confirm whether an account exists
- Where to go next
- Installation
Install the package, pick your entry points, and check runtime requirements.
- Quickstart
A working passwordless sign-up and sign-in, end to end, in about five minutes.
- How passkeys work
Relying Party ID, challenges, user handles, discoverable credentials.
- Examples
Complete runnable apps for Express and Next.js, with every file listed.
Server
- PasskeyServer
The one object you construct, and every method it exposes.
- new PasskeyServer(config)
- rpID
- store
- startRegistration
- finishRegistration
- startAuthentication
- finishAuthentication
- listCredentials
- renameCredential
- deleteCredential
- express
- handler
- Constructor
- new PasskeyServer(config)
- Properties
- rpID
- store
- The four ceremony methods
- startRegistration
- finishRegistration
- startAuthentication
- finishAuthentication
- Credential management
- listCredentials
- renameCredential
- deleteCredential
- HTTP adapters
- express
- handler
- Next
- Configuration
Every option on PasskeyServerConfig, what it changes, and when to move it.
- rpName
- origin
- store
- rpID
- userVerification
- residentKey
- authenticatorAttachment
- timeout
- challengeTimeout
- challengeSize
- supportedAlgorithms
- attestation
- attestationRootCertificates
- requireBackupEligible
- hooks
- hooks.onRegistered
- hooks.onAuthenticated
- hooks.onCounterRegression
- Required
- rpName
- origin
- store
- Identity
- rpID
- Ceremony policy
- userVerification
- residentKey
- authenticatorAttachment
- Timing
- timeout
- challengeTimeout
- Cryptography
- challengeSize
- supportedAlgorithms
- Attestation
- attestation
- attestationRootCertificates
- requireBackupEligible
- Hooks
- hooks
- hooks.onRegistered
- hooks.onAuthenticated
- hooks.onCounterRegression
- Full example
- Registration
startRegistration and finishRegistration, and the eighteen checks in between.
- Authentication
startAuthentication and finishAuthentication, usernameless and username-first.
- Credential management
Listing, renaming and revoking passkeys from an account settings page.
- HTTP adapters
The Express middleware, the fetch handler, and the routes they mount.
Browser
- Client API
register, login, autofill, capability detection, and the low-level ceremony calls.
- register
- login
- signInWithAutofill
- isSupported
- isPlatformAuthenticatorAvailable
- isAutofillAvailable
- configure
- createCredential
- getAssertion
- cancelPendingCeremony
- The two calls
- register
- login
- Conditional UI
- signInWithAutofill
- Capability detection
- isSupported
- isPlatformAuthenticatorAvailable
- isAutofillAvailable
- Configuration
- configure
- Lower-level ceremony calls
- createCredential
- getAssertion
- cancelPendingCeremony
- Errors
- Browser errors are deliberately vague
- React
Storage
- PasskeyStore
The ten-method persistence contract and the three rules that matter.
- takeChallenge must delete
- createUser must persist the id it is given
- Index what gets looked up
- getUserByUsername
- getUserById
- createUser
- createCredential
- getCredentialById
- listCredentialsByUserId
- updateCredential
- deleteCredential
- saveChallenge
- takeChallenge
- The three rules
- takeChallenge must delete
- createUser must persist the id it is given
- Index what gets looked up
- The records
- PasskeyUser
- PasskeyCredential
- PasskeyChallenge
- Methods
- getUserByUsername
- getUserById
- createUser
- createCredential
- getCredentialById
- listCredentialsByUserId
- updateCredential
- deleteCredential
- saveChallenge
- takeChallenge
- Next
- Store adapters
Working implementations for Postgres, Prisma, Drizzle, Redis and MongoDB.
Reference
- Errors
Every PasskeyError code, what causes it, and what to do about it.
- PasskeyError
- unsupported
- cancelled
- already_registered
- insecure_context
- not_allowed
- server_error
- challenge_not_found
- origin_mismatch
- rpid_mismatch
- last_credential
- configuration_error
- The class
- PasskeyError
- Browser codes
- unsupported
- cancelled
- already_registered
- insecure_context
- not_allowed
- server_error
- Server codes
- The ones you will actually hit
- challenge_not_found
- origin_mismatch
- rpid_mismatch
- last_credential
- configuration_error
- Mapping to your API
- Types
Every exported interface and type alias.
- PasskeyServerConfig
- OriginMatcher
- PasskeyHooks
- StartRegistrationInput
- StartRegistrationResult
- VerifyRegistrationResult
- StartAuthenticationInput
- StartAuthenticationResult
- VerifyAuthenticationResult
- PublicCredentialInfo
- AttestationResult
- Base64URLString
- Server
- PasskeyServerConfig
- OriginMatcher
- PasskeyHooks
- StartRegistrationInput
- StartRegistrationResult
- VerifyRegistrationResult
- StartAuthenticationInput
- StartAuthenticationResult
- VerifyAuthenticationResult
- PublicCredentialInfo
- AttestationResult
- Storage
- Wire types
- Base64URLString
- String unions
- Algorithms
- Client
- Errors
- Low-level primitives
CBOR, COSE keys, authenticator data. For tooling, not for websites.
- decodeCBOR
- decodeCBORFirst
- parseAuthenticatorData
- parseClientData
- parseCOSEPublicKey
- verifySignature
- algorithmName
- toBase64Url
- fromBase64Url
- CBOR
- decodeCBOR
- decodeCBORFirst
- What the parser refuses
- Authenticator data
- parseAuthenticatorData
- Client data
- parseClientData
- COSE keys
- parseCOSEPublicKey
- verifySignature
- algorithmName
- Encoding
- toBase64Url
- fromBase64Url
- A worked example
Guides
- Frameworks
Express, Next.js, Hono, SvelteKit, Remix, Bun, Deno, Cloudflare Workers.
- Adding to an existing app
Staged rollout alongside passwords, without opening an account-takeover hole.
- Security model
The full verification checklist, design decisions, and what stays your job.
- Failure throws
- Challenges are deleted on read
- Registration cannot take over a username
- Login does not reveal whether an account exists
- Constant-time comparison
- Deleting the last passkey is refused
- A strict CBOR parser
- Zero runtime dependencies
- Session management
- CSRF
- Rate limiting
- Transport security
- Authorization
- Logging
- Why passkeys resist phishing
- Verification checklist
- Registration, WebAuthn §7.1
- Authentication, WebAuthn §7.2
- Design decisions
- Failure throws
- Challenges are deleted on read
- Registration cannot take over a username
- Login does not reveal whether an account exists
- Constant-time comparison
- Deleting the last passkey is refused
- A strict CBOR parser
- Zero runtime dependencies
- Attestation
- The signature counter
- What stays your job
- Session management
- CSRF
- Rate limiting
- Transport security
- Authorization
- Logging
- Account recovery
- Reporting a vulnerability
- Troubleshooting
NotAllowedError, origin_mismatch, challenge_not_found, testing on a phone.
- The prompt never appears, and you get cancelled immediately
- origin_mismatch on finish
- challenge_not_found, intermittently, only in production
- already_registered when adding a second passkey
- login() shows no passkeys, though one is registered
- The second ceremony on a page fails
- The autofill dropdown never offers passkeys
- Testing on a phone
- unsupported thrown on the server
- Types do not resolve
- bad_signature on every login
- Still stuck
Resources
- FAQ
Short answers to the questions that come up before and during adoption.
- Do I have to remove passwords?
- What happens if a user loses every device?
- Will this work for users who have never heard of passkeys?
- Is passkify production ready?
- How is this different from a hosted auth provider?
- Why not use a WebAuthn library that already exists?
- Why does login() not tell me the username does not exist?
- Can one passkey work across my subdomains?
- Can one account have several passkeys?
- Does passkify support 2FA, where a passkey is the second factor?
- What about hardware security keys?
- Do I need Redis?
- Can I run this on an edge runtime?
- How do I migrate credentials from another library?
- How much does this add to my bundle?
- Adoption
- Do I have to remove passwords?
- What happens if a user loses every device?
- Will this work for users who have never heard of passkeys?
- Is passkify production ready?
- Comparisons
- How is this different from a hosted auth provider?
- Why not use a WebAuthn library that already exists?
- Behaviour
- Why does login() not tell me the username does not exist?
- Can one passkey work across my subdomains?
- Can one account have several passkeys?
- Does passkify support 2FA, where a passkey is the second factor?
- What about hardware security keys?
- Operations
- Do I need Redis?
- Can I run this on an edge runtime?
- How do I migrate credentials from another library?
- How much does this add to my bundle?
- Still stuck
- Changelog
Release history, and the compatibility promise for each part of the API.
For agents
- /llms.txt — the map
- /llms-full.txt — every page, one file
npx passkify skills install— skills for your coding agentnpx passkify mcp— an MCP server over these docs