Cloudflare Workers Now Support Access Policies Directly — Lock Down Internal Apps by Default
Cloudflare now lets you attach Access policies directly to Workers, so every domain and preview URL is behind your company login by default. Account-level defaults make private-by-default the norm, and a new ctx.access API drops the JWT boilerplate.

Cloudflare has shipped a meaningful upgrade to Workers: you can now apply Cloudflare Access directly to a Worker, or to every Worker in your account, so internal applications are behind your company login by default. No more relying on each developer to remember to lock down their own deployments.
Previously, Access policies were tied to hostnames. If you had a Worker reachable on multiple domains, you had to configure Access on each one individually. Miss one, and that domain was exposed. Now the policy attaches to the Worker itself, covering every domain associated with it — custom domains, routes, workers.dev subdomains, and preview URLs.
You get three levels of control:
- Account-level policy: Set it once, and every Worker in your account — current and future — is private by default. You can scope it to preview URLs only, production traffic, or both.
- Worker-level policy: Lock down a single Worker without affecting the rest of your account.
- Bypass: If you have a Worker that should be public, you can override the account-wide policy on that specific Worker.
For teams running internal platforms, there's a nice trick: set an Access policy on your dispatch Worker in Workers for Platforms, and every Worker deployed through it is private by default. Cloudflare also open-sourced an internal sites template that shows the pattern.
Identity in your code without JWT pain
When Access is protecting a Worker, you can get the authenticated user's email, name, and groups directly in your code via the ctx object. No more parsing JWTs, verifying signatures, and extracting claims.
export default {
async fetch(request, env, ctx) {
if (!ctx.access) {
return new Response("Access required", { status: 403 });
}
const identity = await ctx.access.getIdentity();
const email = identity?.email ?? "unknown";
return new Response(`Hello, ${email}`);
}
};For local development, you can simulate an authenticated user in wrangler.jsonc:
{
"access": {
"dev": {
"aud": "my-app",
"identity": { "email": "admin@company.com" }
}
}
}This means you can test per-user behavior without deploying and going through the full Access login flow every time.
Under the hood: FL2 makes it possible
This feature is built on FL2, Cloudflare's Rust-based modular proxy. To attach Access to Workers instead of hostnames, Cloudflare had to split Workers routing from Workers execution, moving routing logic to run before Access. In the old NGINX/Lua-based FL1 system, that refactor would have been risky. FL2's strict module system with statically declared phases made it safe, letting the compiler catch broken interactions.
Set an Access policy on your dispatch Worker, and every Worker deployed through it is private by default.
Discussion
0 Comments
Be the first to start the discussion.