API keys that are never deactivated accumulate across developer departures, vendor changes, and tool evaluations. An old Stripe key issued to a former contractor, a SendGrid key from a deprecated integration, or an OpenAI key created for a proof-of-concept all remain valid indefinitely unless explicitly revoked. NIST IA-5 requires managing authenticator lifetimes. PCI-DSS v4.0 Req-8.6.3 requires passwords/passphrases for application and system accounts to be changed periodically per a targeted risk analysis — the correct control for API-key lifecycle. CWE-522 covers credentials that are not adequately protected throughout their lifecycle. An attacker who obtains a three-year-old API key through any historical leak finds it just as usable as one issued today.
Info because unrotated API keys create long-lived exposure windows but require prior credential compromise to be exploited; the risk is proportional to how old the keys are.
Maintain a rotation registry for every external API key. When rotating, generate the new key first, deploy it, verify it works, then deactivate the old key in the service dashboard — in that order, to avoid downtime.
# API_KEY_ROTATION.md
| Service | Rotation interval | Last rotated | Old key deactivated? |
|----------|------------------|-------------|--------------------|
| Stripe | Annually | 2026-01-01 | Yes |
| OpenAI | Every 6 months | 2026-01-01 | Yes |
| SendGrid | Annually | 2026-01-01 | Yes |
Rotation process:
1. Generate new key in service dashboard
2. Update secrets manager: `aws secretsmanager put-secret-value --secret-id prod/stripe-key`
3. Deploy and confirm new key is active (check logs for auth errors)
4. Deactivate old key in service dashboard
5. Record rotation date and old key ID in this file
For services that support multiple active keys, keep the overlap window under 24 hours.
ID: environment-security.access-audit.api-keys-rotated
Severity: info
What to look for: Check for evidence of API key and service account credential rotation. Look in secrets manager version history, documentation, or rotation logs. Verify old keys are deactivated.
Pass criteria: Count all API keys and service account credentials. API keys and service accounts are rotated on a documented schedule (at least annually). Evidence of recent rotation is present. Old keys are deactivated, not just replaced.
Fail criteria: No rotation happening, or keys older than rotation interval without evidence of deactivation.
Skip (N/A) when: Never — API key rotation applies to all applications using external services.
Detail on fail: "Stripe API key has not been rotated in 3 years" or "Old API keys are replaced but not deactivated in service dashboards".
Remediation: Implement API key rotation:
# API_KEY_ROTATION.md
- Stripe API keys: Rotated annually (January 1)
- OpenAI API keys: Rotated every 6 months
- SendGrid API keys: Rotated annually
Process:
1. Generate new API key in service dashboard
2. Update secrets manager with new key
3. Deploy and verify new key works
4. Deactivate old key in service dashboard
5. Document rotation date and old key ID
Set calendar reminders and automate where possible (some services support key auto-rotation).