Private by default for workers.dev URLs
The old setup was awkward in a very specific way: protection lived beside the Worker, not in it. If a route changed, a Custom Domain moved, or a workers.dev URL got added during testing, the Access application list could drift out of sync. That kind of drift is easy to miss and annoying to clean up.
With Worker-attached Access, the protection follows the Worker itself. That means associated domains, routes, workers.dev URLs, and preview URLs can all inherit the same policy without separate Access application entries for each one. The practical effect is blunt: the default is closed, and exposure needs to be deliberate.
Why the default flips from public to private
The old model assumed that public reachability was normal and protection was bolted on afterwards. That works until the Worker starts collecting extra entry points. A preview URL appears, someone adds a route for testing, or a workers.dev URL stays alive after the main hostname moves. Each one becomes another place to forget a rule.
An account-wide default changes that habit. Instead of asking which entry point needs Access, the account can require sign-in before anyone reaches a Worker. That removes the “temporary public path that stayed open for six months” problem, which is a familiar sort of mess.
The old model depended on separate Access applications
Separate Access applications made sense when protection was attached to the domain or route. They also created a second inventory to keep tidy. In practice, that inventory had to match the Worker’s current routes, domains, and preview surfaces. When those changed, the Access entries needed to change as well.
That is the part that goes wrong. The Worker changes first, the Access list changes later, and in the gap the wrong thing is open or closed. Attaching policy to the Worker removes that split-brain setup.
Account-wide protection changes the failure mode
If the account default is private, the main risk is no longer forgotten coverage. The risk becomes forgetting to create an explicit exception where public access is actually required. That is a better failure mode for most internal or authenticated Workers.
Public access still exists, but it sits behind a policy decision rather than a missing config line. If a Worker must be public, the bypass needs to be explicit.
What changes in the request path and the dev loop
Protected requests now carry identity into the Worker runtime. That changes how the code handles authentication data and how local development behaves. The old JWT dance disappears from the common path, which is a relief for anyone who has spent too long decoding headers by hand.
ctx.access and ctx.access.getIdentity() remove the JWT dance
When Access is enabled on a Worker, authenticated requests include ctx.access. From there, ctx.access.getIdentity() returns user identity data, including email, name, and groups. No manual JWT validation is needed in the Worker itself.
That shifts auth handling out of application code and into the platform boundary where it belongs. The Worker receives identity as part of the request context rather than reconstructing it from headers. If ctx.access is absent, the Worker can return a 401 because Access did not run.
wrangler dev can carry a test identity from wrangler.jsonc
Local development can carry a test Access identity through wrangler.jsonc. The access.dev block can set an audience and a test identity email, which gives wrangler dev a way to simulate an authenticated request. Remove that dev block and the same setup simulates an unauthenticated request.
That is a tidy improvement for development, because the identity path can be exercised without hand-rolling tokens or copying browser state into a terminal session. It is also a reminder that the local path should match the deployed one closely enough to catch bad assumptions early.
Where to apply the policy and what to verify
Policy can sit on a single Worker or across all Workers in the account. It can also target preview deployments only, or both preview and production. That matters because preview URLs are exactly where people tend to get lazy and leave things half-protected.
Cover workers.dev URLs, previews, and production without drift
If a Worker has a public route in one place and a protected preview in another, the setup gets messy fast. The better boundary is to cover the Worker once and let the associated domains, workers.dev URLs, and preview URLs inherit the same rules. That keeps the policy tied to the code path rather than to whatever hostname happened to exist this week.
For teams that use preview deployments heavily, a preview-only policy can make sense. For stable production access, the same Worker policy can apply to both preview and live traffic. The point is not to layer more rules for the sake of it, but to stop the usual drift between environments.
Check preview-only rules, bypasses, and unauthenticated responses
Preview-only rules need a close look because they can create false confidence. A protected preview does not mean the production route is protected, and the reverse is just as awkward. Check which deployment targets the policy actually covers before assuming the URL in the browser is the one that matters.
Bypasses need the same scrutiny. If a Worker is meant to stay private, any public exception should be narrow and obvious. If it is meant to be public, the response path should behave like a public service, not a protected one returning odd half-authenticated errors. When ctx.access is missing, a clean 401 is the predictable outcome, which is better than letting the Worker drift into ambiguous behaviour.



