Skip to content

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

  1. 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.dev subdomain/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)

  2. 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.

  3. 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.

  4. Identity delivered in the request context, no JWT parsing. With Access enabled, Cloudflare attaches the authenticated user's identity to the Worker's ctx as ctx.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 with if (!ctx.access) return new Response("Access required", {status: 403}).

  5. Local dev has identity parity. wrangler dev reads an access.dev block in wrangler.jsonc (e.g. {"aud": "my-app", "identity": {"email": "admin@company.com"}}) and surfaces it through the same ctx.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).

  6. 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-template example: a drag-and-drop internal static-site platform where every site deployed through the dispatcher is private.

  7. 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).

  8. 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

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

  • systems/cloudflare-access — auth product now attachable per-Worker / per-account
  • systems/cloudflare-workers — routing/execution split; ctx.access identity
  • 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
Last updated · 766 distilled / 2,225 read