Access (Zero Trust Access Control)
By the end of this lesson you will understand how Cloudflare Access provides VPN-less authentication for your internal apps, how to set up access policies, and what's included in the free tier.
What Is Cloudflare Access?
Cloudflare Access is an identity-aware proxy that sits in front of your applications and enforces who can access them. Instead of using a VPN, users authenticate through their identity provider (Google, GitHub, email OTP, etc.) and Cloudflare grants or denies access per-application.
flowchart LR
USER["User\n(Browser)"] -->|"Request to\napp.example.com"| CF["Cloudflare\nAccess Proxy"]
CF -->|"Authenticate?"| IDP{"Identity\nProvider"}
IDP -->|"✅ Verified"| APP["Internal App\n(via Tunnel)"]
IDP -->|"❌ Denied"| BLOCK["Access Denied"]
style CF fill:#f6821f,color:#fff,stroke:#e5711e
style IDP fill:#7c3aed,color:#fff,stroke:#6d28d9
style BLOCK fill:#dc2626,color:#fff,stroke:#b91c1c
Free Tier
| Feature | Free (up to 50 users) |
|---|---|
| Users | 50 |
| Applications | Unlimited |
| Identity providers | Google, GitHub, Email OTP, and more |
| Access policies | Unlimited |
| Service tokens | ✅ |
| Session duration | Configurable |
Setting Up Access
Step 1: Create a Zero Trust Organization
- Go to one.dash.cloudflare.com
- Create a team name (this becomes your auth domain:
<team>.cloudflareaccess.com)
Step 2: Add an Identity Provider
Navigate to Settings → Authentication → Login methods and add a provider:
| Provider | Type | Setup Complexity |
|---|---|---|
| One-time PIN (Email) | Email-based OTP | None — built-in |
| OAuth | Create a Google OAuth app | |
| GitHub | OAuth | Create a GitHub OAuth app |
| Microsoft / Azure AD | OIDC/SAML | Create an Azure AD app registration |
| Okta | OIDC/SAML | Configure in Okta admin |
Start with One-time PIN — it requires zero setup. Users enter their email, receive a code, and authenticate. You can add other providers later.
Step 3: Create an Access Application
- Go to Access → Applications → Add an Application
- Choose Self-hosted
- Configure:
- Application name: e.g., "Grafana"
- Session duration: e.g., 24 hours
- Application domain:
grafana.example.com
Step 4: Define an Access Policy
| Setting | Example |
|---|---|
| Policy name | "Allow Team" |
| Action | Allow |
| Include rule | Emails ending in @yourcompany.com |
You can stack multiple rules:
| Rule Type | Example | Description |
|---|---|---|
user@example.com | Allow a specific email address | |
| Email domain | @company.com | Allow anyone with a company email |
| GitHub org | my-org | Allow members of a GitHub organization |
| IP range | 203.0.113.0/24 | Allow from specific IPs |
| Country | US, UK | Allow from specific countries |
| Everyone | — | Allow all (useful with require rules) |
How It Works in Practice
Once configured, visiting grafana.example.com:
- Cloudflare intercepts the request
- Checks for a valid Access session cookie
- If no cookie → redirect to the login page (
<team>.cloudflareaccess.com) - User authenticates with their identity provider
- Cloudflare issues a signed JWT (session cookie)
- User is redirected to the application
- Subsequent requests use the session cookie (no re-authentication until session expires)
sequenceDiagram
participant User
participant Access as Cloudflare Access
participant IdP as Identity Provider
participant App as Internal App
User->>Access: Visit app.example.com
Access->>User: Redirect to login page
User->>IdP: Authenticate (Google, GitHub, email OTP)
IdP-->>Access: Identity verified
Access-->>User: Set session cookie (JWT)
User->>Access: Request with session cookie
Access->>App: Forward request (authenticated)
App-->>User: Application response
Service Tokens (for Automated Access)
For automated systems (CI/CD, monitoring, cron jobs) that need to access protected applications, use Service Tokens instead of identity provider authentication:
- Go to Access → Service Auth → Service Tokens
- Create a token — you receive a Client ID and Client Secret
- Include these headers in your automated requests:
curl -H "CF-Access-Client-Id: <client-id>" \
-H "CF-Access-Client-Secret: <client-secret>" \
https://app.example.com/api/status
Common Misconceptions
"Access requires a paid plan"
Reality: Cloudflare Access is free for up to 50 users. This is enough for small teams, personal projects, and homelab setups.
"Access only works with Cloudflare Tunnel"
Reality: Access works with any application proxied through Cloudflare — tunneled or not. However, Tunnel + Access is the most secure combination because the origin is never directly accessible.
"Users need to install software"
Reality: Access works entirely through the browser. Users click a link, authenticate, and access the app. No client software is needed (unless you need TCP/SSH access, which requires WARP).
Key Takeaways
- Cloudflare Access provides VPN-less authentication for internal apps — free for 50 users.
- Supports multiple identity providers: Google, GitHub, Email OTP, and more.
- Policies control who can access each application based on email, domain, IP, or group membership.
- Service tokens enable automated/machine access to protected applications.
- Combine with Cloudflare Tunnel for the most secure setup (no open ports + authentication).
What's Next
- Continue to Gateway to learn about Cloudflare's Secure Web Gateway for DNS filtering.