From agent-skills
Structured triage and rotation procedure for a leaked credential or API key. Enforces triage-before-revoke discipline to avoid turning a security incident into a production outage. Use when the user says "I leaked a key", "found a key in a commit", "API key is in git history", "credential exposed", "secret in a log", "key was in a screenshot", "rotate a compromised key", "key appeared in a PR diff", "secret scanner flagged a key", or "I accidentally pushed a secret".
How this skill is triggered — by the user, by Claude, or both
Slash command
/agent-skills:key-leak-triageThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Core rule: triage before revoke.** Panic-revoking a leaked key before you know who uses it can cause an outage worse than the leak itself. The procedure below takes 5-20 minutes. The outage it prevents can take hours.
Core rule: triage before revoke. Panic-revoking a leaked key before you know who uses it can cause an outage worse than the leak itself. The procedure below takes 5-20 minutes. The outage it prevents can take hours.
In these cases: revoke first, accept the outage, then work through the recovery. Come back to step 4 (abuse check) and step 6 (prevent) when the fire is out.
Stop. Before touching the key:
This is the step most people skip. UI labels on keys are NOT reliable indicators of what runtime systems consume them.
Run all of the following:
# Search by the key value itself (first 8 chars is enough if the full key risks re-logging)
grep -r "sk-FIRST-8-CHARS" . --include="*.env" --include="*.json" --include="*.yaml" \
--include="*.yml" --include="*.ts" --include="*.js" --include="*.py" \
--include="*.sh" --include="*.toml" -l
# Search by the key's name/label as it appears in config
grep -r "KEY_NAME_HERE" . -l
# Check CI configs
grep -r "KEY_NAME_HERE" .github/ .gitlab-ci.yml .circleci/ -l 2>/dev/null
# Check deployment env var manifests (adjust paths for your infra)
grep -r "KEY_NAME_HERE" infra/ deploy/ k8s/ platform/ fly/ -l 2>/dev/null
Also check:
Classification A — local-only: The key appears only in local scripts, developer tooling, or one developer's machine. No production service consumes it.
Action: rotate at leisure. Revoking immediately is safe because nothing in production will break.
# Provision the new key at the provider first
# Update your local scripts / .env.local
# Then revoke the old key
# Verify old key is 401
Classification B — runtime-critical: The key is consumed by a running production service, a CI pipeline that gates deployments, or any automated system that runs without human intervention.
Action: rotate-then-revoke. Never revoke before the replacement is live.
# Step 1: Provision the replacement key at the provider
NEW_KEY=sk-REPLACE-WITH-NEW-KEY
# Step 2: Deploy the new key to every consumer found in step 2
# (update env vars in your deployment platform, restart services)
# Step 3: Verify every consumer is healthy with the new key
# (check health endpoints, run smoke tests, review deployment logs)
# Step 4: ONLY THEN revoke the old key
# Step 5: Verify old key returns 401
curl -H "Authorization: Bearer sk-REPLACE-WITH-OLD-KEY" \
https://provider.example.com/v1/models
# Expect: 401 Unauthorized
# Step 6: Verify services still healthy after revoke
At the provider's dashboard or API, pull usage for the exposed key across the full exposure window:
Document what you find. If abuse is confirmed, treat this as a security incident, not just a rotation.
# Revoke the old key at the provider (UI or API)
# Verify: old key is now rejected
curl -H "Authorization: Bearer sk-REPLACE-WITH-OLD-KEY" \
https://provider.example.com/v1/models
# Must return 401
# Verify: production services are still healthy
# (check health endpoints, recent successful API calls in logs)
Do not skip the health check after revocation. Sometimes the new key deployment had a silent error and services were actually still using the old key.
# Rewrite history (destructive — coordinate with team first)
git filter-repo --path-glob '*.env' --invert-paths
# or use git filter-repo --replace-text with a mapping file
# Force push
git push origin --force --all
# CRITICAL: retag from the new main
# Stale tags point to the old commits and re-expose scrubbed history
git tag -d v1.0.0 # delete old tag
git push origin :refs/tags/v1.0.0 # delete remote tag
git tag v1.0.0 HEAD # retag from current clean tip
git push origin --tags
After history rewrite, all collaborators must re-clone or reset their local copies.
.gitignore..gitignore and document this in the runner's README.| Failure | What happens | Fix |
|---|---|---|
| Revoking before finding all consumers | Production outage | Always run step 2 before step 5 |
| Trusting the UI label | Missed consumer causes outage after revoke | Grep the actual configs, not the label |
| Skipping health check after revoke | Silent deploy failure means services were using old key all along | Always verify services healthy after revoke |
| Forgetting to retag after history rewrite | Stale tag re-exposes scrubbed commit | Retag from new HEAD immediately after rewrite |
| New key has different scopes than old key | Services fail with 403 (permission denied) not 401 | Provision new key with same scopes; test before revoking old |
npx claudepluginhub sathiaai/claude-kickoff-playbook --plugin agent-skillsProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.