Cloudflare Zero Trust, part of the product family Cloudflare calls Cloudflare One, replaces the corporate VPN and the office web proxy with policies enforced at Cloudflare's edge. A client on each device sends traffic to the nearest Cloudflare data centre; there, the Gateway service filters DNS, network and HTTP traffic, Access decides who may reach internal applications, and Cloudflare Tunnel carries permitted traffic to private networks that have no inbound ports open.
This site already covers two parts in depth: Cloudflare Access for application policies and Cloudflare Tunnels for the connector. This article is about the platform as a whole, seen from the device: how traffic gets in, the order in which Gateway evaluates policies, TLS inspection, device posture, split tunnels and private routing, and the operational failures that hit real rollouts. Product names and behaviour were checked against Cloudflare's documentation in October 2026; plans and prices are not covered because they change.
The components
| Component | What it does | Where it runs |
|---|---|---|
| Cloudflare One Client (formerly WARP) | sends device traffic and DNS to Cloudflare, reports posture | endpoint |
| Gateway | DNS, network and HTTP filtering, TLS inspection, egress control | Cloudflare edge |
| Access | identity- and posture-aware decisions for applications | Cloudflare edge |
| Tunnel | outbound-only connector from private networks to the edge | your network |
| Device posture | checks such as OS version, disk encryption, required apps | client plus edge |
| Browser Isolation, DLP, CASB | optional controls layered on Gateway | Cloudflare edge |
The model is that every decision happens at the edge, close to the user, and that the same identity and posture signals feed every policy. A contractor on an unmanaged laptop and an engineer on a managed one reach the same edge, but the policies they meet differ because the inputs differ. For the vendor-neutral version of this model, see cloud zero trust in depth.
How traffic flows
A device enrols into your organisation by signing in through your identity provider, subject to device enrolment rules you define, for example only users in a given email domain or group. From then on the client, in its default Traffic and DNS mode, routes the device's traffic (all ports and protocols by default) and DNS queries to Cloudflare. DNS is answered by Gateway's resolver, which applies DNS policies. Connections are then subject to network policies at layer 4 and, if the traffic is HTTP and inspection applies, to HTTP policies at layer 7.
If the destination is public, Gateway forwards it to the internet from Cloudflare's network. If it is a private IP or hostname that you have routed through a tunnel, it travels to the cloudflared connector inside your network and on to the server. The server sees connections from the connector, not from the user's laptop, which is why application logs need the identity headers or Gateway logs to attribute activity.
Gateway policy evaluation order
Gateway policy types are evaluated in a fixed sequence: DNS policies that use pre-resolution selectors, resolver policies, DNS policies that use post-resolution selectors (such as the resolved IP), egress policies, network policies and finally HTTP policies. Resolver and egress policies are Enterprise features. Within a type, policies run in ascending precedence order and the first Allow or Block match stops evaluation.
HTTP policies add a twist: they are grouped by action before precedence applies. All Do Not Inspect policies run first, then Isolate policies, then Allow, Block and Do Not Scan, then request-body inspection such as DLP and antivirus. A site matching a Do Not Inspect policy is allowed through and skips every other HTTP policy, so a broad Do Not Inspect rule silently disables your HTTP blocks for those hosts, regardless of where it sits in the list.
Access is separate. If traffic goes to a private IP protected by an Access application, Access policies still apply even when a Gateway Allow matched first. A Gateway Block ends evaluation; a Gateway Allow never overrides Access. Debugging a denied request therefore means checking both Gateway activity logs and Access logs.
| Order | Policy type | Typical use |
|---|---|---|
| 1 | DNS (pre-resolution) | block categories, malware and newly seen domains |
| 2 | Resolver (Enterprise) | send internal zones to your own DNS servers |
| 3 | DNS (post-resolution) | decisions based on the resolved IP |
| 4 | Egress (Enterprise) | fixed source IPs for allow-listed SaaS |
| 5 | Network | ports, protocols and private CIDRs by group |
| 6 | HTTP | URL rules, TLS inspection exceptions, isolation, DLP |
TLS inspection and device posture
HTTP policies on HTTPS traffic need TLS inspection: Gateway terminates the TLS connection, applies policy to the decrypted request and re-encrypts towards the origin. Devices must trust the certificate Gateway presents, which means deploying a Cloudflare-provided or your own root certificate through MDM before turning inspection on. Applications that pin certificates, many developer tools with their own trust stores, and some banking and health sites will break or must be excluded. Exclusions are Do Not Inspect policies, and because those win over everything else in HTTP, keep them narrow: a hostname list, not a category. The TLS mechanics are covered in TLS 1.3 internals.
Device posture adds the second signal. The client reports checks such as OS version, disk encryption and the presence of specific applications, and integrations can import signals from endpoint tools. Posture checks are used as selectors in both Gateway and Access policies, so you can allow SSH to production only from devices with disk encryption and a current OS, and fall back to an isolated browser session for everything else.
Split tunnels and private DNS
Split tunnels decide which traffic the client sends to Cloudflare. In Exclude mode, the default, everything goes through except listed ranges and domains; in Include mode only listed ranges go through. The default Exclude list contains local and special ranges, including 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 and 100.64.0.0/10. That default is the most common reason a new private-network rollout fails: you publish 10.20.0.0/16 through a tunnel, but the client never sends those packets to Cloudflare because 10.0.0.0/8 is excluded. Remove the range, or replace it with narrower exclusions that skip only the corporate CIDR. In Include mode you must also include your identity provider, team domain and protected applications so sign-in works.
DNS needs the same care. Internal names with no public record must be resolved by your own DNS servers, which is what Local Domain Fallback configures: domains listed there are sent to the resolvers you name instead of Gateway, and are therefore not subject to Gateway DNS policies. Resolver policies are the Enterprise alternative that keeps resolution under policy.
Policies as code
Policies are configured in the dashboard, the API or Terraform. Through the API, a Gateway rule is created with POST /accounts/{account_id}/gateway/rules. The body names an action such as block, allow or isolate, a filter type (dns, l4, http, egress or dns_resolver), wirefilter expressions in traffic, identity and device_posture, and a precedence where lower runs first.
import os, requests
API = "https://api.cloudflare.com/client/v4"
ACCOUNT = os.environ["CF_ACCOUNT_ID"]
HEADERS = {"Authorization": f"Bearer {os.environ['CF_API_TOKEN']}"}
rule = {
"name": "Allow SSH to prod for SRE on compliant devices",
"action": "allow",
"filters": ["l4"],
"enabled": True,
"precedence": 1000,
# Build each expression in the dashboard first and copy the generated text:
"traffic": "net.dst.ip in {10.20.0.0/16} and net.dst.port == 22",
"identity": 'any(identity.groups.name[*] in {"sre"})',
"device_posture": 'any(device_posture.checks.passed[*] in {"<disk-encryption-check-id>"})',
}
r = requests.post(f"{API}/accounts/{ACCOUNT}/gateway/rules", json=rule, headers=HEADERS, timeout=30)
r.raise_for_status()
print(r.json()["result"]["id"])Two habits keep this manageable. Generate expressions in the dashboard's policy builder and copy them, because the API normalises expressions and hand-written ones drift from what it stores. And manage policies from version control so that precedence, the property that most often causes outages, is reviewed like code. Pair every Allow for a private range with an explicit Block below it so the default is deny for that range.
Worked example: replacing a VPN
A 300-person company wants to retire its VPN for an internal network at 10.20.0.0/16 with a wiki, a Git server and SSH to production. The rollout runs in stages. First, two cloudflared replicas run in the data centre and the tunnel publishes the private route. Second, the client is deployed by MDM with the Cloudflare root certificate, enrolment limited to the company identity provider, and 10.0.0.0/8 replaced in the Exclude list by narrower ranges that leave 10.20.0.0/16 routed through Cloudflare. Third, Local Domain Fallback sends corp.internal to the internal DNS servers.
Policies follow: a network Allow for HTTPS to the wiki and Git for all employees, an Allow for port 22 to production limited to the SRE group and to devices passing the disk-encryption check, and a Block for the rest of the range. DNS policies block security threat categories for everyone. A pilot group of twenty runs for two weeks with the VPN still available.
The pilot finds three problems. Home routers using 10.20.0.0/24 collide with the corporate range for two people, fixed by moving those routers. A build tool with its own trust store fails under inspection and gets a narrow Do Not Inspect rule by hostname. And one engineer's SSH is denied although Gateway allowed it: the production bastion also has an Access application whose policy did not include the SRE group, confirming that Gateway Allow does not override Access.
Failure modes
- Private routes never reach Cloudflare. The default Exclude list covers RFC 1918 space. Check the device's effective split tunnel list before debugging the tunnel.
- Overly broad Do Not Inspect. It runs before every other HTTP policy, so a category-wide rule turns off HTTP filtering for that category. Audit these first.
- Precedence mistakes. An early Allow shadows a later Block. Keep a deny-by-default rule at the end of each private range and test with real identities.
- Internal names resolve publicly or not at all. Missing Local Domain Fallback or resolver policies; check what Gateway logged for the query.
- Users disabling the client. Use device settings that prevent switching it off on managed devices, and require posture checks so a disconnected device loses access.
- Captive portals and conflicting VPNs. Hotel Wi-Fi sign-in pages and other VPN clients interfere with the tunnel; document the portal behaviour and exclude other VPNs' ranges deliberately.
Trade-offs
Moving enforcement to Cloudflare's edge removes VPN concentrators and inbound firewall holes, and puts DNS, web and private-app policy in one place with one log stream. The price is dependence on one provider for both security and connectivity, TLS inspection with its privacy and compatibility costs, and an endpoint agent that must be deployed and kept healthy. Plan for an outage path for break-glass administrative access that does not depend on the same platform.
Observability is the other half of the trade. Gateway records DNS, network and HTTP activity with the matched policy, user and device, and Access records its own decisions. Export both to your log platform rather than relying on the dashboard, keep the policy ID in every alert, and build one query that answers the support question everyone asks: which rule blocked this user, on this device, at this time.
Start with DNS filtering, which is low-risk and immediately useful, then private access for a few applications, then HTTP inspection, which has the most compatibility work. Each stage stands on its own, so you can stop at any of them.
What to do next
- Inventory what the VPN is actually used for: CIDRs, ports, hostnames and groups.
- Enrol a pilot group with enrolment rules tied to your identity provider.
- Turn on DNS policies for security categories and watch the logs for a week.
- Deploy a tunnel with replicas and fix the split tunnel list for its private routes.
- Configure Local Domain Fallback or resolver policies for internal zones.
- Write network policies per application with a final Block for each private range.
- Add posture checks to sensitive policies and confirm denials for non-compliant devices.
- Roll out the root certificate, then enable TLS inspection with narrow Do Not Inspect rules.
- Move policies into version control and review precedence changes like code.