# Database credentials rotated per policy

- **Pattern:** `ab-001273` (`environment-security.access-audit.db-credentials-rotated`)
- **Severity:** info
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001273
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001273)

## Why it matters

Database credentials that are never rotated represent an indefinite exposure window: a breach discovered six months late, a departed employee, or a compromised developer machine may have leaked those credentials with no way to detect it retroactively. NIST IA-5 requires authenticator management including credential lifetime controls. 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 and protected against misuse — the correct control for database service-account credentials. CWE-522 covers insufficiently protected credentials, which includes stale credentials that cannot be revoked because no rotation process exists. Without documented last-rotation dates, you cannot demonstrate compliance or reason about the risk surface.

## Severity rationale

Info because stale database credentials do not represent an active vulnerability but create an unbounded exposure window if a past breach went undetected.

## Remediation

Document last rotation dates and next scheduled rotation for every database credential set. For managed database services, prefer automated rotation over manual processes.

```markdown
# ROTATION_SCHEDULE.md
## Database Credentials
| Environment | Last rotated | Next due   | Method    |
|-------------|-------------|------------|----------|
| Production  | 2026-01-15  | 2026-04-15 | Manual   |
| Staging     | 2026-01-15  | 2026-04-15 | Manual   |
```

**Enable automated rotation on AWS RDS:**
```bash
aws rds modify-db-instance \
  --db-instance-identifier prod-db \
  --manage-master-user-password
# Rotates credentials in Secrets Manager automatically
```

**Manual rotation process:** Generate new password → update Secrets Manager → trigger a rolling deployment → verify connectivity → archive old password with deactivation date. Document each step with a timestamp.

## Detection

- **ID:** `db-credentials-rotated`
- **Severity:** `info`
- **What to look for:** Check if a documented database credential rotation policy exists. Look for evidence of recent rotation: version history in secrets manager, old credentials marked as archived, or rotation logs.
- **Pass criteria:** Count all database credential sets and list their last rotation dates. A documented rotation policy exists (quarterly, monthly, etc.) and evidence shows recent rotation within at least 90 days of the policy interval.
- **Fail criteria:** No rotation policy, or last rotation was beyond policy interval (e.g., policy says quarterly but last rotation was 8 months ago).
- **Skip (N/A) when:** The project uses auto-rotating credentials (managed database services with auto-rotation enabled).
- **Detail on fail:** `"No database credential rotation policy documented"` or `"Last database password rotation was 10 months ago; quarterly policy not followed"`.
- **Remediation:** Establish and document rotation:

  ```
  # ROTATION_SCHEDULE.md
  Database Credentials: Rotated quarterly
  - Last rotation: 2026-01-15
  - Next rotation: 2026-04-15
  - Process: Update secret in AWS Secrets Manager, test connection, update app deployment
  ```

  If using a managed database service (RDS, Cloud SQL), enable automated rotation:
  ```bash
  # AWS RDS
  aws rds modify-db-instance --db-instance-identifier mydb \
    --manage-master-user-password --enable-iam-database-authentication
  ```

## External references

- cwe CWE-522
- nist IA-5
- pci-dss Req-8.6.3

Taxons: cryptography-and-secrets, operational-readiness

HTML version: https://auditbuffet.com/patterns/ab-001273
