Drill 48 — The Logs That Remembered Everything
Theme: Security & Trust Boundaries · Format: 20-min drill · Difficulty: core
The story
A compliance audit samples the centralized logging system and finds that a debug flag — enabled during an incident two years ago and never turned off — has been logging full request payloads: SSNs, account numbers, income data. Two years of retention. Full-text searchable. Accessible to every engineer with log access, which is all of them. The logs were never in any data inventory, because logs are "operational," not "data."
⏸ Stop here and ask the room: how many separate policies did this violate, and which system was supposed to catch it?
Run it — facilitator script
Timing for a 20-minute session: 2 min story · 10 min staged questions · 3 min reveal · 5 min transfer.
Who audits what goes into logs?
- Listen for: the honest present-tense answer — nobody — followed by mechanical fixes: schema-level controls on what can serialize, log statements as a code-review checklist item, and platform-side scanning of the log stream for PII (Personally Identifiable Information) patterns as the backstop.
- Weak signal: "the logging platform team," said hopefully. Owning the storage is not owning the content — the platform team runs the warehouse; they've never once looked inside the boxes.
Do deletion obligations (customer requests, retention limits) reach the logging system?
- Listen for: the recognition that a deletion pipeline routed by the data inventory can only reach what the inventory lists — so an uninventoried log store means every "deleted" customer persists, searchable, indefinitely. Logs must be in the inventory for any obligation to find them.
- Weak signal: "logs age out eventually" — two years of full-text-searchable SSNs already happened while "eventually" was the plan. Retention by default is not retention by policy.
What does "log access for everyone" actually grant here?
- Listen for: full-text search over SSNs, balances, and income for every engineer — meaning one phished engineer, or one bad day, equals bulk PII access. Good answers tier the access (scrubbed views for routine debugging, payload access gated and audited) and note that scrubbed logs are what make broad access survivable at all.
- Weak signal: "engineers need logs to debug" — true, and it doesn't require payloads. Defending the current grant instead of decomposing it is how the grant got this wide.
The reveal
The deletion-rights process the company proudly built (Drill echoes: call-recordings lineage) never touched logs — so every "deleted" customer persisted, searchable, in the observability stack.
Why this happens — the mechanics
Logs accumulate obligations because they're written for the worst day and kept for every day. Under incident pressure, more logging is always the right call — the debug flag captures full payloads because that's what solves the outage at 3 a.m. But turning verbosity off has no constituency: no ticket depends on it, no dashboard shows it, and the flag's continued existence costs nothing anyone can see — while quietly writing PII (Personally Identifiable Information) at line rate for two years. Enabling was an incident action; disabling belonged to nobody.
The "operational" classification is a mental exemption, not a legal one. Data governance routes obligations — inventory, classification, retention, deletion, access — through the systems labeled as data stores; logs sit outside the label and inherit none of the plumbing. Regulators don't recognize the exemption: an SSN carries the same obligations whether it sits in a governed table or an index nobody inventoried. Every "deleted" customer persisting in the observability stack isn't an edge case — it's the guaranteed output of a deletion pipeline whose map of data stores was incomplete.
Access compounds the exposure. Log platforms default to broad access because debugging is everyone's job — reasonable, right up until one flag converts "all engineers can read logs" into "all engineers can full-text search SSNs." The audit found it because audits sample; an attacker would have found it because attackers search — and a full-text index over two years of payloads is the best exfiltration tool anyone ever built for them, in-house, for free.
Diagrams
Problem — how the failure unfolds:
timeline
title Two years of remembered payloads
section The incident
Day 0 : Debug flag enabled mid-incident
Week 1 : Incident closed : Flag never turned off (silent)
section Two quiet years
Daily : Full payloads logged (silent) : SSNs, accounts, income data
Always : Searchable by every engineer : Never in any data inventory
Always : Deletion rights never reach logs
section Year 2
The audit : Compliance samples the logs : Finding filed - two years of PII
Solution — where the guardrails go:
flowchart TD
A["Service emits structured logs"] --> B["Schema-level PII<br/>scrubbing: block-listed<br/>fields never serialize"]
B --> C["Retention limits enforced<br/>platform-side"]
D["Debug verbosity enabled<br/>during an incident"] --> E["Debug flag carries a TTL —<br/>auto-reverts like a<br/>feature flag"]
E -.-> M["Expiry monitor confirms<br/>the revert happened"]
M -.-> AL["Alert if verbose logging<br/>outlives its TTL"]
C --> F["Logs listed in the data<br/>inventory"]
F --> G["Deletion pipeline<br/>propagates into the<br/>observability stack"]
What good looks like
- Allow-listed structured logging — fields serialize only if declared in the schema, and block-listed fields (SSN, account number, date of birth) are rejected at the library level, so the mistake fails in development instead of shipping.
- Ingestion-side scrubbing as the second layer — pattern redaction in the log pipeline (SSN formats, Luhn-valid card numbers, email addresses) catches whatever the schema layer missed, before anything hits an index.
- Debug verbosity with a TTL (Time To Live) — verbose logging auto-reverts in 24–72 hours like a feature flag, with an alert if anyone extends it; "enabled during an incident" comes with its own expiry date.
- Platform-enforced retention — hot, searchable indexes capped at 30–90 days with a defined archive-and-expire policy behind them; nothing stays full-text searchable forever by default.
- Logs in the data inventory — logs, traces, and crash dumps listed alongside databases, so deletion requests and retention obligations route into the observability stack instead of stopping at its door.
- Tiered log access — scrubbed views for routine debugging; payload-level access gated, audited, and rare enough that each grant is a conversation.
- A weekly canary search — a synthetic test customer's SSN and email searched across the log platform on a schedule; any hit files a ticket automatically, turning this drill's transfer question into a standing monitor.
The lesson
Logs are a data store with all the same obligations — classification, retention, access control, deletion — plus the worst defaults of any system you run. Controls: structured logging with schema-level PII scrubbing (block-listed fields never serialize), retention limits enforced platform-side, debug verbosity with a TTL (auto-revert, like a feature flag — Drill 28), and logs included in every data inventory and deletion pipeline.
Named concepts: PII in telemetry, data inventory completeness, retention enforcement, debug-flag TTLs.
Real-world echoes
Microsoft AI research, 2023 — a misconfigured SAS (Shared Access Signature) token meant to share a training dataset exposed 38 terabytes of internal storage, including backups containing internal messages. Different mechanism, same lesson as the debug flag: the data exhaust around the thing you meant to share had quietly accumulated far more sensitivity than the thing itself, and nobody was auditing the exhaust.
Transfer
Search our logs right now for a test customer's SSN and email. If anything comes back, the drill just became an incident — which is the point of running drills.
Make it a ticket: Run the transfer search today; whatever comes back, add the block-listed fields to the logging schema and put a TTL on every debug-verbosity flag — the deliverable is the first auto-revert recorded in the flag history.
Related
- Drill 45 — The Vendor's Bad Week — the same payloads-in-logs failure, in a vendor's environment instead of yours; run both and the boundary lesson draws itself.
- Drill 42 — The Notebook on GitHub — sensitive material persisting where nobody governs it: a notebook cell there, a log index here; scanners find one, auditors sample the other.
- Drill 28 — The Friday Flag, theme 5 — the auto-reverting feature flag this drill borrows: anything enabled under pressure needs an expiry date it enforces itself.
