Hono on Cloudflare Workers
Real separate deploymentA confidential Auth0 client using @auth0/auth0-hono · deployed for real to Cloudflare Workers, not embedded in this app · same OIDC flow as Traditional/BFF, but a genuinely different session-storage and runtime model
Try it on the real deployment
This runs on its own Cloudflare Workers deployment with its own Auth0 application — log in there for real, view the decoded claims and access token on its /dashboard, then log out.
Same flow, different foundations
| Traditional / BFF (this suite) | Hono on Cloudflare Workers | |
|---|---|---|
| Runtime | Node.js serverless (Vercel Functions) | V8 isolate, edge-distributed (Cloudflare Workers) |
| Session storage | Stateful — Firestore-backed SessionDataStore; cookie holds only an opaque session ID | Stateless by default — session data lives inside an encrypted cookie, no database |
| Revocation model | Delete the Firestore doc; Back-Channel Logout already wired | No server-side record to delete by default — revocation means key rotation or a short TTL |
| Setup | Hand-rolled routes per pattern, using SDK primitives directly | One middleware call — app.use('*', auth()) auto-mounts login/callback/logout/backchannel-logout |
| SDK | @auth0/nextjs-auth0 | @auth0/auth0-hono |
Same confidential-client model, same Authorization Code + PKCE flow underneath — the actual teaching point is that the session-storage and runtime axes are both genuinely different, not that one implementation is better than the other.
Security Implications
Strengths
- No database to provision or manage — the default session mode is entirely self-contained in an encrypted cookie, removing an entire category of infrastructure (and its own attack surface) that Traditional/BFF depend on.
- Runs at the edge across Cloudflare's network rather than a single serverless region, with no Node.js API polyfills needed for the core auth flow.
- One middleware call (auth()) auto-mounts login, callback, logout, and backchannel logout — far less hand-rolled route code than this suite's other confidential-client demos, which trades explicitness for convenience.
Risks & Considerations
- The default session mode's revocation model is fundamentally weaker than Traditional/BFF's: there is no server-side record to delete. A compromised session cookie remains valid until it expires or the signing key is rotated — killing a session on demand is not possible out of the box.
- Do not assume Back-Channel Logout parity with Traditional/BFF just because the SDK supports it — that requires explicitly wiring a stateful KVSessionStore (Cloudflare KV), which this deployment does not use.
- authRequired defaults to true and protects every route, including public ones, unless explicitly set to false — an easy default to miss (this demo's own `/` route 401'd until that was set explicitly), and the opposite failure mode of most frameworks, which default to routes being public.
- A self-contained cookie holding the full OIDC payload (ID token, access token, refresh token, profile claims) can bump up against browser per-cookie size limits (~4KB) faster than it looks — a tenant with several custom claims or a large user profile could hit this in production even though it works fine in a demo with a minimal user.
Hardening Checklist
- Keep session TTLs short in the default stateless mode — there is no kill switch, so lifetime is the primary control you have over exposure.
- Add a KVSessionStore (or equivalent pluggable store) if this needs to reach Back-Channel Logout parity with the rest of the suite — it is supported, just not the default.
- Explicitly set authRequired: false for any route that should be public, and verify it — do not rely on the default matching your intent.
- If the session is approaching cookie size limits, use a pluggable SessionStore (e.g. KVSessionStore) to keep the cookie itself small — the same lever that restores Back-Channel Logout parity also fixes this.