cloudflare / cloudflare/cloudflare-docs

Cloudflare Tunnel: docs imply top-level originRequest.access applies to all ingress rules, but cloudflared silently ignores it

Open
#32,006 1 comment 0 reactions 2 assignees Claimed by @nikitacano View on GitHub
product:cloudflare-one stale
Dominant language
MDX
Stars
5.2k
Forks
16.7k
Avg merge
2d 6h
Merged PRs (30d)
337

Description

**Which pages are affected?**

- https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/do-more-with-tunnels/local-management/configuration-file/#origin-configuration
(source: `src/content/partials/cloudflare-one/tunnel/locally-managed/configuration-file.mdx`)
- https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/configure-tunnels/origin-parameters/#access-settings
(source: `src/content/partials/cloudflare-one/tunnel/origin-parameters.mdx`)

**What is wrong?**

The "Origin configuration" section teaches that a top-level `originRequest` block sets defaults for all ingress rules, and the `access` parameter page says to "add the following rule to `originRequest`" without qualifying where. Following the two pages together, a reasonable reading is that this protects every service behind the tunnel:

```yml
originRequest:
access:
required: true
teamName:
audTag:
-

ingress:
- hostname: app.example.com
service: http://localhost:8000
- service: http_status:404
```

In reality `cloudflared` silently ignores a top-level `access` block. The config validates, no warning is logged, and unauthenticated traffic is forwarded to the origin. The JWT validation middleware is only attached when the `access` block sits under an individual ingress rule: `validateIngress` in [`ingress/ingress.go`](https://github.com/cloudflare/cloudflared/blob/master/ingress/ingress.go) reads the raw per-rule `r.OriginRequest.Access`, not the merged defaults (the merge in `ingress/config.go` copies the top-level block, but its result is never consulted for middleware attachment).

Verified on `cloudflared` 2026.7.1 with an A/B test against the same hostname (no Access app on the hostname, so no JWT on any request): top-level block returned `200` from the origin; the identical block moved under the ingress rule returned `403` from `cloudflared`.

This is a known cloudflared behaviour: cloudflare/cloudflared#784 (open since 2022) reports it, and a maintainer described it as "largely intended" because Access rules are tied to hostnames. The docs have not been updated to match, which matters because the failure mode is a security control that users believe is active but is not (see also the last comment on that issue).

**Suggested fix**

1. In the configuration-file partial's "Origin configuration" section, note that `access` is an exception to top-level inheritance and must be set on each ingress rule.
2. In the origin-parameters partial's `access` section, state explicitly that the block must be placed under `originRequest` of each individual ingress rule, and that a top-level block is not enforced.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.