Local development
Run the auth server on your machine against a local D1 database.
You can run the full auth server locally against a local D1 database — no Cloudflare account required for day-to-day development.
1. Set up local environment variables
cd apps/auth
cp .env.example .env.local
cp .dev.vars.example .dev.varsFill in .env.local and .dev.vars with your local values.
2. Generate a local JWT certificate
npm run jwt:generate-local-cert3. Run local D1 migrations
npm run db:migrate4. Create a local admin user
npm run db:create-admin:local5. Start the dev server
npm run dev --workspace=apps/auth
# or, from the repo root: npm run devThe auth server is available at http://localhost:3000.
Passkeys need HTTPS
For passkey testing you may need HTTPS. Use a tunneling tool (e.g. Cloudflare Tunnel) to expose your local server with a valid TLS certificate.
6. Verify the local setup
npm run verifyConfirms the local JWT material, the local R2 jwks.json (the kid the server signs with), and
the core secrets all line up — catching the case where the local R2 holds a stale key and
locally-issued tokens fail verification.
One-shot bootstrap
npm run setup:local is the fresh-environment bootstrap: it prepares .env.local and .dev.vars,
writes HASH_METHOD=md5 for local-only hashing, applies db/schema.sql to the local D1 database,
and seeds a local admin / admin user with an MD5 password hash. Use npm run setup:local:env
when you want the local env files without touching the database.
Local hashing
Local development uses HASH_METHOD=md5 so you don't need the Rust argon-hasher Worker running
to sign in. Production always uses Argon2id via the hasher Worker.