Skip to content

Enable Cloudflare Access on the /v1/admin perimeter before paid launch #108

Description

@serge-ivo

From the admin security audit (2026-08). Not a code bug — a deployment-posture gap.

cloudflareAccessGate() is wired in front of /v1/admin/* (workers/api/src/index.ts:99) but is inert until both CF_ACCESS_TEAM_DOMAIN and CF_ACCESS_AUD are set (lib/cf-access.tsif (!cloudflareAccessConfigured(c.env)) return next();). Prod currently runs with these unset, so today the entire operator portal (every cross-tenant read: all users, all instance configs, all coding-session timelines, all errors, all spend) is protected by requireAdmin alone — a single HS256 bearer token.

The gate itself is sound: it requires both env vars, pins alg:RS256, verifies against fetched JWKS, and fails closed (JWKS fetch failure / malformed / expired / aud-mismatch → 403). It just isn't engaged.

Action

  • Create a Cloudflare Access application for admin.proagentstore.online (self-hosted, policy = the operator email(s)).
  • Set CF_ACCESS_TEAM_DOMAIN + CF_ACCESS_AUD as API Worker secrets (Doppler pags/prdwrangler secret put).
  • Verify the admin UI still loads through the Access login and a non-allowlisted identity gets 403.

Severity: MED. Do before the paid launch — a leaked/forged admin session or a mistaken ADMIN_ALLOWLIST entry is currently full game-over with no second factor.

Files: workers/api/src/index.ts, workers/api/src/lib/cf-access.ts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1: blocks external usersMust be true before someone who is not the owner can run an agent (#68)admin-portalPAGS admin/operator portalenhancementNew feature or requestsecuritySecurity hardening / audit finding

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions