← back to Secrets Manager
CF-TOKEN-LEAK-ROTATION-BLOCKED-20260621.md
53 lines
# Cloudflare API token LEAK — rotation BLOCKED, awaiting Steve
**Date:** 2026-06-21
**Severity:** HIGH — a live `cfut_`-prefixed Cloudflare User API token was leaked in plaintext
in a subagent's transcript this session. As of this writing the leaked token is STILL LIVE.
## The leaked token
- Canonical registry key: `CLOUDFLARE_API_TOKEN` (and the IDENTICAL value is also stored under
`CLOUDFLARE_PAGES_TOKEN` — same digest `e700:3609b6eb`, same `cfut_` value, len 53).
- Cloudflare token ID (from `/user/tokens/verify`): `289d0aead3b4c6c9dbb38926bcd964a0`
- Last-4: `e700` · sha256-prefix: `3609b6eb`
- Verified status at provider right now: **active** (200, success:true).
## Why rotation could not be completed autonomously
The leaked token lacks the permissions required to revoke/roll itself:
- `GET /user/tokens` → 403 code 9109 (cannot list tokens)
- `PUT /user/tokens/{id}/value` → 403 code 9109 (cannot roll its own secret)
- No Cloudflare Global API Key, no `X_AUTH_EMAIL`/`X_AUTH_KEY` pair, and no token with the
**"API Tokens Write"** scope exists anywhere in the registry / master .env.
So neither rolling nor deleting the leaked token is possible with any credential the
secrets-manager holds. The old value remains LIVE.
## What Steve must do (one of)
1. **Dash (fastest):** Cloudflare dashboard → My Profile → API Tokens → find token id
`289d0aead3b4c6c9dbb38926bcd964a0` (last-4 `e700`) → **Roll** (or Delete + create a new
token with the same DNS-edit scope for the designerwallcoverings.com zone).
2. **OR provide a credential with "API Tokens Write"** (a Global API Key, or a new admin token
scoped to User → API Tokens → Edit). Paste it and the agent will roll
`289d0aead3b4c6c9dbb38926bcd964a0` automatically, then fan out.
## Then (agent finishes automatically)
Once Steve provides the NEW token value (paste it / "here's the new CF key"):
- Validate via `GET /user/tokens/verify` (must be 200/active).
- `add` / `import-paste` fans the new value to BOTH `CLOUDFLARE_API_TOKEN` and
`CLOUDFLARE_PAGES_TOKEN` destinations:
- master `~/Projects/secrets-manager/.env`
- `~/Desktop/site-factory.env`
- `~/Projects/site-factory/.env`
- `~/.claude/skills/cloudflare-manager/.env`
- `~/.claude/skills/setup-domains/.env`
- `~/.claude/skills/domain-setup/.env`
- `~/Projects/coming-soon-template/.env` (PAGES token)
- (`~/.claude.json` MCP env: none currently route the CF token — no MCP block to touch.)
- Confirm the OLD value (`…e700`) now returns 401/inactive at `/user/tokens/verify`.
NOTE: consider whether the two key names should diverge into two separately-scoped tokens
when re-minting, so a future leak of one doesn't expose both surfaces.