CLOUDFLARE — SECURITY

CLOUDFLARE
ZERO TRUST

Never trust, always verify. Cloudflare Zero Trust replaces the corporate VPN with identity-aware, policy-driven access — for every user, device, and application, on any network.

Access Tunnel WARP Gateway Browser Isolation Free for <50 users Used by 2nth.ai
01

WHAT IS ZERO TRUST

Zero Trust is a security model, not a product. The principle: no user, device, or network location is trusted by default — even inside your own network. Every request for access must be authenticated, authorised, and continuously validated.

The traditional model assumes that anything inside the corporate network is safe. That assumption broke the moment teams went remote, started using SaaS, and attackers learned to move laterally after a single breach. The perimeter disappeared. Zero Trust acknowledges that and removes the concept of "inside" entirely.

Cloudflare Zero Trust is the implementation: a suite of five products that enforce Zero Trust principles at the network level, between users and applications, and between services and services — all running on Cloudflare's global network.

The core principle

Treat every access request as if it originates from an untrusted network. Verify identity. Enforce policy. Log everything. Assume breach.

02

WHY IT REPLACES VPN

TRADITIONAL VPN
  • Binary access — you're in or you're out
  • Full network access once connected
  • No per-application policies
  • Lateral movement after breach is trivial
  • Slow — all traffic hairpins through a central server
  • Painful to manage at scale
  • No device posture checks
  • Hard to audit who accessed what
CLOUDFLARE ZERO TRUST
  • Per-application, per-resource policies
  • Identity + device posture required every session
  • Breach is contained — no lateral movement
  • Traffic routes via nearest Cloudflare PoP (fast)
  • Works on any network, any device
  • Full audit log of every access event
  • Free for teams under 50 users
  • Integrates with any IdP (Google, Okta, GitHub, etc.)
03

THE 5 COMPONENTS

Cloudflare Zero Trust is five products that work together. You can deploy them independently or as a suite.

ACCESS
Application gateway + SSO

Sits in front of your apps. Every request goes through Cloudflare. Access checks identity and policy before passing the request on.

TUNNEL
Secure inbound connector

A daemon running on your server that creates an outbound-only encrypted tunnel to Cloudflare. No open inbound ports. No public IP needed.

WARP
Device agent

Client installed on user devices. Routes device traffic through Cloudflare. Enables device posture checks and private network access.

GATEWAY
DNS + HTTP filtering

Cloudflare's Secure Web Gateway. Filters DNS queries and HTTP traffic. Blocks malware, phishing, and content categories. Full inspection.

BROWSER ISOLATION
Remote browser

Runs the browser in Cloudflare's network. Nothing executes on the user device. Protects against malicious web content and data exfiltration.

04

ACCESS — APPLICATION GATEWAY

Cloudflare Access is the front door for every application you want to protect. Instead of putting a login form on the app itself, Access intercepts every request and checks identity and policy before the request reaches your app.

The user experience: hit a protected URL → Cloudflare redirects to your IdP (Google, GitHub, Okta, etc.) → user authenticates → Cloudflare issues a signed JWT → app receives the request with the JWT as proof of identity.

How it works

Access request flow
Userany network
Cloudflare EdgeAccess policy check
IdPGoogle / GitHub / Okta
JWT issuedsigned by CF
Appreceives request + JWT

Policy rules

Access policies define who can reach what. Rules can be based on:

  • Emailcraig@2nth.ai or *@2nth.ai
  • Identity provider groups — GitHub org, Google Workspace group
  • Country — allow ZA, block specific regions
  • Device posture — require WARP, check OS version, require disk encryption
  • mTLS certificate — for machine-to-machine service access

Self-hosted vs SaaS applications

TypeWhat it protectsHow
Self-hostedApps on your own infrastructure (admin panels, internal tools, APIs)Combine with Cloudflare Tunnel — no public IP needed
SaaSThird-party apps that support SAML/OIDC (Jira, Notion, GitHub)Access acts as IdP proxy — enforces additional policy before SSO
SSH / RDPServer access via browserAccess renders SSH in browser — no client needed

Validating the JWT in your app

Once Access is in front of your app, every request carries a Cf-Access-Jwt-Assertion header. You should validate it to prevent bypassing Access by hitting your origin directly.

// Cloudflare Worker — validate Access JWT
import { jwtVerify, importX509 } from 'jose';

const TEAM_DOMAIN = 'https://your-team.cloudflareaccess.com';
const CERTS_URL = `${TEAM_DOMAIN}/cdn-cgi/access/certs`;

export async function validateAccessJWT(request: Request): Promise<boolean> {
  const token = request.headers.get('Cf-Access-Jwt-Assertion');
  if (!token) return false;

  // Fetch public keys from Cloudflare
  const certsRes = await fetch(CERTS_URL);
  const { public_cert } = await certsRes.json() as any;

  try {
    const key = await importX509(public_cert, 'RS256');
    await jwtVerify(token, key, { issuer: TEAM_DOMAIN });
    return true;
  } catch {
    return false;
  }
}
05

TUNNEL — SECURE INBOUND CONNECTOR

Cloudflare Tunnel (formerly Argo Tunnel) solves a fundamental problem: how do you expose a service to the internet without opening inbound firewall ports or having a public IP address?

The answer: run cloudflared on your server. It creates an outbound-only encrypted connection to Cloudflare's nearest data centre. Traffic flows in through Cloudflare, down the tunnel to your service. The internet never touches your server directly.

Tunnel architecture

How Tunnel routes traffic
Internetuser request
Cloudflare EdgeDNS → proxied
Tunnelencrypted outbound
cloudflaredon your server
localhost:3000your app
Key security property

No inbound ports open. No public IP required. Your server firewall can drop all incoming connections. The only traffic that reaches your app came through Cloudflare.

Setup

# Install cloudflared
brew install cloudflare/cloudflare/cloudflared  # macOS
# or download from https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/

# Authenticate
cloudflared tunnel login

# Create a named tunnel
cloudflared tunnel create my-app

# Create config file (~/.cloudflared/config.yml)
tunnel: <TUNNEL-ID>
credentials-file: /home/user/.cloudflared/<TUNNEL-ID>.json

ingress:
  - hostname: app.example.com
    service: http://localhost:3000
  - hostname: api.example.com
    service: http://localhost:8787
  - service: http_status:404

# Add DNS record (proxied CNAME to <tunnel-id>.cfargotunnel.com)
cloudflared tunnel route dns my-app app.example.com

# Run the tunnel
cloudflared tunnel run my-app

# Or run as a system service
cloudflared service install

Using Tunnel with Access

Tunnel + Access is the standard pattern for protecting internal apps without a VPN:

  1. Tunnel exposes your app at app.example.com through Cloudflare
  2. Access policy sits in front — only authenticated users matching the policy reach the tunnel
  3. Your server sees only traffic that already passed the Access check
  4. Close all inbound firewall ports entirely
06

WARP — DEVICE AGENT

WARP is the client application installed on user devices (Mac, Windows, iOS, Android, Linux). It routes device traffic through Cloudflare's network and is the enforcement point for device posture policies.

For Zero Trust, WARP does two things: (1) it identifies the device to Cloudflare so Access policies can include device posture rules, and (2) it routes traffic through Gateway for DNS and HTTP filtering.

WARP modes

ModeWhat it doesUse case
WARPRoutes all traffic through Cloudflare. DNS + HTTP filtering active.Endpoint protection for team devices
Gateway with WARPEnables Gateway policies and device posture checksRequired for ZT Access device posture rules
Proxy modeRoutes only traffic bound for private networksAccessing internal apps without full traffic routing

Device posture checks

Once WARP is deployed, Access policies can require device health checks before granting access:

  • WARP running — device must have WARP active
  • OS version — macOS 14+, Windows 11+
  • Disk encryption — FileVault / BitLocker enabled
  • Application running — e.g. require CrowdStrike or Sentinel
  • Domain joined — device registered with your organisation's directory
# Deploy WARP via MDM (example: Jamf)
# Set the organisation name to your Zero Trust team name
# Users get WARP pre-configured — just needs authentication on first launch

# Or manually:
# 1. Install WARP from cloudflare.com/warp
# 2. Click Preferences → Account → Login with Cloudflare Zero Trust
# 3. Enter team name (your-team.cloudflareaccess.com)
07

GATEWAY — DNS & HTTP FILTERING

Cloudflare Gateway is the Secure Web Gateway (SWG) component. It sits between your users and the internet, inspecting DNS queries and HTTP/S traffic, applying filtering policies, and logging everything.

DNS filtering

All DNS queries from WARP-enrolled devices go through Cloudflare's resolver. Gateway can block queries based on:

  • Categories (malware, phishing, adult content, social media)
  • Domain lists (custom blocklists)
  • Security intelligence (Cloudflare's threat feeds)
  • New domains (flag domains registered in the last 30 days)

HTTP filtering

Gateway can perform full TLS inspection, enabling policy enforcement on HTTPS traffic:

  • Block file uploads to unauthorised cloud storage
  • Prevent data exfiltration via HTTP POST
  • Enforce Safe Search on Google/Bing/YouTube
  • Block OAuth to unauthorised SaaS apps
Setup: DNS-only (no WARP needed)

Point your DNS resolver to 1.1.1.1 using your Gateway DoH/DoT endpoint: https://<team>.cloudflareaccess.com/dns-query. Instant filtering with no client software.

Resolver policies (example)

# Gateway DNS policy examples (configured in dashboard)

# Block known malware/phishing domains
IF Security Category = Malware OR Phishing
THEN Block

# Block social media during work hours (optional)
IF Category = Social Networks AND Time = 09:00-17:00
THEN Block

# Log all new/uncategorised domains
IF Domain Age < 30 days
THEN Log + Allow (review)

# Allow everything else
THEN Allow
08

BROWSER ISOLATION

Browser Isolation runs the web browser inside Cloudflare's network rather than on the user's device. The user sees a pixel stream of the browser — interactive but with no code executing locally.

This eliminates an entire class of attack: malicious JavaScript, drive-by downloads, browser exploits — none of them can reach the user's device because the browser isn't running there.

Use cases

  • Unmanaged device access — contractors using personal devices accessing corporate apps
  • Risky web categories — any URL matching a risky policy opens in isolated browser automatically
  • Data protection — copy/paste, download, and printing can be disabled for sensitive apps
  • Legacy browser support — old apps that require IE-era rendering
Isolation without inconvenience

For end users, an isolated browser looks and feels like a normal browser tab. The isolation is transparent — there's no separate app to open or noticeable latency for most content.

09

FULL ZERO TRUST ARCHITECTURE

How all five components work together in a complete deployment:

Complete Zero Trust stack
┌─────────────────────────────────────────────────────┐
│ CLOUDFLARE EDGE (330+ PoPs) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │
│ │ GATEWAY │ │ ACCESS │ │ ISOLATION │ │
│ │ DNS/HTTP │ │ App proxy │ │ Browser │ │
│ │ filtering │ │ + policy │ │ sandbox │ │
│ └──────┬──────┘ └──────┬──────┘ └───────────┘ │
└─────────┼───────────────┼─────────────────────────────┘
↓ DNS queries ↓ App requests
┌──────────────────────────────────────────────────┐
│ PRIVATE NETWORK │
│ │
│ ┌─────────────────┐ ┌──────────────────────┐ │
│ │ cloudflared │ │ Internal services │ │
│ │ (Tunnel) │──▶│ localhost:3000 │ │
│ │ no open ports │ │ no public IP │ │
│ └─────────────────┘ └──────────────────────┘ │
└──────────────────────────────────────────────────┘
User devices running WARP → routes to Gateway → posture checked → Access policies enforced
10

HOW 2NTH.AI USES ZERO TRUST

2nth.ai runs its admin infrastructure behind Cloudflare Zero Trust. Here's the current and planned deployment:

ResourceProtectionPolicy
Admin API routesAccess policy on /admin/*Email in @2nth.ai, @imbila.ai, or @b2bs.co.za
bill.2nth.ai admin viewRole check in Worker sessionAdmin email list from env var — moving to Access policy
Wrangler / CF API accessAPI tokens with scoped permissionsSeparate token per project, minimum required scopes
Client portals (planned)Access per-client subdomainPer-client email domain + WARP device posture
Internal tooling (planned)Tunnel + AccessNo public IP, identity gate for every tool
The operator model

Zero Trust is how one operator secures infrastructure that would normally need a dedicated security team. No VPN to manage. No firewall rules to maintain. Policy-as-config in the Cloudflare dashboard.

11

SETUP GUIDE

Getting a basic Access + Tunnel deployment running from scratch.

Step 1 — Create a Zero Trust organisation

  1. Go to dash.cloudflare.com → Zero Trust (left sidebar)
  2. Choose a team name (e.g. 2nth → your apps will be at *.cloudflareaccess.com)
  3. Select the Free plan (up to 50 users, no credit card)

Step 2 — Connect an identity provider

# In Zero Trust dashboard → Settings → Authentication → Add new IdP

# Google Workspace
# 1. Create OAuth2 app in Google Cloud Console
# 2. Authorised redirect URI: https://<team>.cloudflareaccess.com/cdn-cgi/access/callback
# 3. Add Client ID + Secret to Cloudflare

# GitHub (good for dev teams)
# 1. Create OAuth app in GitHub → Settings → Developer settings
# 2. Homepage: https://<team>.cloudflareaccess.com
# 3. Callback: https://<team>.cloudflareaccess.com/cdn-cgi/access/callback

# One-time PIN (no IdP needed — email OTP)
# Built-in, no setup required — good for testing

Step 3 — Create an Access application

# Zero Trust → Access → Applications → Add an application

Type: Self-hosted
Application name: 2nth Admin
Subdomain: admin  (→ admin.2nth.ai)
Session duration: 24 hours

# Add a policy
Policy name: 2nth team
Action: Allow
Include: Email ends in @2nth.ai OR @imbila.ai

Step 4 — Create a Tunnel

# Install cloudflared
brew install cloudflare/cloudflare/cloudflared

# Login
cloudflared tunnel login

# Create tunnel
cloudflared tunnel create 2nth-admin

# Create ~/.cloudflared/config.yml
tunnel: <your-tunnel-id>
credentials-file: /Users/you/.cloudflared/<tunnel-id>.json

ingress:
  - hostname: admin.2nth.ai
    service: http://localhost:8788   # your local admin server
  - service: http_status:404

# Route DNS
cloudflared tunnel route dns 2nth-admin admin.2nth.ai

# Run
cloudflared tunnel run 2nth-admin

Step 5 — Verify

  1. Visit admin.2nth.ai in a browser
  2. Cloudflare Access redirects you to your IdP login
  3. After login, Access issues a JWT and passes the request to your tunnel
  4. Your local service handles the request — never exposed publicly
12

POLICY PATTERNS

Common policy configurations for 2nth-style operator deployments:

PatternRuleWhen to use
Email domain allowEmail ends in @yourcompany.comTeam-wide access to internal tools
Specific emailsEmail in [list]Tightly scoped admin access
Country blockCountry NOT in [ZA, GB, US]Geo-restrict sensitive apps
Device posture requiredWARP enrolled + OS version ≥ XHigh-security apps requiring managed devices
IdP groupGitHub org = imbilaworkGrant access to all org members
Bypass (no auth)IP in [known CIDRs]Server-to-server calls that don't carry a user token
Service tokenService token = [token]Machine-to-machine API calls through Access
13

mTLS AND SERVICE TOKENS

For machine-to-machine communication — where there's no user to authenticate — Zero Trust uses either mutual TLS (mTLS) or service tokens.

Service tokens

A service token is a Client ID + Client Secret pair. The calling service includes these as headers. Access validates them and passes the request.

# Calling a Zero Trust protected API from a Worker
const response = await fetch('https://internal-api.example.com/data', {
  headers: {
    'CF-Access-Client-Id': env.CF_ACCESS_CLIENT_ID,
    'CF-Access-Client-Secret': env.CF_ACCESS_CLIENT_SECRET,
  }
});

# In Access policy:
# Action: Service Auth
# Include: Service Token = [your token name]

mTLS

mTLS requires both sides of a connection to present a certificate. Cloudflare can validate client certificates before passing requests to your origin — useful for IoT devices, embedded hardware, and B2B API integrations where you control both ends.

# Upload your CA certificate to Cloudflare
# (Settings → mTLS → Upload Certificate Authority)

# In Access policy or WAF rule:
# Require: client certificate issued by your CA
# This blocks any request that doesn't present a valid cert — regardless of other auth
14

PRICING

PlanUsersCostWhat you get
FreeUp to 50$0Access, Tunnel, WARP, Gateway DNS filtering, basic policies
Pay-as-you-go51+$3/user/monthAll Free features + HTTP filtering, Browser Isolation (add-on), more policy types
Zero Trust EnterpriseUnlimitedCustomFull Browser Isolation, DLP, CASB, Remote Network, Priority support
For 2nth operators

The Free plan handles all operator-scale infrastructure. 50 users is enough for a 2nth team + client portal access. You hit pay-as-you-go only when running client environments at scale — and at $3/user/month, it's cheaper than any alternative.