-
Notifications
You must be signed in to change notification settings - Fork 29
Description
The current Hono example runs better-auth-cloudflare as part of a single monolithic worker. This works fine for simple apps, but most production Cloudflare architectures split functionality across multiple workers. There’s currently no example showing how to run auth as a dedicated isolated worker consumed by other workers via Cloudflare Service Bindings.
Why this matters
Cloudflare’s Service Bindings allow one worker to call another directly — no public HTTP, no latency overhead, no extra egress cost. This enables an auth-as-a-service pattern inside your own Cloudflare account:
┌─────────────────┐ Service Binding ┌──────────────────┐
│ App Worker A │ ──────────────────► │ Auth Worker │
├─────────────────┤ │ (better-auth-cf) │
│ App Worker B │ ──────────────────► │ D1 + KV │
└─────────────────┘ └──────────────────┘
Benefits:
- Isolation — auth logic, D1 schema, KV namespace all owned by one worker. No other worker touches auth data directly
- Reusability — any new worker just adds a
[[services]]binding and gets session checking for free - Zero latency — Service Bindings are in-process, not HTTP round trips
- Simpler security surface — auth worker is never publicly exposed, only reachable via bindings
What the example would show
wrangler.toml in the auth worker — standard, as today
wrangler.toml in a consuming worker:
[[services]]
binding = "AUTH"
service = "my-auth-worker"Session checking in a consuming worker:
app.get("/api/protected/*", async (c) => {
const res = await c.env.AUTH.fetch(
new Request("https://auth/api/auth/get-session", {
headers: c.req.raw.headers // forward cookies
})
);
const session = await res.json();
if (!session?.user) return c.json({ error: "Unauthorized" }, 401);
// handle request
});Optional: typed auth client helper shared across workers via a workspace package
Why the current example doesn’t cover this
The existing Hono example co-locates the auth handler and the protected route in the same worker. That’s fine as a getting-started demo, but leaves developers to figure out the Service Bindings pattern themselves — which involves:
- Understanding that
better-auth’s handler works fine as a standalone worker with no changes - Knowing to forward raw request headers (including cookies) through the binding
- Handling CORS correctly when the auth worker is internal-only
- Knowing
BETTER_AUTH_URLshould point to the public-facing domain, not the internal binding URL - Passing
ctx.waitUntilcorrectly so background tasks (token cleanup, session writes) complete after the response is sent across the binding
Is this blocking?
No — the pattern works today, it’s just undocumented in this repo. Developers hitting multi-worker architectures have to piece it together from Cloudflare docs + Better Auth docs + this repo’s README separately.
Related
- Roadmap item:
Durable Objectssupport (which would pair well with this pattern for stateful session management) - The README mentions Service Bindings in the Hono setup guide but doesn’t show a concrete example
- Known gotcha:
ctx.waitUntilmust be forwarded through the binding call to prevent background task errors after response is sent