Client Area

Cloudflare Zero Trust and Access for Internal Apps

ByDomain India Team·DomainIndia Engineering
6 min read24 Apr 20264 views
# Cloudflare Zero Trust and Access for Internal Apps
TL;DR
Cloudflare Access puts a zero-trust gateway in front of your internal apps — admin panels, staging sites, internal dashboards. No VPN needed. Employees authenticate with Google Workspace / Microsoft 365 / OTP, and Cloudflare blocks everyone else at the edge. This guide covers the full setup for a DomainIndia-hosted app.
## Why Zero Trust for internal apps Traditional: admin panel at `admin.yourcompany.com` → protect with basic auth + IP whitelist. Problems: - Basic auth passwords leak - IP whitelist breaks when staff work from cafes - No audit trail of who accessed what - VPN for everyone is heavy and brittle Zero Trust: - Employees log in with SSO (Google, Microsoft, Okta) - Cloudflare verifies identity at the edge - Each app has its own policy (which users, from where, with MFA) - Every request logged - No passwords or shared secrets Free plan: up to 50 users free. Paid: $3-7/user/month. ## Architecture ``` Employee browser │ ▼ Cloudflare edge ◄── SSO provider (Google/Microsoft/Okta) │ ▼ (identity verified) DomainIndia origin (admin app, staging, internal tool) ``` Cloudflare inserts an `Authorization` header or JWT; your origin trusts it because the traffic arrives via Cloudflare Tunnel. ## Step 1 — Enable Cloudflare Zero Trust
1
Log in to Cloudflare dashboard
2
Zero Trust (in left sidebar) → click "Launch"
3
Choose team name (becomes team-name.cloudflareaccess.com)
4
Select "Free" plan (sufficient for most small teams)
## Step 2 — Add SSO provider Zero Trust → Settings → Authentication → Login methods → Add new. **Google Workspace:** - Create OAuth 2.0 credentials in Google Cloud Console - Add redirect URI shown by Cloudflare - Copy Client ID + Secret into Cloudflare **One-time PIN (no SSO):** - Simplest — users get emailed a code - Good for external contractors / partners ## Step 3 — Create an Access application Zero Trust → Access → Applications → Add application → Self-hosted. - Application name: `Admin Panel` - Subdomain: `admin` - Domain: `yourcompany.com` - Session duration: 24 hours **Policy:** - Action: Allow - Include: Emails ending in `@yourcompany.com` - Require: Authentication via Google Optional extra: - Require MFA (once Google provides it) - Include specific IPs (office network) - Require certain countries (block rest of world) ## Step 4 — Cloudflare Tunnel (recommended) Traditional: expose your origin to the internet + use Access to block. Better: Cloudflare Tunnel — origin makes outbound connection, never exposes a public port.
1
Zero Trust → Networks → Tunnels → Create tunnel
2
Name the tunnel
3
Copy the install command shown, run on your DomainIndia VPS:
4
Configure routes:
5
DNS auto-configures — no manual DNS record needed
Origin server (`localhost:3000`) never exposed to internet. Traffic exits only to Cloudflare. ## Step 5 — Verify origin identity Your app should only trust requests from Cloudflare Access. Two options: **Option A — `Cf-Access-Jwt-Assertion` header:** Cloudflare adds this JWT header to every authenticated request. Verify in your app: ```javascript import jwt from 'jsonwebtoken'; import jwksClient from 'jwks-rsa'; const client = jwksClient({ jwksUri: 'https://team-name.cloudflareaccess.com/cdn-cgi/access/certs', }); app.use(async (req, res, next) => { const token = req.headers['cf-access-jwt-assertion']; if (!token) return res.status(401).send('No access token'); const decoded = jwt.decode(token, { complete: true }); const key = await client.getSigningKey(decoded.header.kid); const payload = jwt.verify(token, key.getPublicKey(), { audience: 'YOUR_AUD', // shown in Access app settings issuer: 'https://team-name.cloudflareaccess.com', }); req.user = { email: payload.email, groups: payload.groups }; next(); }); ``` **Option B — `CF-Connecting-IP` whitelist:** Only accept requests from Cloudflare IP ranges. Simpler but less strong. See [Cloudflare IP list](https://www.cloudflare.com/ips/). ## Step 6 — Policies for fine-grained access Different rules for different apps: ``` Application: Production database console Policy: Allow Include: user is DBA role Require: MFA + India-only IP Session: 1 hour ``` ``` Application: Marketing CMS Policy: Allow Include: @yourcompany.com OR [email protected] Session: 8 hours ``` ``` Application: Staging site Policy: Allow Include: @yourcompany.com Bypass: from office IP 120.60.X.X Session: 24 hours ``` ## Step 7 — Logs and audit Zero Trust → Logs → Access shows: - Who accessed what, when, from where - Failed auth attempts (useful for threat detection) - MFA challenges Export to SIEM via Logpush (paid) or manually via API. ## Cloudflare WARP for outbound For fully zero-trust deploys, WARP agent on employee laptops forces all traffic through Cloudflare — including DNS queries. Adds malware filtering, DNS-based filtering of malicious sites, even from coffee-shop WiFi. ## Common patterns **Pattern 1: Protect Grafana / internal dashboards** Grafana → Tunnel (localhost:3000) → Access policy (admins only) → `grafana.yourcompany.com` No password on Grafana itself. Access is the gatekeeper. Grafana's `auth_proxy` module trusts the JWT identity. **Pattern 2: Partner extranet** External partners get invited via email. They sign in with one-time PIN. Policy restricts to specific URLs (`/partner/*`) only. Ticketing quick + no account provisioning burden. **Pattern 3: SSH via Access** Zero Trust can broker SSH connections too. Install `cloudflared access ssh` on laptops. No public SSH port needed on VPS. Every session auditable. ## Migration — from password-protected admin to Zero Trust
1
Set up Zero Trust + SSO (5 min)
2
Create Access application for admin panel (2 min)
3
Install cloudflared tunnel on VPS (5 min)
4
Update DNS to proxy through Cloudflare
5
Test with a test user
6
Remove basic auth from origin (now redundant)
7
Announce to team + share SSO login URL
Total migration: under 1 hour for a single app. ## Common pitfalls ## FAQ
Q Cost?

Free up to 50 users. Beyond that: $3/user/mo (teams up to 250) or $7/user/mo (unlimited + ZTNA features).

Q Zero Trust vs VPN?

Zero Trust is per-app authentication; VPN is network-level. Zero Trust is modern practice — narrower blast radius if a user is compromised.

Q Can I use Zero Trust with non-Cloudflare DNS?

You can use external DNS, but CF must proxy the traffic for policies to apply. Easier to move DNS to Cloudflare.

Q Does Tunnel slow my app?

Slightly (edge hop). 20-50ms added latency typical. For sub-100ms internal apps, acceptable.

Q Access with non-web protocols?

Access supports SSH, RDP, kubectl, databases via Cloudflare's Browser Isolation + WARP. Beyond scope of this article.

Front your DomainIndia internal apps with Cloudflare Zero Trust. See our hosting options

Was this article helpful?

Your feedback helps us improve our documentation

Still need help? Submit a support ticket