Developer tools for passkeys and WebAuthn
This site is built using Eleventy (11ty).
- Node.js 24.x+ (a mise config pinning it is included, so
mise installworks)
npm installImportant
The webauthnapi.passkeys.dev worker is required for local development! Pull down its repo and follow its Development instructions. Make sure this worker is running locally at http://localhost:8787 before continuing.
To build the site and serve it, along with the API, at http://localhost:8080 (see API for setup):
npm run devBecause of the Worker-based architecture of the site, pages must be rebuilt any time site content is updated. Run the following command locally in a separate terminal to enable seeing updated content after saving changes in the editor:
npm run build:watchTo generate the static site in the public/ directory:
npm run buildThe "Try WebAuthn" demo on the homepage calls /api/v1/*, which is handled by a small Worker in worker/. It owns the session cookie and forwards each request over an RPC service binding (WEBAUTHN) to the webauthnapi-passkeys-dev Worker, which lives in its own repository. The rest of the site is served as static assets from _site/.
To run it locally:
- In the API repository, run
npm run dev(it uses port 8081, and its local dev registry connects the binding). - Here, create a git-ignored
.dev.varswithSESSION_SECRET=<anything>,RP_ID=localhostandEXPECTED_ORIGINS=http://localhost:8080. - Run
npm run devto build the site and serve it with the API onhttp://localhost:8080. Runnpm run watchin another terminal to rebuild when source files change.
Before deploying, set the secret with npx wrangler secret put SESSION_SECRET, then run npm run deploy.
Preview versions are served from a *-tools-passkeys-dev.passkeydeveloper.workers.dev hostname. For those hostnames the Worker uses the hostname as the RP ID and https://<hostname> as the expected origin, so ceremonies complete there, with credentials kept separate from production. Everywhere else, RP_ID and EXPECTED_ORIGINS apply. Previews should use their own SESSION_SECRET.
The site is a Cloudflare Worker serving the built _site/ directory as static assets (see wrangler.jsonc). It is not a Pages project. In Cloudflare, connect the repository under Workers & Pages as a Worker (Workers Builds) with build command npm run build, deploy command npx wrangler deploy, and non-production branch deploy command npx wrangler versions upload.
To deploy by hand, run npm run deploy. npm run preview uploads a version without promoting it and prints its preview URL.
src/: Source files (Nunjucks templates, data, and tool logic).src/_includes/: Shared layouts and components.src/_data/: Global site metadata._site/: The generated static site (output).
Sitemaps are automatically generated during the build process. SEO metadata (Open Graph, Twitter cards, etc.) is managed via the Eleventy data cascade and layouts. Overrides can be set in the Front Matter of individual pages.