The stack in 60 seconds
┌──────────────────────────────┐
│ User's browser / app SDK │
└──────────────┬───────────────┘
│ HTTPS
▼
┌───────────────────────────────────────────┐
│ auth.kynetra.dev (Cloudflare Pages) │
│ Next.js 15 — marketing, dashboard, docs │
└──────────────┬────────────────────────────┘
│ fetch()
▼
┌───────────────────────────────────────────┐
│ kynetra-auth-api (Cloudflare Worker) │
│ Hono framework + WebCrypto + jose │
├───────────────────────────────────────────┤
│ Bindings: │
│ DB → D1 (SQLite, APAC) │
│ RATE_LIMIT → KV namespace │
│ ASSETS → R2 bucket │
│ AI → Workers AI │
│ AUTH_EVENTS_QUEUE → Queues │
│ ANALYTICS → Analytics Engine │
│ + cron triggers (every 15 min, daily) │
└───────────────────────────────────────────┘Why edge auth matters
Sub-millisecond JWT verification
Cloudflare's edge runs at 300+ PoPs globally. A JWT verification that takes 8-15ms on a centralized server takes <1ms on a Worker because the runtime is already warm and physically near the user.
Zero cold starts
Workers V8 isolates start in <5ms. Compare to AWS Lambda's 200-1000ms cold start for Node, or even longer for containers. Your auth flow is never the slow path.
No infrastructure to manage
No EC2, no RDS, no Redis clusters, no Kubernetes. The Worker scales from zero to millions of requests automatically. D1 is replicated across regions. Cron triggers run on Cloudflare's schedulers.
Data model
D1 SQLite schema, 9 tables. Postgres types mapped to SQLite primitives:
| Postgres | D1 / SQLite | Strategy |
|---|---|---|
| uuid | text | crypto.randomUUID() in application code |
| jsonb | text | JSON.parse / JSON.stringify on read/write |
| timestamp | integer | Unix epoch ms — orderable, no parsing |
| boolean | integer (0/1) | Drizzle ORM handles transparently |
Tables: tenants, users, credentials, sessions, roles, memberships, audit_logs, admin_settings, mfa_enrollments.
Cryptography choices
Password hashing: PBKDF2-SHA256 @ 100k
Workers caps PBKDF2 at 100,000 iterations (vs 600k+ on Node). Combined with a 16-byte random salt this gives reasonable protection. For Argon2-grade hashing, run signup through a separate hashing service.
JWT: HS256 via jose
Symmetric HMAC. Fast at the edge, works without JWKS rotation. RS256 supported when JWKS_PRIVATE_KEY is provisioned. All tokens carry sub, tid, email, roles[], scope[], jti, iat, exp.
TOTP: WebCrypto HMAC-SHA1
RFC 6238 implemented against the WebCrypto API — no Node crypto module needed. ±1 step tolerance for clock drift. 20-byte base32 secrets.
Secret encryption at rest: AES-256-GCM
LLM API keys, magic-link tokens, and other secrets are AES-GCM encrypted with a key derived from JWT_SECRET via PBKDF2. Auth tags prevent tampering.
Cron triggers
The Worker runs scheduled jobs without external orchestration. Two crons are active in production:
*/15 * * * *Revoke expired sessions, purge consumed magic-link tokens (soft-delete)0 3 * * *Daily 03:00 UTC: hard-delete records soft-deleted > 90 days agoPerformance
Want to see it live?
Cloudflare Console shows all 6 bindings + cron triggers in real time.