Cloudflare Access is the authentication and authorization edge for operator surfaces. Cloudflare is the identity provider; account membership is the authorization selector. Proton Pass is the credential source for automation.
Live status (verified 2026-07-28 — see .cloudflare-access.yml header):
ledger.factory-wager.com — whole hostname behind Access. APPLIED (302 → Access login).reasonix.factory-wager.com — whole hostname behind Access.score.factory-wager.com/portal — portal path behind Access. APPLIED 2026-07-28 17:18 (302 → Access login; also project-r-score.pages.dev/portal).score.factory-wager.com/registry and public proof/API read routes stay
outside this app so package and verification consumers remain non-interactive.pages.dev hostname and preview deployments should use the
Pages Access control in addition to the custom-domain application — not yet
enforced. A normal custom-domain Access app does not cover those hostnames.The policy source is
.cloudflare-access.yml. It is deliberately
scoped: true; the toolchain must ignore unlisted live Access apps instead of
deleting them.
cloudflare_account_member: {} include rule.
Omitting account_id selects the current account and keeps identifiers out
of source.Current Cloudflare references:
.cloudflare-access.yml
and must pass bun run cloudflare:access:verify.Inventory authority remains projects/README.md and
bun run projects:roots:check. Vault coverage authority remains
bun run env:inventory:vault.
.cloudflare-access.yml, this runbook, and the
static verifier/test.Agents claim disjoint files, re-check git status before staging, and commit in
this order: safety contract, identity hotfixes, vault wiring, live plan
evidence, then portal evidence.
The existing general Cloudflare token and DNS token do not have Access scope. Before a live plan:
Cloudflare Access API Token in the factorywager Proton vault.pass-cli proves the item resolves.Token creation is a human Cloudflare-dashboard action. Source changes must not pretend the permission exists before the vault item is real.
portal-cli doctor group infra observes edge behavior (no Access API token required):
| Check | Level | Proves |
|---|---|---|
infra-ledger-access |
fatal | ledger.factory-wager.com returns Access challenge (302 → *.cloudflareaccess.com or www-authenticate: Cloudflare-Access) |
infra-portal-access |
warn | both score.factory-wager.com/portal/ and project-r-score.pages.dev/portal/ are Access-enforced |
bun tools/portal-cli.ts doctor --env ci --group infra
bun tools/portal-cli.ts doctor --group infra --verbose
| Surface | Edge | Doctor |
|---|---|---|
ledger.factory-wager.com |
Access 302 | infra-ledger-access PASS |
score.factory-wager.com/portal |
public 200 | infra-portal-access FAIL warn |
project-r-score.pages.dev/portal |
public 200 | (same) |
terminal.factory-wager.com |
NXDOMAIN (CNAME deleted 2026-07-28) | infra-terminal-host — host gone; see tunnel-inventory · brand-alignment |
reasonix.factory-wager.com |
NXDOMAIN | infra-reasonix-dns info (expected) |
bun tools/portal-cli.ts doctor --group infra --no-write # live
bun tools/portal-cli.ts doctor --group infra --offline --layout plain
kimi-cloudflare-access plan currently fails with Cloudflare API 403 —
CLOUDFLARE_API_TOKEN has no Access/Zero Trust scope; DNS token is Zone.DNS-only.
Human steps before apply:
factorywager vault → item Cloudflare Access API Token.bun run proton:inject:factorywager:reasonix (or wire CLOUDFLARE_ACCESS_API_TOKEN).bun run cloudflare:access:verify then kimi-cloudflare-access plan (creates/updates only).kimi-cloudflare-access apply only with rollback snapshot.portal-cli doctor --group infra → portal warn must go green.pages.dev).Do not run apply until token + IdP + Pages Access + rollback exist.
bun run cloudflare:access:verify
bun run proton:check
kimi-cloudflare-access plan # requires Access-scoped token
After apply, verify: