Technical SOPs
Operator Dashboard — Cloudflare Access Edge Gate Setup
Operator Dashboard — Cloudflare Access Edge Gate
First, the mental model (this trips people up)
The dashboard already has working authentication, and it is NOT in Cloudflare. There are two separate systems:
| Layer | Where it lives | What it does |
|---|---|---|
| App SSO (the “Continue with Microsoft” button) | login.astro → Supabase Auth → Entra | Authenticates the user inside the app; issues the session RLS checks. This is what makes login work today. |
| Cloudflare Pages | Cloudflare | Only hosts the static files. Does no authentication. |
| Cloudflare Access (this doc) | Cloudflare Zero Trust | A separate, additive edge gate — checks identity before the app loads. Optional defense-in-depth. |
So if you go looking in Cloudflare for “the setting that makes the dashboard login work,” there isn’t one — that’s all app + Supabase + Entra. Cloudflare Access below is a new, outer perimeter we’re adding on top; it does not change the app’s own login.
Why add it: without Access, the /login page and /api/* functions are publicly reachable
(the app’s Supabase+RLS still stops unauthorized data access, but the URLs respond). Access puts a
Microsoft check at Cloudflare’s edge so those URLs aren’t reachable at all without auth — shrinking
the attack surface. All steps are in the Zero Trust console; no API token needed.
Prereq — enable Zero Trust (one-time)
- dash.cloudflare.com → Zero Trust.
- Pick a team name (e.g.
cybersuite) → team domain becomescybersuite.cloudflareaccess.com. - Choose the Free plan (≤50 users, $0).
Part A — Register a dedicated Entra app (entra.microsoft.com)
Separate from the Supabase app — different redirect, same flow.
- App registrations → New registration.
- Name:
CyberSuite — Cloudflare Access - Account types: Single tenant 🔒
- Redirect URI: leave blank — you paste the exact value Cloudflare gives you in Part B.
- Register → copy Application (client) ID + Directory (tenant) ID.
- Certificates & secrets → New client secret → copy the Value → 1Password (
CyberSuite-Infra). - API permissions → Microsoft Graph → Delegated:
openid,email,profile(+Directory.Read.Allonly if you want to use Entra groups in policies) → Grant admin consent.
Part B — Add Entra as a Zero Trust login method
- Zero Trust → Settings → Authentication → Login methods → Add new → Azure AD.
- Cloudflare displays the callback/redirect URL on this screen — copy it into the Entra app’s Redirect URI (Part A step 4). (This cross-wire is the step people miss.)
- Paste in App ID, Client secret, Directory (tenant) ID.
- (Optional) enable Support groups if you added the Graph permission.
- Save → Test — it should round-trip through Microsoft and report success.
Part C — Create the Access application
- Zero Trust → Access → Applications → Add an application → Self-hosted.
- Name:
CyberSuite Operator Dashboard - Session duration:
24 hours. - Application domain: subdomain
dashboard, domaincybersuite.tech, path blank (covers app +/api). - Identity providers: select Azure AD; turn OFF “Accept all available identity providers” and disable One-time PIN — Microsoft becomes the only way through.
- Next.
Part D — Access policy
- Policy name:
Operators - Action: Allow
- Include → Emails →
jerrym@cybersuite.tech,jerry@pdright.com. - Save → Add application.
Part E — Test
- Incognito → dashboard.cybersuite.tech → Cloudflare Access screen → Microsoft → then the dashboard.
- Confirm a non-listed email is blocked at the edge (never reaches the app).
Know before you commit
- Two Microsoft checks now: Access (edge) then the app’s Supabase SSO. Both use Entra, so the second is normally a silent SSO (no second prompt).
/apifunctions are now edge-protected — no longer publicly reachable. Browserfetch()from the app still works (the Access cookie rides same-domain requests).- ⚠️
cybersuite-dashboard.pages.devis a side door. Access sits on thecybersuite.techzone, not on Cloudflare’spages.dev. The raw.pages.devURL bypasses Access (Supabase RLS + the function gate still protect the data there). Follow-up hardening: require Access on the Pages project / retire the public.pages.devroute. Don’t treat the app as fully edge-locked until this is closed. - Access lockout is recoverable (it gates the app, not the tenant) — but keep the
Operatorspolicy correct; you can always edit/remove it in the Zero Trust console.
”Done” means
- Parts A–E complete; Microsoft challenge appears before the dashboard
- Non-operator email blocked at the edge
-
.pages.devside-door follow-up logged