Operator Auth (Cloudflare Access)
Overview
Section titled “Overview”Convertella operators authenticate through Cloudflare Access (Zero Trust), not via Lucia. There are no operator passwords or magic links. Operator identity is verified from Cloudflare Access JWT tokens.
- User navigates to operator route (e.g.,
operator.convertella.app) - Cloudflare Access intercepts, presents MFA challenge
- On success, Cloudflare sets
CF_Authorizationcookie - The Astro app validates the JWT on every request
- Email is extracted from JWT, checked against operator allowlist
JWT Verification
Section titled “JWT Verification”The src/lib/auth/cf-access.ts module performs JWT verification:
- Reads
Cf-Access-Jwt-Assertionheader (orCF_Authorizationcookie) - Fetches JWKS from
https://<team>.cloudflareaccess.com/cdn-cgi/access/certs - Verifies JWT signature, validates
aud,exp,iat - Extracts
emailclaim - Checks email against
OPERATOR_ALLOWED_EMAILSenv var (comma-separated)
Failure Modes
Section titled “Failure Modes”| Condition | Response |
|---|---|
| Missing or invalid JWT | 401 (JSON) for APIs; Cloudflare handles redirect for pages |
| Valid JWT, email not in allowlist | 403 with “operator access required” |
Operator Routes
Section titled “Operator Routes”All operator functionality is under:
/operator/*— Pages (dashboard, organizations, projects, domains, audit)/api/operator/*— API endpoints
Environment Variables
Section titled “Environment Variables”| Variable | Purpose |
|---|---|
CF_ACCESS_TEAM_DOMAIN | Cloudflare Access team domain (e.g., convertella.cloudflareaccess.com) |
CF_ACCESS_AUD | Expected audience tag for JWT validation |
OPERATOR_ALLOWED_EMAILS | Comma-separated email addresses allowed operator access |
Automation without a browser
Section titled “Automation without a browser”| Surface | Mechanism |
|---|---|
Handbook (docs.convertella.app) | Cloudflare Access service token headers (CF-Access-Client-Id, CF-Access-Client-Secret). See Handbook hosting. |
Operator API (/api/operator/*) | Cloudflare Access JWT from a logged-in session, or legacy bearer token (below) |
Service tokens are created in Zero Trust and allow-listed on the handbook Access application. They do not replace Access — they authenticate as a machine identity.
Legacy: Bearer Token (retired)
Section titled “Legacy: Bearer Token (retired)”The legacy bearer-token auth path in src/lib/auth/operator-portal.ts has been removed as of the Worker split (workstream 1.8). Operator routes now exclusively use Cloudflare Access JWT verification.