secret-rotation-walkthrough
Skill14 starsChanged 9 days agoMITView on GitHub
Use when a secret has been exposed (committed to git, leaked in logs, shared accidentally) and needs immediate rotation across all systems that use it, OR when running a scheduled rotation. Walks through the full rotation cycle without missing a system. Examples cover Supabase keys, hosting env vars, payment gateway secrets, webhook tokens — but the protocol applies to any secret.
- Reads credentials
In this repository11 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- anti-ai-slopSkill
- bukti-sebelum-klaimSkill
- pakai-alat-duluSkill
- pre-deploy-3gateSkill
- security-audit-databaseSkill
- security-audit-web-appSkill
- seo-audit-multilocaleSkill
- seo-content-auditSkill
- tanya-seperlunyaSkill
- voice-register-checkSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
18 rules. About 0 are common, 15 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈15
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 20
Before generating new secret:
- Distinctive: line 22
Check for active misuse: Look at recent activity logs of the service the secret accesses.
- Distinctive: line 23
If active misuse: consider revoking the secret immediately (read-only mode for the service if available) BEFORE generating replacement.
- Distinctive: line 27
Before generating the new value, list everywhere the OLD value exists.
- Distinctive: line 69
Update env var with new value.
- Distinctive: line 71
Verify the service still works (curl an endpoint, check logs).
- Distinctive: line 75
Update the env var in the dashboard (every environment: production, staging).
- Distinctive: line 77
Verify the deployed app still works.
- Very specific: line 80
Update .env file on the VPS.
- Distinctive: line 86
Only after Phase 3 is done across ALL systems.
- Distinctive: line 96
If this was an emergency rotation:
- Very specific: line 97
Write a brief postmortem: how did the leak happen?
- Distinctive: line 98
Add a rule to the project's CLAUDE.md to prevent recurrence.
- Very specific: line 99
If multiple secrets in the same repo could leak the same way, consider a one-off audit: grep for likely-secret patterns (sk-, eyJ, long …
- Distinctive: line 128
Never paste actual secret values into chat or logs.
- Distinctive: line 129
Never skip Phase 1 (identify all systems).
- Distinctive: line 130
Never skip Phase 4 verification (test that old secret is actually invalid).
- Distinctive: line 132
If the user says "I'll do the actual rotation later" — push back: leaked secrets get exploited fast.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Secret rotation walkthrough
You're guiding the user through rotating a secret. This skill exists because rotation is one of those tasks where missing one step (one system that still uses the old secret) means the rotation didn't actually fix the leak — or worse, broke production.
When to use this
Two cases:
- Emergency rotation: secret was exposed (committed to git, posted in chat, screenshot leaked, employee left). Old secret must be invalidated NOW.
- Scheduled rotation: quarterly hygiene, no known leak. Less urgent but same protocol.
For emergency: there's a "minimize damage" phase BEFORE rotation. For scheduled: skip ahead.
Phase 0 (emergency only): contain the damage
Before generating new secret:
- Confirm the leak scope. Where exactly was it exposed? (committed to which repo, posted in which channel, screenshotted by whom, etc.) The scope determines who could have seen it.
- Check for active misuse. Look at recent activity logs of the service the secret accesses. Any requests from unexpected IPs / unexpected times / unusual patterns since the leak?
- If active misuse: consider revoking the secret immediately (read-only mode for the service if available) BEFORE generating replacement. Better short outage than ongoing damage.
Phase 1: identify every system that uses this secret
Before generating the new value, list everywhere the OLD value exists. Otherwise rotation will break things.
For Supabase service-role key, common locations:
- Local
.env.localon developer machines - Hosting platform environment variables (Dokploy, Coolify, Docker env files; every environment: production, staging)
- VPS environment files (e.g.
/etc/something/.envfor cron worker) - GitHub Actions secrets (if CI uses it)
- Any other deploy platform or edge function host
- Backup/snapshot scripts running on a server
- Internal tooling (admin scripts a teammate runs locally)
For payment gateway secret (DOKU, Midtrans, Stripe, etc):
- Same list as above
- Plus: the webhook configuration on the provider dashboard (signature secret)
- Plus: any third-party integration that calls the API on your behalf
For a CDN / DNS API token:
- Wherever DNS automation runs
- Wherever cache purges run
- Wherever certificate provisioning runs
Deliverable for this phase: a numbered list of every system using the secret. Don't proceed until the list feels complete. Ask user if you're missing any.
Phase 2: generate the new secret
- Generate via the provider's official UI or CLI. Never reuse old values, never derive from old values.
- For Supabase: project settings → API → reset service role key.
- For a payment gateway: dashboard → API keys → create new + record old key for revocation later.
- For a CDN / DNS provider: tokens page → create new with the same scopes.
Save the new value somewhere temporary but secure (your password manager). Don't paste into chat (this counts as another leak).
Phase 3: deploy new secret to every system, in safe order
Order matters. If you update the API server first but not the workers, workers will fail with old secret. If you revoke before deploying everywhere, everything fails.
Safe order:
- Update systems that READ data first (lower stakes if they're briefly down).
- Update systems that WRITE data second (higher stakes — you want them to keep working through the change).
- Update webhook receivers LAST — they're often the most fragile.
For each system:
- Update env var with new value.
- Restart / redeploy the service so it picks up the new value.
- Verify the service still works (curl an endpoint, check logs).
- THEN move to next system.
For a hosting dashboard (Dokploy, Coolify, etc.):
- Update the env var in the dashboard (every environment: production, staging).
- Trigger a redeploy so the app picks up the new value.
- Verify the deployed app still works.
For VPS-based services:
- Update
.envfile on the VPS. - Restart the service (
pm2 restart worker-name,systemctl restart service, etc). - Tail logs for 1-2 minutes to confirm clean restart.
Phase 4: revoke the old secret
Only after Phase 3 is done across ALL systems.
- For most providers: dashboard has a "revoke" or "delete" action on the old key.
- For some providers (AWS, many CDN/DNS providers): old keys remain valid until explicitly deleted — delete them.
- For self-managed (HMAC secrets, custom tokens): the new value replacing the old in env effectively revokes if there's no fallback.
Verify revocation: try to use the OLD value to make a request. Should fail (401, 403). If it still works, revocation didn't happen — investigate.
Phase 5: incident postmortem (emergency only)
If this was an emergency rotation:
- Write a brief postmortem: how did the leak happen? Was it a process gap (no
.gitignore?), a behavior gap (committed real key into example file?), or a system gap (CI logs printed env vars)? - Add a rule to the project's CLAUDE.md to prevent recurrence. One-liner with Why: referencing this incident.
- If multiple secrets in the same repo could leak the same way, consider a one-off audit: grep for likely-secret patterns (
sk-,eyJ, long random strings) across full git history.
How to deliver the report
After each phase:
✅ Phase [N] complete: [summary]
[any caveats]
Next: Phase [N+1].Final report:
✅ Rotation complete for [secret name].
Rotated across [N] systems:
- [system 1]: ✅ verified
- [system 2]: ✅ verified
- ...
Old secret revoked: ✅ confirmed (test request returned [error code]).
Postmortem rule added to CLAUDE.md: [yes/no]End with: "Selesai. Mau gue bantu nge-grep history repo buat secret-pattern lain (jaga-jaga), atau lo udah comfortable?"
Constraints
- Never paste actual secret values into chat or logs. Even partially.
- Never skip Phase 1 (identify all systems). Most rotation failures come from missing one system.
- Never skip Phase 4 verification (test that old secret is actually invalid). "I clicked revoke" ≠ "the key is dead".
- For emergency rotation: timer matters. Track elapsed time between leak detection and revocation. Should be minutes, not hours.
- If the user says "I'll do the actual rotation later" — push back: leaked secrets get exploited fast. Better partial rotation now than scheduled rotation never.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

