Raxx · internal docs

internal · gated

Runbook — getraxx.com CF Access gate removal (launch day)

System: Cloudflare Zero Trust Access — getraxx.com pre-launch beta gate
Owner: sre-agent / operator
Created: 2026-05-11 UTC
Execute before: 2026-05-23 UTC (v1 launch target)
Terraform module: terraform/modules/cf-access-getraxx/
Related PR: #1628 (noindex — complementary; also remove noindex on launch day)


What this runbook does

Removes the Cloudflare Zero Trust Access gate from getraxx.com and www.getraxx.com, making the site publicly accessible. This is a one-way step for launch day.

After this runbook completes: - https://getraxx.com/ returns the site directly (HTTP 200) without a login prompt. - https://www.getraxx.com/ same. - Crawlers and browsers can reach robots.txt and _headers.


How to tell the gate is active (pre-removal state)

curl -I https://getraxx.com/ 2>/dev/null | head -5

Expected BEFORE removal (gate active):

HTTP/2 302
location: https://getraxx.cloudflareaccess.com/cdn-cgi/access/login/...
cf-request-id: ...

Expected AFTER removal (gate removed, site public):

HTTP/2 200
content-type: text/html; charset=UTF-8

Pre-flight checklist (do these BEFORE terraform destroy)


Removal procedure

Step 1 — Source credentials

export CLOUDFLARE_API_TOKEN=$(infisical secrets get CF_ACCESS_MGMT \
  --path /MooseQuest/cloudflare/ --plain)
export TF_VAR_cf_access_account_id=$(infisical secrets get CF_ACCESS_ACCOUNT_ID_MOOSEQUEST \
  --path /MooseQuest/cloudflare/ --plain)

Verify the token is active before proceeding:

curl -s -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  https://api.cloudflare.com/client/v4/user/tokens/verify | python3 -m json.tool
# Expect: "status": "active"

If the token is invalid, stop here and follow the rotation procedure in docs/ops/runbooks/rotation/cloudflare-user-api-token.md before continuing.

Step 2 — Plan the destroy

cd terraform/modules/cf-access-getraxx
terraform plan -destroy

Expected output:

Plan: 0 to add, 0 to change, 3 to destroy.
  - cloudflare_zero_trust_access_application.getraxx_beta
  - cloudflare_zero_trust_access_policy.getraxx_beta_invitees
  - cloudflare_ruleset.www_to_apex_redirect

Note on state drift (2026-05-11): The cloudflare_ruleset.www_to_apex_redirect resource was added to main.tf after the initial apply. If Terraform state does not include it (shows 2 not 3 to destroy), run the import first:

terraform import cloudflare_ruleset.www_to_apex_redirect \
  zone/0bdcee38d1da2d021eb6166f0bd6204f/f978e87ed24147d19c5cad45a93ff97a

This requires a token with Zone:Read scope (CF_ACCESS_MGMT). See issue #1652.

If the plan shows anything other than 2–3 to destroy (e.g., errors about state drift), STOP and escalate to operator before continuing.

Step 3 — Destroy

terraform destroy
# Type "yes" when prompted.

Terraform will remove the Access policy first, then the Access application. Both removals are typically instantaneous (<5s) — CF propagates the change globally within ~30s.

Step 4 — Verify removal

Wait 30 seconds for CF propagation, then:

curl -I https://getraxx.com/ 2>/dev/null | head -8

Expected after removal:

HTTP/2 200
content-type: text/html; charset=UTF-8

Also verify www (should redirect 301 to apex, which is now public):

curl -I https://www.getraxx.com/ 2>/dev/null | head -5

Expected:

HTTP/2 301
location: https://getraxx.com/

Note: www continues to redirect 301 → apex post-launch. This is correct behavior; the zone redirect rule remains active. The www → apex 301 is not removed on launch day.

If either still returns a 302 to cloudflareaccess.com: - Wait another 60 seconds (CF propagation can take up to 90s). - If still redirecting after 90s, go to the CF Zero Trust dashboard and confirm the application was deleted (see emergency rollback procedure below).

Step 5 — Post-removal cleanup

  1. Update deploy-getraxx.yml (required for correct post-launch state): - Replace the "Copy _headers into dist (pre-launch noindex state)" step with the post-launch version that writes index, follow: ```yaml

    • name: Write _headers for public indexing run: | printf '/*\n X-Robots-Tag: index, follow\n' >> getraxx-dist/_headers ```
    • The zone-level redirect rule (www → apex) should remain active post-launch — it ensures www users always land on the canonical getraxx.com URL.
    • Trigger workflow_dispatch to redeploy with the updated _headers.
  2. Update docs/security/web-surface-posture.md: change the getraxx.com row from CF Access (beta gate) back to WAF + rate limit (public).

  3. Update docs/security/auth-posture.md §9: change the getraxx.com row from Gated (CF Access) back to Public.

  4. File a GitHub issue to archive or delete the Terraform module. The state file in S3 is empty after terraform destroy; the module directory is inert (no live resources) but may confuse future operators. Options: - Delete terraform/modules/cf-access-getraxx/ and commit. - Keep it as a reference with a # ARCHIVED header in main.tf.

  5. Confirm PR #1628 noindex removal is either already merged or open for merge. The noindex file changes are complementary — crawlers should be allowed back in after launch. (Step 1 above handles _headers in the workflow; also update frontend/getraxx-landing/public/_headers to restore index, follow.)


Emergency rollback — if removal breaks something

Symptom: site returns 5xx or is completely unreachable after removal

This is unrelated to the CF Access gate removal — CF Access controls authentication, not routing. A 5xx after removal means the CF Pages deployment or DNS is the issue, not Access. Check: 1. CF Pages build status: https://dash.cloudflare.com/<ACCOUNT_ID>/pages/view/getraxx 2. DNS resolution: dig getraxx.com — should resolve to a CF Pages IP. 3. CF status: https://www.cloudflarestatus.com/

Symptom: site is still requiring Access login after destroy

CF propagation is slower than expected (rare, but happens). Options in order:

Option A — wait: CF Access changes propagate within 5 minutes globally. Wait up to 5 minutes before escalating.

Option B — purge CF cache for the zone:

curl -sS -X POST \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" \
  "https://api.cloudflare.com/client/v4/zones/0bdcee38d1da2d021eb6166f0bd6204f/purge_cache" \
  -d '{"purge_everything":true}'
# Expect: {"success":true}

Option C — re-apply then destroy again: if Terraform state shows the resources are gone but CF is still serving Access, there may be a phantom application. Check the CF dashboard directly:

https://one.dash.cloudflare.com/<ACCOUNT_ID>/access/apps

If the getraxx.com — pre-launch beta gate app is still listed, delete it manually via the dashboard.

Re-adding the gate (rollback — the launch is NOT happening today)

If the decision is made to roll back and keep the gate active:

Via Terraform (preferred):

cd terraform/modules/cf-access-getraxx
terraform apply
# Re-creates the 2 resources from the same tfvars.

Via CF Zero Trust dashboard (emergency manual path): 1. Go to https://one.dash.cloudflare.com/<ACCOUNT_ID>/access/apps 2. Click "Add an application" → "Self-hosted" 3. Application name: getraxx.com — pre-launch beta gate 4. Application domain: getraxx.com (zone: getraxx.com) 5. Also add www.getraxx.com as an additional domain. 6. Session duration: 24 hours 7. Identity providers: check One-time PIN 8. Enable "Auto-redirect to identity provider" 9. Click Next → Add a policy: - Policy name: Beta invitees (email list) - Action: Allow - Include: Emails — kris@moosequest.net (add others as needed) 10. Save the application. 11. Verify: curl -I https://getraxx.com/ → should return 302 to cloudflareaccess.com.

Cloudflare support escalation (if dashboard changes are not propagating): - URL: https://support.cloudflare.com/hc/en-us/requests/new - Email: support@cloudflare.com - Subject: "CF Zero Trust Access application not propagating after destroy/recreate — getraxx.com" - Include: account ID, zone ID (0bdcee38d1da2d021eb6166f0bd6204f), approximate timestamp of change.


Known trade-offs accepted with this gate

  1. robots.txt unreachable. Crawlers cannot reach https://getraxx.com/robots.txt through CF Access. The Disallow: / and X-Robots-Tag: noindex from PR #1628 are moot while the gate is active — authenticated crawlers do not exist. Accepted: pre-launch we want zero public visibility, and crawlers cannot authenticate through CF Access OTP.

  2. Social card previews require authentication. Link unfurlers (Slack, Twitter, iMessage) will show the CF Access login page thumbnail instead of the OG image. Accepted pre-launch.

  3. CF Access session cookies. Beta users will be prompted once per 24h per browser. Incognito tabs require re-auth.


References