Skip to main content

Workbench: protect sections with Cloudflare Access and fix login failures

Use this runbook when a workbench section is reachable without a login, when a new section is added, or when the owner reports a login failure such as "That account does not have access." The verified facts behind it (preview hosts, the automation token's permission boundaries, which email each login method presents) are in the Knowledge entry Cloudflare; read it first.

Protected sections: finance, divorce, inbox, docs. Each needs an Access application on the production host and a wildcard application covering preview-deployment hosts, with a policy allowing only the owner's addresses: jknash@gmail.com and jknash@x-centric.com.

The two cases at a glance (the prose below governs):

Preconditions​

  • Muse's environment with the cloudflare skill and the stored token (custom.cloudflare). The token can manage applications and policies. It cannot manage the Access organization or identity providers; this runbook marks the steps where that boundary matters.

Case A: protect (or re-protect) the sections​

1. Confirm Access is enabled on the account​

~/workspace/skills/cloudflare/.venv/bin/python \
~/workspace/skills/cloudflare/bin/cf.py access-setup

If it fails with error 9999 ("Access is not enabled"), stop. Only the owner can enable Access: Cloudflare dashboard, Zero Trust, choose a team name and the free plan. Resume this runbook once the owner confirms it is enabled.

2. Let the setup create what is missing​

access-setup is idempotent. It reads the Pages project's real subdomain, then ensures all eight applications exist (four production, four wildcard preview) with the allow policy on each. Re-running it is safe.

Exit test: it prints each domain with "app exists" or "app created" and no failures. Cross-check with:

~/workspace/skills/cloudflare/.venv/bin/python \
~/workspace/skills/cloudflare/bin/cf.py access-list

Expect 8 applications.

3. Verify from outside​

Unauthenticated checks, on the production host and on any current preview host (the deployment URL printed by the deploy runbook):

  • /, expect 200 (public by design).
  • /finance/, /divorce/, /inbox/, expect 302 to the Access login.
  • At least one data file, for example /finance/data/finance.json, expect 302.
  • The same section paths on the preview host, expect 302.

Exit test: every protected URL returns 302 on both hosts. A 200 anywhere means that host or path has no application; re-check the domain strings in access-list against the failing URL before changing anything else.

Case B: "That account does not have access"​

The sign-in succeeded but the presented email is not in the policy. The login page offers only the Cloudflare provider, which presents the Cloudflare account email (jknash@x-centric.com for the owner), not Gmail.

1. Read the current policy on one application​

Fetch the application's policies through the API and compare the include list with the address the owner actually signed in as. Do not guess the address; ask the owner which email their Cloudflare account uses if it is not already recorded here.

2. Add the missing address to every policy​

Update all eight applications' policies so include lists both owner addresses as separate email entries. A partial fix (production only) leaves preview hosts rejecting the same sign-in.

Exit test: policy reads on all eight applications show both addresses, and the owner signs in successfully on a production section and a preview URL.

3. If the owner wants the Gmail PIN instead​

That needs the one-time PIN identity provider, which is an organization setting: the automation token cannot create it (verified error 1010). Two routes, both owner actions:

  • Zero Trust dashboard: Settings, Authentication, Login methods, add One-time PIN. Or
  • Extend the workbench-automation token with "Access: Organizations, Identity Providers, and Groups: Edit", after which an agent can add the provider through the API.

Until then, the Cloudflare-provider sign-in with both addresses allowed is the working configuration. Do not loosen any policy to "fix" a login problem in the meantime.

What this runbook must NOT do​

  • Never make a section public, even temporarily, to work around a login failure.
  • Never add an address to a policy without the owner confirming it is theirs.
  • Never paste the automation token anywhere; if its permissions need to change, the owner edits it in the dashboard and it stays in secure storage.

Published by Muse · 2026-10-02.