Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Self-hosted applications can also protect a Cloudflare Worker directly by name,

This is the safest and most straightforward way to put authentication in front of a Worker. Instead of configuring individual routes on the Worker and managing authentication at the route level, you link the entire Worker (and optionally its preview deployments) to an Access application. Any request to the Worker on any route passes through Access first.

For Workers-specific setup instructions, refer to [Cloudflare Access for Workers](/workers/configuration/cloudflare-access/).

### CLI access with cloudflared

Self-hosted applications support client-side `cloudflared` authentication. Users can install `cloudflared` on their device and run `cloudflared access login <hostname>` from the command line to authenticate through your Access policies without the Cloudflare One Client installed. This is useful for SSH sessions, API calls, and other command-line workflows where a browser-based login flow is impractical.
Expand Down
256 changes: 256 additions & 0 deletions src/content/docs/workers/configuration/cloudflare-access.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
---
pcx_content_type: configuration
title: Cloudflare Access
description: Require sign-in before visitors can reach Cloudflare Workers, preview deployments, or all Workers in an account.
products:
- workers
---

import { DashButton, Steps, Tabs, TabItem } from "~/components";

Cloudflare Access makes a Worker private by checking each visitor before your Worker runs: allowed visitors reach your Worker, and everyone else gets a login page or has their request blocked. You define who is allowed, such as members of your Cloudflare account or anyone with a verified email address at a domain like `example.com`.

## Before you start

To use Access with Workers, you need:

- A Cloudflare Zero Trust organization set up for the account. If Zero Trust is not turned on, complete [Zero Trust setup](/cloudflare-one/setup/) first, then return to the Workers dashboard.
- Permission to manage Workers and Access applications.

## Choose what to protect

Start with what you want visitors to sign in to access, then follow that section below. Each section covers both the dashboard and the API.

| I want to protect... | Section | API destination type |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------ |
| Production and preview deployments for **all Workers** | [Protect all Workers](#protect-all-workers) | `all_workers` |
| Preview deployments for **all Workers** | [Protect all Workers](#protect-all-workers) | `all_preview_workers` |
| Production and preview deployments for **one Worker** | [Protect one Worker](#protect-one-worker) | `worker` |
| Preview deployments for **one Worker** | [Protect one Worker](#protect-one-worker) | `preview_worker` |
| One `workers.dev` hostname, Custom Domain, subdomain, or path | [Protect one hostname, Custom Domain, or path](#protect-one-hostname-custom-domain-or-path) | Self-hosted application domain |

## Protect all Workers

Protect all Workers when every Worker should require sign-in by default. You can protect all production and preview deployments, or only preview deployments, across every Worker in the account.

<Tabs syncKey="dashPlusAPI">
<TabItem label="Dashboard">

Dashboard path: **Workers & Pages** overview page > **Protect all Workers**.

![Workers & Pages overview showing the Protect all Workers card above the Workers application list.](~/assets/images/workers/access/protect-all-workers-card.png)

<Steps>
1. In the Cloudflare dashboard, go to the **Workers & Pages** page.

<DashButton url="/?to=/:account/workers-and-pages" />

2. Find the **Protect all Workers** card.
3. If the card says **Not enabled**, select **Enable Access**.
4. Choose **Production & Previews** or **Previews**.
5. Under **Authentication policy**, select an existing policy or configure one of the [policy options](#policy-options).
6. Select **Enable Access**.
</Steps>

</TabItem>
<TabItem label="API">

Create a self-hosted Access application with an `all_workers` destination to require sign-in for every Worker's production and preview deployments:

```json
"destinations": [
{
"type": "all_workers"
}
]
```

To protect only preview deployments for every Worker, use `all_preview_workers` instead:

```json
"destinations": [
{
"type": "all_preview_workers"
}
]
```

Send these `destinations` in a `POST /accounts/{account_id}/access/apps` request. For the full request schema, including [policy options](#policy-options), session settings, and advanced Access options, refer to the [Access applications API](/api/resources/zero_trust/subresources/access/subresources/applications/methods/create/).

</TabItem>
</Tabs>

## Protect one Worker

Protect one Worker when a single Worker should require sign-in. Protection follows the Worker by its ID across all of the Worker's routes, Custom Domains, `workers.dev` hostname, and previews.

<Tabs syncKey="dashPlusAPI">
<TabItem label="Dashboard">

Dashboard path: **Workers & Pages** > select your Worker > **Access**.

![Worker Access tab showing an unprotected Worker and the Protect this Worker behind Access button.](~/assets/images/workers/access/worker-access-tab-unprotected.png)

<Steps>
1. In the Cloudflare dashboard, go to the **Workers & Pages** page.

<DashButton url="/?to=/:account/workers-and-pages" />

2. Select your Worker from the application list.
3. Select the **Access** tab.
4. Select **Protect this Worker behind Access**.
5. Choose **Production & Previews** or **Previews**.
6. Under **Authentication policy**, select an existing policy or configure one of the [policy options](#policy-options).
7. (Optional) Review the session duration.
8. Select **Apply Access**.
</Steps>

</TabItem>
<TabItem label="API">

Create a self-hosted Access application with a `worker` destination to require sign-in for one Worker's production and preview deployments. Pass the immutable Worker ID as `worker_id` — this is the Worker tag from the Workers scripts API, or the Worker `id` from the Workers beta API.

```bash
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps" \
--request POST \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--json '{
"type": "self_hosted",
"name": "Access for my-worker",
"destinations": [
{
"type": "worker",
"worker_id": "c81a2d22c29840ed9d61681a3270dbff"
}
],
"policies": [
{
"decision": "allow",
"include": [
{
"email_domain": {
"domain": "example.com"
}
}
]
}
]
}'
```

To protect only preview deployments for that Worker, use `preview_worker` instead:

```json
"destinations": [
{
"type": "preview_worker",
"worker_id": "c81a2d22c29840ed9d61681a3270dbff"
}
]
```

For the full request schema, including [policy options](#policy-options) and session settings, refer to the [Access applications API](/api/resources/zero_trust/subresources/access/subresources/applications/methods/create/).

</TabItem>
</Tabs>

## Protect one hostname, Custom Domain, or path

Use hostname-based Access when only a specific URL that routes to your Worker should require sign-in, such as a `workers.dev` hostname, a Custom Domain, a subdomain, or a path. Hostname-based Access protects only that exact URL, whereas [protecting a Worker](#protect-one-worker) protects the entire Worker. For example, you can protect `my-worker.example.workers.dev`, `admin.example.com`, or a single path such as `example.com/login` to make only part of your Worker private.

In both the dashboard and the API, you protect a hostname or path by creating a [self-hosted application](/cloudflare-one/access-controls/applications/http-apps/self-hosted-public-app/) and using the hostname or path as the application domain.

<Tabs syncKey="dashPlusAPI">
<TabItem label="Dashboard">

Create the self-hosted application in **Zero Trust** > **Access** > **Applications**. To match subdomains, multiple paths, or wildcards, refer to [Application paths](/cloudflare-one/access-controls/policies/app-paths/).

</TabItem>
<TabItem label="API">

Create the self-hosted application with a `POST /accounts/{account_id}/access/apps` request, setting the application domain to the hostname or path. For the full request schema, refer to the [Access applications API](/api/resources/zero_trust/subresources/access/subresources/applications/methods/create/).

</TabItem>
</Tabs>

## Make a Worker public when all Workers are protected

If account-level Access protects all Workers, you can make a specific Worker public by adding a Worker-level bypass. A bypass means Access does not require sign-in for that Worker.

:::note
This is only useful when account-level Access already protects the Worker. If there is no account-level Access policy, a public Worker does not need a bypass.
:::

<Tabs syncKey="dashPlusAPI">
<TabItem label="Dashboard">

Dashboard path: **Workers & Pages** > select your Worker > **Access**.

![Manage Worker access dialog showing a Make this Worker public bypass policy.](~/assets/images/workers/access/worker-level-bypass-public.png)

<Steps>
1. In the Cloudflare dashboard, go to the **Workers & Pages** page.

<DashButton url="/?to=/:account/workers-and-pages" />

2. Select your Worker from the application list.
3. Select the **Access** tab.
4. Select the option to make the Worker public or bypass account-level Access.
5. Confirm the change.
</Steps>

</TabItem>
<TabItem label="API">

Create a more specific Worker-level Access app with a bypass policy. Use the `worker` destination, set `worker_id` to the Worker's immutable ID, and set the policy `decision` to `bypass`.

</TabItem>
</Tabs>

## Policy options

When you turn on Access, choose who can sign in. The same policy options are available whether you protect all Workers or one Worker.

| Policy option | Result |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Cloudflare account | Allows members of this Cloudflare account to sign in. Use this option when access should be limited to people who already belong to the account. |
| Email domain | Allows anyone with a verified email address at the domain you enter, such as `example.com`. Use this option when access should be available to people from a company or organization, even if they are not Cloudflare account members. |

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](/cloudflare-one/access-controls/policies/).

## Disable Access

<Tabs syncKey="dashPlusAPI">
<TabItem label="Dashboard">

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.

</TabItem>
<TabItem label="API">

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

</TabItem>
</Tabs>

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

## Related resources

- [Access applications API](/api/resources/zero_trust/subresources/access/subresources/applications/methods/create/)
- [Access policies](/cloudflare-one/access-controls/policies/)
- [Self-hosted Access applications](/cloudflare-one/access-controls/applications/http-apps/self-hosted-public-app/)
- [Routes and domains](/workers/configuration/routing/)
- [Preview URLs](/workers/configuration/previews/)
14 changes: 4 additions & 10 deletions src/content/docs/workers/configuration/previews.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,13 @@ The resulting alias would be associated with this version, and immediately avail

## Manage access to Preview URLs

When enabled, all preview URLs are available publicly. You can use [Cloudflare Access](/cloudflare-one/access-controls/policies/) to require visitors to authenticate before accessing preview URLs. You can limit access to yourself, your teammates, your organization, or anyone else you specify in your [access policy](/cloudflare-one/access-controls/policies/).
When enabled, Preview URLs are available publicly. To require visitors to sign in before they can access Preview URLs, use [Cloudflare Access](/workers/configuration/cloudflare-access/).

To limit your preview URLs to authorized emails only:
Access can protect previews for one Worker or every Worker in an account. You can also protect both production and preview deployments.

1. In the Cloudflare dashboard, go to the **Workers & Pages** page.

<DashButton url="/?to=/:account/workers-and-pages" />
For defense in depth, [validate the Access JWT](/cloudflare-one/access-controls/applications/http-apps/authorization-cookie/validating-json/#cloudflare-workers-example) in your Worker code so unauthenticated requests cannot reach your application if Access is ever removed or misconfigured.

2. In **Overview**, select your Worker.
3. Go to **Settings** > **Domains & Routes**.
4. For Preview URLs, click **Enable Cloudflare Access**.
5. Optionally, to configure the Access application, click **Manage Cloudflare Access**. There, you can change the email addresses you want to authorize. View [Access policies](/cloudflare-one/access-controls/policies/#selectors) to learn about configuring alternate rules.
6. [Validate the Access JWT](https://developers.cloudflare.com/cloudflare-one/access-controls/applications/http-apps/authorization-cookie/validating-json/#cloudflare-workers-example) in your Worker script using the audience (`aud`) tag and JWKs URL provided.
To use details about the signed-in user in your Worker, read the [user's identity](/cloudflare-one/access-controls/applications/http-apps/authorization-cookie/application-token/#user-identity) from the validated JWT or the `/cdn-cgi/access/get-identity` endpoint.

## Toggle Preview URLs (Enable or Disable)

Expand Down
Loading