Skip to content

Cloudflare (Pages + Access)

Owner: Bryan · Every docs site we run is a Cloudflare Pages project gated by Cloudflare Access.

Values that never change

Item Value
GitHub org Dalayon-Reports (repos private)
Pages build command pip install -r requirements.txt && mkdocs build
Pages output dir site
Pages env var PYTHON_VERSION = 3.12
Zero Trust team dalayon
Zero Trust team domain dalayon.cloudflareaccess.com
Plan Free (50 Access seats)
Google OAuth redirect URI https://dalayon.cloudflareaccess.com/cdn-cgi/access/callback
Login methods One-time PIN + Google (account-wide, already set up)
Session duration 24 hours

Deploy a Pages project

  1. Cloudflare dashboard → Compute → Workers & Pages → Create application.
  2. It defaults to the Worker flow. Click "Looking to deploy Pages? Get started" to switch to Pages. (The Worker flow / npx wrangler deploy is wrong for a static site.)
  3. Connect to Git → GitHub → Dalayon-Reports → select the repo → Begin setup.
  4. Enter the build settings from the table above. Framework preset = None.
  5. Save and Deploy. Site goes live at <project>.pages.dev.
  6. Custom domains tab → Set up a domain → enter the subdomain → Activate. DNS auto-creates (dalayon.work is on Cloudflare); SSL active in a few minutes.

Gate a site with Access

  1. Zero Trust → Access → Applications → Add an application → Self-hosted, inner tab Public DNS → Continue.
  2. Destinations → Public hostnames. Add both:
    • the custom hostname (subdomain + dalayon.work, no path), and
    • the .pages.dev hostname (use "Switch to custom input"). Gating both closes the public .pages.dev back door. Never skip the second one.
  3. Access policy → Create new policy:
    • Action Allow.
    • Include → Emails ending in for a domain, and/or Include → Emails for specific addresses.
    • Always include your own and the team's emails so you do not lock yourselves out.
  4. Authentication: leave "Accept all available identity providers" on (One-time PIN + Google already exist account-wide; no IdP setup per site).
  5. Session duration 24 hours. Create.
  6. Verify in incognito: the custom domain and the .pages.dev URL should both require login; an allowed email gets in; a non-listed email is denied.

Two gating patterns

Site Policy = who gets in
Client hub (<slug>.dalayon.work) The client's email domain (or specific emails) plus the team.
This ops manual (ops.dalayon.work) Team emails only. No client domains, ever.

Gate ops.dalayon.work and ops-manual.pages.dev. Same two-destination rule.

Access rules (do not break these)

  • Never add clients as Cloudflare account Members. That grants dashboard admin. Clients only go on the Access policy email list; they consume an Access seat (50 free) on first login.
  • Confidential content (KPIs, revenue) goes live only after the gate is confirmed. Keep placeholders until then.
  • One-time PIN must exist as an identity provider or only account members can log in. It is already set account-wide.

Cache after deploy

docs/_headers sets no-cache on /stylesheets/* and /assets/* so edited CSS/JS/data revalidate after a deploy. Locally, hard-refresh (Ctrl+Shift+R) to beat stale CSS.