Decide blast radius:
| Risk | Examples | Rotate within |
|---|---|---|
| Critical โ public-facing, full account access | Anthropic API key, Cloudflare API token, root SSH keys, Gmail OAuth | Immediately |
| High โ service that can reach money / customer data / others’ systems | Stripe key, Gotify token (if used for alerts that gate decisions), database master pwd | Today |
| Medium โ service that’s mostly homelab-internal | Sonarr/Radarr/Lidarr API keys, internal app passwords, indexer credentials | This week (logged in TASKS.md) |
| Low โ read-only or already-public-equivalent | Public RSS feeds, public bookmarks | Note but don’t rush |
Add an entry to ~/Sync/ED/TASKS.md Active โ Security/Credentials section with the exact value so future-you knows what to rotate. Include the consumer map (where the credential is used).
Example (this happened on 2026-05-25 with the *arr keys):
- [ ] **Rotate Sonarr/Radarr/Lidarr API keys** โ they were hardcoded in
~/Sync/ED/skills/arr-media-management/SKILL.md (Syncthing-replicated).
Old values: d792444549..., b117993eb50..., 3dc17d20ca664...
Consumers: Prowlarr (settings โ apps), Recyclarr (yaml), homelab-config (none โ extracts at runtime via arr-briefing-data.py)
Service-specific procedures live in dedicated runbooks where they’re complicated:
- Rotate *arr API keys
- Anthropic API key (the “Fix” section of doc-sync auth-fail is also a rotation procedure)
For simple cases: log in to the service, generate a new credential, save the new value to ~/Sync/ED/SECRETS.md, update consumers, test.
For containerized services: docker restart <name> after env var update. For Mac launchd: kickstart the job. For Claude Desktop: full quit + relaunch.
If the leak was into a git repo:
# Find every commit containing the value
git -C ~/Sync/ED log -p --all -S 'leaked-value-here' | head -30
# Remove from history (heavy โ use only when necessary, force-pushes break clones)
# Prefer rotating + accepting that the historical value is exposed but inert.
For the homelab-config repo (private but synced), rotating the underlying credential is usually enough โ historical exposure of a now-invalid key is not a real risk.
Once consumers are updated and the new credential works:
- Remove the rotation entry from TASKS.md
- Update
SECRETS.mdwith the new value + last-rotated date - If the leak was a class of mistake (hardcoded in a SKILL, committed in a config), add a defense:
- Pre-commit hook to scan for
sk-,<ApiKey>, etc. - Bundle behavioral rule against the pattern
- Linter for the file type
- Pre-commit hook to scan for