Manage cryptographic key rotations without breaking production. Inventory all keys and credentials, assess rotation urgency based on age, exposure risk, and compliance requirements, generate step-by-step rotation runbooks, and verify nothing breaks after rotation.
Use when: "rotate keys", "key rotation plan", "API key rotation", "credential rotation", "how old are our keys", "key management audit", "secret hygiene", or before compliance audits requiring key rotation evidence.
inventory — Catalog All Keys and Credentials#bash
# Find hardcoded secrets (should be 0)
rg -i "(api_key|apikey|secret_key|access_key|private_key|token)\s*[=:]\s*['\"][a-zA-Z0-9+/=_-]{16,}" \
--type-not binary -g '!node_modules' -g '!vendor' -g '!*.test.*' -g '!*.example*' 2>/dev/null
# Find environment variable references for secrets
rg -i "(API_KEY|SECRET|TOKEN|PASSWORD|PRIVATE_KEY|ACCESS_KEY|CLIENT_SECRET)" \
--type-not binary -g '!node_modules' -g '!vendor' 2>/dev/null | \
grep -v "test\|example\|mock\|fake\|dummy" | head -30
# Check secrets manager
aws secretsmanager list-secrets 2>/dev/null | python3 -c "
import json, sys
secrets = json.load(sys.stdin)['SecretList']
for s in secrets:
last_rotated = s.get('LastRotatedDate', 'NEVER')
last_changed = s.get('LastChangedDate', 'Unknown')
print(f'{s[\"Name\"]}: last_rotated={last_rotated}, last_changed={last_changed}')
"
# Vault secrets
vault secrets list 2>/dev/null
vault list secret/ 2>/dev/null
For each key/credential:
FactorScoreCriteriaAge🔴 5Never rotated or > 1 yearAge🟡 36-12 monthsAge🟢 1< 6 monthsExposure🔴 5In code/git historyExposure🟡 3In env file on serverExposure🟢 1In secrets managerScope🔴 5Admin/root accessScope🟡 3Write accessScope🟢 1Read-onlyCompliance🔴 5Required by PCI/SOC2Compliance🟢 1No compliance requirement
Priority = sum of scores. Rotate highest priority first.
markdown
# Key and Credential Inventory
## Summary
- Total keys/credentials: 34
- Overdue for rotation: 12 (🔴)
- Due soon (30 days): 5 (🟡)
- Healthy: 17 (🟢)
## Critical (rotate immediately)
| Key | Type | Age | Last Rotated | Location | Priority |
|-----|------|-----|-------------|----------|----------|
| STRIPE_SECRET_KEY | API key | 14 months | Never | .env (server) | 18/20 🔴 |
| DB_PASSWORD (prod) | Password | 11 months | 2025-05-15 | Vault | 15/20 🔴 |
| JWT_SIGNING_KEY | Signing key | 8 months | 2025-08-01 | env var | 14/20 🔴 |
## Rotation Schedule
| Key | Next Rotation | Responsible | Runbook |
|-----|--------------|-------------|---------|
| STRIPE_SECRET_KEY | ASAP | @payments-team | See below |
| DB_PASSWORD | May 2026 | @infra | DB password rotation runbook |
rotate — Generate Rotation Runbook#For each key type, generate a step-by-step rotation runbook:
API Key Rotation (zero-downtime):
Database Password Rotation:
JWT Signing Key Rotation (asymmetric):
verify — Post-Rotation Health Check#After rotation, verify:
schedule — Set Up Rotation Reminders#Generate calendar events or ticketing system reminders: