Cloudflare Service Binding
Call your bao auth worker directly from another Cloudflare Worker with zero HTTP overhead for server-side session checks.
If your app runs on Cloudflare Workers or Pages with Functions, you can bind directly to your bao auth Worker. Server-side session verification becomes an in-process call — no HTTP round-trip, no network latency.
Client-side code (running in the browser) still uses createAuthClient over HTTP as normal.
Add the service binding
In your app’s wrangler.json or wrangler.jsonc, add a services entry pointing at your bao worker name:
{
"name": "my-app",
"services": [
{
"binding": "BAO_AUTH",
"service": "my-app-production", // your bao worker name
},
],
}Your bao worker name is the name field in the auth-service’s wrangler.json, typically {appName}-{env} (e.g. my-app-production).
Add the binding type to your environment interface:
// worker-configuration.d.ts
interface Env {
BAO_AUTH: Fetcher;
// ...your other bindings
}Verify a session server-side
Forward the incoming request headers to the auth-service via the binding. The auth-service reads the session cookie and returns the session:
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Forward the session cookie to the auth-service
const sessionResponse = await env.BAO_AUTH.fetch(
new Request("https://bao/api/auth/get-session", {
headers: request.headers,
}),
);
const session = await sessionResponse.json<{
user?: { id: string; email: string };
}>();
if (!session.user) {
return new Response("Unauthorized", { status: 401 });
}
return new Response(`Hello ${session.user.email}`);
},
};The URL hostname (https://bao/...) is ignored by the service binding — only the path matters. Use any placeholder hostname.
Astro (Pages with Functions)
In an Astro SSR project using @astrojs/cloudflare, access the binding from Astro.locals.runtime.env:
// src/middleware.ts
import { defineMiddleware } from "astro:middleware";
export const onRequest = defineMiddleware(async (context, next) => {
const env = context.locals.runtime.env as Env;
const sessionResponse = await env.BAO_AUTH.fetch(
new Request("https://bao/api/auth/get-session", {
headers: context.request.headers,
}),
);
const session = await sessionResponse.json<{ user?: { id: string } }>();
context.locals.user = session.user ?? null;
return next();
});// src/pages/dashboard.astro (frontmatter)
---
if (!Astro.locals.user) {
return Astro.redirect("/login");
}
---Client-side setup
The binding only applies to server-side code. In the browser, use createAuthClient as normal — see Connect your app.
When to use this vs HTTP
| HTTP client | Service Binding | |
|---|---|---|
| Works in | Any runtime | Cloudflare Workers / Pages only |
| Server-side latency | ~10–50ms per check | ~0ms (in-process) |
| Setup | Env var + CORS | wrangler binding |
| Client-side | Same | Same |
If you’re already on Cloudflare and server-side auth is on the hot path (e.g. middleware that runs on every request), the service binding is worth it. Otherwise the HTTP client is simpler and portable.