Log retention is bounded by rotation config, IaC retention settings, or platform-managed logging
Why it matters
Application logs quietly accumulate confidential data: IP addresses, emails, session identifiers, request payloads. SOC 2 C1.2 requires that confidential information is disposed of when no longer needed, and unbounded log retention is the most common quiet violation of it (bounded retention also evidences CC7.2, since a log pipeline someone actually configured is one someone actually monitors). Auditors ask "how long do you keep logs, and where is that enforced": the answer must point at a rotation config, an IaC retention setting, or a platform whose defaults bound it. AI-generated and vibe-coded apps typically fail this because tutorials show new winston.transports.File(...) and never the lifecycle: the transport ships, the retention bound never does, and the log directory grows until the disk fills or a subpoena arrives. GDPR's storage-limitation principle (Art. 5(1)(e)) applies the same pressure from the privacy side. The good news is that the dominant deploy targets (Vercel, Netlify, Heroku) manage log retention themselves, so most stdout-only apps pass with a note; the check exists to catch the self-managed file and ELK/Loki setups where nobody ever set a bound.
Severity rationale
Low because unbounded log retention is a slow-accruing confidentiality and disk exposure rather than an immediate breach vector, and platform-managed deployments bound it by default; the mechanism is retained confidential data with no disposal path.
Remediation
Put a retention bound wherever logs persist. For file transports, replace the plain file transport in your logger setup (e.g. src/lib/logger.ts) with a rotating one that deletes old files:
import DailyRotateFile from 'winston-daily-rotate-file';
logger.add(new DailyRotateFile({
filename: 'logs/app-%DATE%.log',
maxSize: '20m',
maxFiles: '30d', // rotation without maxFiles rotates but never disposes
}));
For platform log groups, set the bound in IaC (retention_in_days = 30 on an aws_cloudwatch_log_group, retention_days on a GCP logging bucket). For self-hosted Loki set retention_period under limits_config; for self-hosted Elasticsearch commit an ILM delete policy. If you deploy to Vercel, Netlify, or Heroku and log only to stdout, the platform bounds retention for you: nothing to add.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the SOC 2 Technical Readiness Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- soc2:2017 · C1.2 — Disposal of confidential information
- iso-27001:2022 · A.8.15 — Logging
- nist:rev5 · AU-11 — Audit Record Retention
Taxons
History
- 2026-07-03·v1.0.0·Initial soc2-readiness v1 authoring — bounded log retention as the SOC 2 C1.2 disposal variant, with a platform-managed pass leg so stdout-only Vercel/Netlify/Heroku apps are not falsely failed.·by soc2-readiness-v1-build