Cloudflare Access (4)·续

You can add one or more policies. Visitors who match any selected policy can sign in.

For advanced policy configuration, such as multiple identity providers, device posture rules, service tokens, complex policy ordering, or custom login or block pages, edit the Access application in Zero Trust after you create it. For the full set of options, refer to Access policies.

Read authenticated user identity with ctx.access

When Cloudflare Access authenticates a request that directly invokes your Worker, the Worker can read the signed-in user's identity — including email, groups, device posture, and more identity fields — through ctx.access. No extra configuration or JWT parsing is required.

Use this to personalize responses, enforce fine-grained permissions, or log activity per user.

ctx.access is undefined if Access did not authenticate the request.

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}`);
    },
};
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}`);
    },
};

ctx.access limitations

Note

ctx.access applies only to the Worker invocation authenticated by Access. Cloudflare Access does not propagate ctx.access through Service Binding HTTP requests or remote procedure call (RPC) invocations. The downstream Worker does not receive the caller's Access context.

If the caller instead sends a fetch() subrequest to an Access-protected hostname with valid service token headers or a valid CF_Authorization cookie, Access evaluates the new request and creates a ctx.access object for the downstream Worker. This is a newly authenticated context, not context propagated from the caller.

Workers with Static Assets execute behind an internal router Worker. Access still protects the application and its assets. However, the router does not pass ctx.access to the user Worker.

The Cloudflare Vite plugin can add assets to the generated deployment configuration when the input Wrangler configuration omits it. Frameworks that use the plugin, including TanStack Start, can therefore be affected even when their source configuration does not declare Static Assets.

Test ctx.access locally

When developing locally with wrangler dev or the Cloudflare Vite Plugin, you can simulate authenticated Cloudflare Access identities without deploying or going through an Access login flow.

Add a dev block inside the access configuration in your wrangler.jsonc:

{
    "access": {
        "dev": {
            "aud": "my-app",
            "identity": { "email": "admin@example.com" }
        }
    }
}
[access.dev]
aud = "my-app"

[access.dev.identity]
  email = "admin@example.com"
  • aud (required) — your Access application's audience tag, available as ctx.access.aud. Wrangler will not start without it.
  • identity (optional) — simulates the authenticated user's identity claims (email, name, groups, and so on) returned by ctx.access.getIdentity(). Include it if your Worker reads user identity. Omit it if your Worker only checks whether Access is enabled.

To test as a different user, change the identity fields and restart. To test unauthenticated requests, remove the dev block — ctx.access will be undefined, just as it would be for a request that did not go through Access in production.

Example Worker

export default {
    async fetch(request, env, ctx) {
        if (!ctx.access) {
            return new Response("Not authenticated", { status: 403 });
        }

const identity = await ctx.access.getIdentity();
        const email = identity?.email ?? "unknown";

return new Response(`Hello, ${email}`);
    },
};
export default {
    async fetch(request, env, ctx) {
        if (!ctx.access) {
            return new Response("Not authenticated", { status: 403 });
        }

const identity = await ctx.access.getIdentity();
        const email = identity?.email ?? "unknown";

return new Response(`Hello, ${email}`);
    },
};

With this configuration, visiting localhost:8787 would return Hello, admin@example.com.

Identity fields

The identity object accepts any fields that match the production Access identity shape. For the full list, refer to Application token — User identity.

Disable Access

To disable Worker-level or account-level Access, open the Worker's Access tab or the Protect all Workers card and disable the corresponding Access rule.

Delete the Access application that protects the Worker, all Workers, or the hostname or path that routes to the Worker.

Understand Access hierarchy

A Worker can be protected by more than one Access rule. When multiple rules could apply to the same request, the most specific rule takes effect first:

  1. Hostname or path-based Access: Applies first when the request matches that hostname or path, such as admin.example.com or example.com/login.
  2. Worker-level Access: Applies next for the selected Worker across its routes, Custom Domains, workers.dev hostname, and previews.
  3. Account-level Worker Access: Applies last as the fallback for all Workers or all Worker previews on the account.

For example, if a Worker has both account-level Access and a Worker-level rule, the Worker-level rule controls that Worker. If a matching hostname or path-based Access app also exists, that hostname or path rule controls the matching URL.

If you remove a more specific rule, a broader rule may still protect the Worker. For example, removing Worker-level Access can reveal account-level Access underneath.

Was this helpful?

YesNo

On this page

Cloudflare Access (4)·续 - 图1Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/workers/configuration/cloudflare-access/#page","headline":"Cloudflare Access","description":"Require sign-in before visitors can reach Cloudflare Workers, preview deployments, or all Workers in an account.","url":"https://developers.cloudflare.com/workers/configuration/cloudflare-access/","inLanguage":"en","image":"https://developers.cloudflare.com/workers/configuration/cloudflare-access/og.png?v=ec35e0ca6f3535fe","dateModified":"2026-10-12","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}


description: Configure Workers projects with a typed cloudflare.config.ts file. title: Programmatic configuration image: https://developers.cloudflare.com/cf/projects/cloudflare-config/og.png?v=b3958a991af163a7


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/cf/llms.txt
Use this file to discover all available pages before exploring further.