Credentials that are never rotated accumulate exposure surface: every developer who ever handled a secret, every system it transited, and every breach that went undetected leaves a window open indefinitely. NIST IA-5 (Authenticator Management) requires organizations to manage credential 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 service-credential rotation. CWE-522 (Insufficiently Protected Credentials) encompasses stale credentials as a protection failure. Without documented intervals, there is no way to verify compliance, respond to a suspected breach with targeted rotation, or demonstrate due diligence during an audit.
Medium because undocumented or unenforced rotation leaves credentials exposed indefinitely after any breach or insider departure goes undetected.
Document rotation intervals for every credential type and create calendar reminders or automated rotation where the secrets manager supports it. Evidence of rotation — version history, rotation logs, or a dated entry in a runbook — is required to pass.
# ROTATION_POLICY.md
| Credential type | Interval | Last rotated | Next due |
|------------------------|------------|--------------|------------|
| Database credentials | Quarterly | 2026-01-15 | 2026-04-15 |
| Stripe API key | Every 6mo | 2026-01-01 | 2026-07-01 |
| OpenAI API key | Annually | 2026-01-01 | 2027-01-01 |
| AWS IAM access keys | Annually | 2026-01-01 | 2027-01-01 |
For AWS Secrets Manager, enable automatic rotation:
aws secretsmanager rotate-secret --secret-id prod/db-credentials \
--rotation-rules AutomaticallyAfterDays=90
ID: environment-security.secrets-management.secrets-rotation
Severity: medium
What to look for: Look for documentation or runbooks that describe secrets rotation intervals. Check for evidence of recent secret rotation: date stamps in secrets manager, rotation logs, or version history showing recent changes.
Pass criteria: Count all secret types managed and list their rotation schedules. A documented secrets rotation policy exists with defined intervals (e.g., quarterly for database credentials, monthly for API keys). Evidence of recent rotation is present (within the last 90 days for frequently rotated secrets).
Fail criteria: No rotation policy documented, or no evidence of recent rotation (credentials haven't been rotated in over 365 days).
Skip (N/A) when: The project uses auto-rotating secrets (e.g., AWS Secrets Manager auto-rotation) and documentation is unnecessary.
Detail on fail: "No rotation policy documented" or "Last evidence of API key rotation was 18 months ago".
Remediation: Document a rotation schedule:
# ROTATION_POLICY.md
- Database credentials: rotated quarterly (Jan 1, Apr 1, Jul 1, Oct 1)
- API keys (Stripe, OpenAI, SendGrid): rotated monthly (1st of month)
- OAuth refresh tokens: rotated on each token refresh automatically
- AWS access keys: rotated yearly, archived keys retained 90 days
If available, enable automatic rotation through your secrets manager (AWS, Azure, Vault all support this). If manual, set up calendar reminders and rotation runbooks.