Secure all your internal vibe-coded applications - in one click¶
Summary¶
Cloudflare lets you apply Cloudflare Access
authentication directly to a Worker — or to
every Worker in an account — so applications sit behind the company login
by default, without each developer wiring it up. The motivating problem is
AI-accelerated internal app sprawl: any employee can vibe-code an app and deploy
it to the public Internet, accidentally exposing internal data. The core
architectural shift is moving the Access policy from the hostname to the
Worker itself: previously you configured Access per-domain, so adding a new
custom domain to a Worker left that hostname reachable without auth until you
updated the policy; now the policy is attached to the Worker, so "any domain or
URL associated with that Worker is automatically protected" — custom domains,
routes, workers.dev subdomains, and preview URLs. An account-level policy makes
every current and future Worker private from the moment it's created
(account-wide-default-policy), with a per-Worker bypass escape hatch.
Authenticated identity is injected into the Worker's context object as
ctx.access — call ctx.access.getIdentity() to get email/name/groups with no
JWT validation required (request-context-identity-injection), and
wrangler dev can simulate an authenticated user locally via an access block in
wrangler.jsonc (local-dev-identity-simulation,
concepts/local-remote-parity). The feature was made possible by FL2, the
Rust-based modular proxy replacing the NGINX+Lua FL1 stack: to let Access target
individual Workers, Cloudflare had to split Workers routing from Workers
execution and move routing to run before Access in the request pipeline — a
change described as complex/risky in FL1 but safe in FL2 because its strict,
phase-ordered module system statically
declares each phase's inputs/outputs, letting the compiler surface broken
inter-product interactions.
Key takeaways¶
-
Attach the auth policy to the Worker, not the hostname. Hostname-scoped Access policies leave a coverage gap: a newly added custom domain is reachable without auth until its policy is created. Binding the policy to the Worker closes the gap — every domain/route/
workers.devsubdomain/preview URL that resolves to the Worker is protected automatically, regardless of how the request arrives. (Source: sources/2026-08-14-cloudflare-secure-all-your-internal-vibe-coded-applications-in-one-click) -
Private-by-default via an account-level policy. Set one Access policy at the account level and every Worker — current and future — is private from creation, so security does not depend on each developer remembering to enable it (private-by-default-deployment, account-wide-default-policy). You choose the scope: preview-URL traffic only, all production traffic, or both. Preview-only is useful when production Workers are intentionally public but in-progress deployments must never be exposed. A per-Worker bypass keeps individual Workers public.
-
Most-specific policy wins. When multiple Access policies apply, precedence is hostname policies → Worker policies → account policies. The new Access tab in the Worker view shows exactly which policies apply to that application.
-
Identity delivered in the request context, no JWT parsing. With Access enabled, Cloudflare attaches the authenticated user's identity to the Worker's
ctxasctx.access;await ctx.access.getIdentity()returns email/name/ groups. Previously the Worker had to validate a JWT itself — parse the token, verify the signature, extract claims. Now that is handled upstream and the Worker reads a ready object (request-context-identity-injection). Guard withif (!ctx.access) return new Response("Access required", {status: 403}). -
Local dev has identity parity.
wrangler devreads anaccess.devblock inwrangler.jsonc(e.g.{"aud": "my-app", "identity": {"email": "admin@company.com"}}) and surfaces it through the samectx.access.getIdentity()shape as production, so per-user rendering can be tested without deploying and signing in through Access each time (local-dev-identity-simulation, concepts/local-remote-parity). -
Internal platforms go private-by-default via the dispatch Worker. Workers for Platforms runs every deployed Worker inside a namespace whose traffic passes through a single entry point, the dispatch Worker. Setting an Access policy on the dispatch Worker makes every Worker deployed through it private by default — a single choke point (patterns/central-proxy-choke-point). Cloudflare open-sourced an
internal-sites-templateexample: a drag-and-drop internal static-site platform where every site deployed through the dispatcher is private. -
FL2's phase-ordered module system made a risky pipeline change safe. Access is the front gate and traditionally ran before all Workers logic. To let Access target individual Workers (not hostnames), Access must know which Worker a request is destined for, which required splitting Workers routing from Workers execution and moving routing earlier in the pipeline. In the old FL1 system (NGINX + Lua modules) this would be complex and risky — "moving logic to an earlier phase of the request pipeline can be unsafe if it depends on shared state that is modified by another product." FL2's strict module system separates logic into "well-defined, consistently ordered phases that statically declare their inputs and outputs," so the compiler surfaces broken interactions between phases and the refactor could roll out gradually with confidence (systems/fl2-proxy, phase-ordered-module-pipeline).
-
Agents authenticate too. Access controls how users authenticate (connect an existing IdP, or restrict to specific emails / email domains / groups) and supports service tokens for granting agents access.
Systems / concepts / patterns extracted¶
- Systems: Cloudflare Access (extended — Worker-
and account-level policies,
ctx.access), Cloudflare Workers (extended — routing/execution split,ctx.access), Workers for Platforms (new — dispatch-Worker namespace model), FL2 (new — Rust modular edge proxy), Cloudflare One,wrangler. - Concepts: private-by-default-deployment (new), phase-ordered-module-pipeline (new), request-context-identity-injection (new), concepts/defense-in-depth, concepts/local-remote-parity.
- Patterns: account-wide-default-policy (new), worker-attached-policy-over-hostname-policy (new), local-dev-identity-simulation (new), patterns/central-proxy-choke-point (dispatch-Worker instance).
Operational notes¶
- Precedence order for overlapping Access policies: hostname → Worker → account.
- Account-level policy scope options: preview-only, all-production, or both.
- Identity object fields exposed via
ctx.access.getIdentity(): email, name, groups (and more per the application-token docs). - Open-source reference:
cloudflare/templates/tree/main/internal-sites-template. - Availability: GA to everyone at publication.
Source¶
- Original: https://blog.cloudflare.com/workers-protected-by-access/
- Raw markdown:
raw/cloudflare/2026-08-14-secure-all-your-internal-vibe-coded-applications-in-one-clic-f75a01ba.md
Related¶
- systems/cloudflare-access — auth product now attachable per-Worker / per-account
- systems/cloudflare-workers — routing/execution split;
ctx.accessidentity - systems/workers-for-platforms — dispatch-Worker choke point for private-by-default platforms
- systems/fl2-proxy — Rust modular proxy whose phase system enabled the pipeline reorder
- private-by-default-deployment
- phase-ordered-module-pipeline
- request-context-identity-injection
- account-wide-default-policy
- worker-attached-policy-over-hostname-policy
- local-dev-identity-simulation