Learn authentication by building it right.
Live Demo Β· Threat Model Β· Auth Flows Β· ADRs
A from-scratch authentication reference implementation for Cloudflare Workers β PBKDF2 password hashing, JWT dual-token sessions, constant-time comparison, and sliding expiration β all wired together with Hono, Turso (with optional Valkey/Redis caching), and strict TypeScript.
Every design choice traces back to a standard: NIST SP 800-63B for credentials, NIST SP 800-132 for key derivation, OWASP ASVS for verification, and RFC 8725 for JWT best practices.
Shipping a product? Use Better Auth instead β it covers OAuth, passkeys, MFA, rate limiting, and more out of the box with an active plugin ecosystem. This repo exists to teach you how auth works, not to replace a production library.
- Read the code, not just the docs β every security property (timing-safe rejection, session-linked revocation, algorithm pinning) is implemented and tested, not just described
- NIST + OWASP + RFC references throughout β learn the why behind each decision
- 370+ tests including attack-vector suites (token tampering, algorithm confusion, unicode edge cases)
- Built for the edge β runs on Cloudflare Workers with Web Crypto API, no Node.js dependencies
- Apache-2.0 β fork it, teach with it, learn from it
| Layer | What it does |
|---|---|
| Password storage | PBKDF2-SHA384 with 128-bit salts, integrity digest, version tracking (password-service.ts) |
| Session management | Server-side sessions with device tracking, sliding expiration, max-3-per-user enforcement; optional cache-backed sessions via Valkey/Redis (session-service.ts, cached-session-service.ts) |
| Password change | Current-password re-verification, full PBKDF2 rehash, atomic revocation of all sessions (account-service.ts, ADR-004) |
| JWT dual-token pattern | 15-min access + 7-day refresh tokens, session-linked for revocation (token-service.ts) |
| Auth middleware | Automatic refresh flow, explicit HS256 pinning, typ claim validation (require-auth.ts) |
| Secure cookies | HttpOnly, Secure, SameSite=Strict, Path=/ (cookie.ts) |
| Security headers | HSTS, CSP, CORP/COEP/COOP, Permissions-Policy, fingerprint removal (security.ts) |
| Input validation | Zod schemas with NIST-compliant password policy (length only, no complexity rules) |
| Attack-vector tests | JWT tampering, algorithm confusion, type confusion, unicode edge cases, info-disclosure checks |
This project intentionally omits features that are outside its educational scope. If you're extending this code toward production (or evaluating what a production auth system requires), the tables below organize the gaps by priority tier.
For most real-world projects, use Better Auth instead of building these yourself.
| Feature | Why It Matters | Standard / Reference |
|---|---|---|
| Rate limiting | Prevents brute-force login and credential-stuffing attacks β the cache layer (ADR-003) is available as a foundation | OWASP ASVS v5.0 Β§6.3.1 |
| Account lockout / throttling | Slows automated attacks without full rate-limiting infra | NIST SP 800-63B Β§5.2.2 |
| Breached-password checking | Prevents use of passwords known to be in public breach dumps | NIST SP 800-63B Β§5.1.1.2, HIBP API |
| Feature | Why It Matters | Standard / Reference |
|---|---|---|
| CSRF protection (if SameSite relaxed) | SameSite=Strict currently prevents CSRF; if changed to Lax for UX, an explicit token is needed | OWASP CSRF Cheat Sheet |
| Refresh token rotation | Detects token theft β if a rotated-out refresh token is replayed, revoke the entire session family | RFC 6819 Β§5.2.2.3 |
aud claim in JWTs |
Prevents token from one service being accepted by another sharing the same secret | RFC 7519 Β§4.1.3, RFC 8725 Β§3.9 |
| Audit logging | Enables incident response, anomaly detection, and compliance | OWASP Logging Cheat Sheet |
| CSP nonces for inline scripts | Current CSP uses 'unsafe-inline'; nonces eliminate inline-script XSS vectors |
MDN CSP script-src |
| Feature | Why It Matters | Standard / Reference |
|---|---|---|
| TOTP multi-factor auth | Adds a second factor for high-value accounts | RFC 6238, NIST SP 800-63B Β§5.1.4 |
| WebAuthn / passkeys | Phishing-resistant authentication using platform authenticators | WebAuthn Level 2 |
| OAuth / social login | Reduces friction, avoids password fatigue | RFC 6749 |
| Magic links / OTP | Passwordless option for low-risk flows | NIST SP 800-63B Β§5.1.3 |
| Session analytics | Device tracking, concurrent-session visibility, anomaly detection | OWASP Session Management Cheat Sheet |
| Signing key rotation | Allows periodic secret rotation without invalidating all sessions | RFC 7517 (JWK) |
| Feature | Why It Matters | Standard / Reference |
|---|---|---|
| DPoP / token binding | Binds tokens to the client's TLS connection, preventing exfiltration replay | RFC 9449 (DPoP) |
| Multi-tenancy | Isolates user pools, secrets, and policies per tenant | Application-specific |
| Geo-fencing / IP reputation | Blocks logins from unexpected regions or known-bad IPs | OWASP ASVS v5.0 Β§6.3.5 |
| Adaptive authentication | Steps up auth requirements based on risk signals (device, location, behavior) | NIST SP 800-63B Β§6 |
| PBKDF2 iteration upgrade or Argon2id | OWASP recommends 210,000 PBKDF2-SHA512 iterations (Cloudflare limits to 100k); Argon2id is memory-hard | OWASP Password Storage Cheat Sheet |
All of these are excellent reasons to reach for Better Auth instead.
.
βββ apps/
β βββ cloudflare-workers/ # Example Worker + Hono routes
βββ packages/
β βββ core/ # Auth services, middleware, crypto utilities
β βββ infrastructure/ # DB client + utilities
β βββ schemas/ # Zod schemas
β βββ types/ # Shared TypeScript types
βββ docs/
βββ adr/ # Architecture Decision Records
βββ audits/ # Security audits
# Clone and install
git clone https://github.com/vhscom/private-landing.git
cd private-landing
bun install
# Build packages
bun run build
# Start dev server
bun run devSee CONTRIBUTING.md for detailed setup and testing instructions.
This repository includes a CLAUDE.md file that provides context for AI assistants. When using Claude Code, Cursor, or similar AI-powered development tools:
- The AI will automatically read
CLAUDE.mdfor project context - Architecture Decision Records in
docs/adr/explain design choices - Security audits in
docs/audits/document the security posture - Tests demonstrate expected behavior and edge cases
The codebase is designed to be AI-readable with clear module boundaries, comprehensive types, and descriptive naming.