← 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.