Date: 2026-04-15
The admin GUI is deployed as static assets to Cloudflare Pages. Anyone who knows or guesses the URL can currently download the JS bundle, inspect the routes and component tree, and enumerate the API surface the admin app talks to. Authentication on the admin app itself (login screen, AX session cookie) gates what the API returns, but does nothing to gate who can see the frontend code.
We would like to restrict both: only authenticated staff should be able to load the admin GUI bundle at all.
Put the admin GUI Pages deployment behind Cloudflare Access (Cloudflare Zero Trust). Every HTTP request for the admin app — HTML, JS bundles, static assets, API calls that go through the same hostname — is intercepted by Cloudflare and requires a valid identity proof before any bytes reach the client.
Identity is proven via SSO (Google / Okta / email OTP, configured per organization). On success, Cloudflare issues a short-lived JWT that is attached to every subsequent request as:
CF_Authorization
cookie
(for
browser
requests)
Cf-Access-Jwt-Assertion
header
(forwarded
to
the
origin)
The
admin
GUI
today
has
its
own
login
screen
that
authenticates
against api-gateway
and
produces
an
AX
session
cookie.
Stacking
Cloudflare
Access in
front
of
that
means
staff
would
log
in
twice
—
once
for
Access,
once
for the
admin
app.
That's
silly.
Instead, wire Access as the identity source and let the admin app mint its AX session from the Access JWT:
api-gateway
verifies
the
Cf-Access-Jwt-Assertion
header
on
an
SSO endpoint
(e.g.
POST /api/access-sso).
Verification
checks:
https://<team>.cloudflareaccess.com/cdn-cgi/access/certs
aud
claim
matches
the
application's
Access
AUD
tag
exp
not
in
the
past
email
claim
ax_token
cookie.
If
not,
reject.
/api/access-sso
to
exchange
the
Access JWT
for
an
AX
session
before
doing
anything
else.
If
the
call
succeeds, skip
the
admin
login
screen
entirely.
If
it
fails
(misconfiguration, unknown
email),
fall
back
to
the
existing
login
flow.
Cloudflare silently renews the Access JWT as long as the SSO session is alive, so the AX session refresh flow doesn't need to change.
Cf-Access-Authenticated-User-Email
on
their
own.
If
the
origin
is ever
reachable
directly
(bypassing
Cloudflare),
those
headers
can
be spoofed
trivially.
The
JWT
signature
is
the
real
proof.
CLOUDFLARE_ACCESS_AUD)
and
fail
startup
if
unset
in environments
that
use
Access.