Sketio

Cloudflare Access Architecture for Internal Apps

Updated

Cloudflare Access puts a login in front of an application without a VPN. You register the app's hostname as an Access application, write policies that say who may reach it, and Access checks every request. The app itself can stay on a private network: Cloudflare Tunnel connects it to Cloudflare through an outbound-only connection, so no inbound port has to be open.

This template draws both halves, and the step teams most often leave until last: the app itself checking the token that Access sends with each request.

Your network: no inbound portsHTTPSTunnellocal URLEmployeeCloudflare AccessIdentity providercloudflaredInternal appAccess signing keysloginpublishesfetch keys

Scroll sideways to see the whole diagram

Cloudflare Access Architecture for Internal Apps. Open it in Sketio to change it.

Start from this diagram and edit it on your own board.

By continuing, you agree to the Terms of Service and Privacy Policy, including sending images of your strokes, diagram labels and similar data to providers in the United States (Cloudflare, Inc. and TypeSafe AI, Inc.) for AI conversion.

What each part does

Employee
Anyone who opens the app's hostname in a browser. Access treats them as unknown until they have logged in and matched a policy.
Cloudflare Access
Holds the Access application (the hostname it protects) and its policies. It checks every HTTP request for a valid application token and, when there is none, sends the user to log in. It is deny by default: a user must match an Allow policy to be let in. Session duration says how long the application token stays valid.
Identity provider
Where people prove who they are. Cloudflare supports SAML and OIDC providers and most OAuth providers, and it can also send a one-time PIN to approved email addresses. You choose which providers each application offers.
cloudflared
A small daemon that runs inside your network and makes outbound connections to Cloudflare. A tunnel is identified by a UUID, and each cloudflared process is a connector. You can run several connectors on one tunnel. Each published application route points a hostname at a local service address, for example http://localhost:8000.
Internal app
The web app or admin tool being protected. It never has to be reachable from the Internet. Each request arrives with the token in the Cf-Access-Jwt-Assertion header, and the app should validate it.
Access signing keys
The public keys that Access publishes at https://<team name>.cloudflareaccess.com/cdn-cgi/access/certs. The app fetches them from there instead of hard-coding one, and picks the key whose kid matches the kid in the token.

How a request flows

  1. An employee opens the app's hostname. The request reaches Cloudflare, where Access looks for a valid application token.
  2. With no token, Access sends the employee to log in: with your identity provider, or with a one-time PIN sent to an approved email address.
  3. Back at Access, the policies are evaluated. Access is deny by default, so the employee gets in only by matching an Allow policy. Evaluation stops at the first Allow or Block policy that matches.
  4. Access issues an application token that stays valid for the session duration and sends the request through the tunnel with the signed token in the Cf-Access-Jwt-Assertion header.
  5. cloudflared, which dialed out to Cloudflare earlier, hands the request to the internal app at its local address.
  6. The app validates the token: it fetches the signing keys, finds the one whose kid matches, verifies the signature, and checks that iss is your team domain and aud is the application's AUD tag. Only then does it trust the email claim.

When to use it

Common variations

Combine several policies

A policy needs at least one Include rule, and Require and Exclude rules narrow it. Use a Block policy for exceptions to an Allow policy. Bypass and Service Auth policies are evaluated first, then Block and Allow policies in order.

Let machines in

A Service Auth policy accepts service tokens or mutual TLS instead of a login, which suits scripts and other services. Avoid Bypass for anything internal: it turns Access off for the matching traffic and those requests are not logged.

Use one login provider and skip the login page

When an application has a single identity provider, instant authentication sends users straight to it and they never see the Access login page.

Run more than one connector

Start cloudflared on a second machine for the same tunnel. Each connector uses the nearest Cloudflare data center, which adds redundancy and capacity.

Without a Tunnel

Access can also sit in front of an origin that is reachable from the Internet. Then validating the token matters more, because it is what rejects requests that did not come through Access.

Make it yours

Replace the hostname and the Allow policy first. Start with one rule, such as the email addresses of the people who need the app, and widen it later.

Opens this diagram as a board you can edit.

By continuing, you agree to the Terms of Service and Privacy Policy, including sending images of your strokes, diagram labels and similar data to providers in the United States (Cloudflare, Inc. and TypeSafe AI, Inc.) for AI conversion.

All templates