Passwords, tokens, or personal data show up in logs
“Searching the log platform for 'Bearer' or 'password' returns hits: request bodies logged on error, Authorization and Cookie headers in access logs, HTTP client errors dumped with their config, and emails in every line.”
THE PRINCIPLE
Redact at the source, not after ingestion. Log identifiers and outcomes, not payloads.
FIRST MOVES
- Rotate any credential or session token found in logs, and purge or restrict the affected indexes and exports.
- Configure redaction in the logger itself (headers, cookies, password, token, apiKey fields) so every call site and transport benefits.
- Stop logging whole request bodies, response bodies, and raw error objects; HTTP client errors often carry request headers.
- Use structured logs with explicit fields; replace emails and session IDs with internal IDs or hashes where identity is not needed.
- Set retention per data class, restrict and audit read access, and add a CI or ingestion check that flags secret-looking strings.
TOOLS: THEN → NOW
Grep and delete after an incidentRedaction configured at the logger (pino redact) or in the collector pipeline
Free-text log lines with interpolated objectsStructured logs with an allowlist of fields
Logs kept indefinitely and broadly readableRetention per data class with access control and audited reads
PATTERN SNAPSHOT
import pino from "pino";
export const logger = pino({
redact: {
paths: [
"req.headers.authorization", "req.headers.cookie", 'res.headers["set-cookie"]',
"*.password", "*.token", "*.refreshToken", "*.apiKey", // one level deep only
"user.email", "user.phone",
],
censor: "[REDACTED]",
},
});
// Log identifiers and outcomes, not payloads.
logger.info({ userId: user.id, route: "/login", outcome: "mfa_required" }, "login attempt");CLOSE THE AI. EXPLAIN THIS.
Why is redaction in the logger safer than a regex scrubber in the log pipeline, and what does a wildcard path like *.password miss?HOW IT WORKS UNDERNEATH
RELATED SYMPTOMS
SOURCES
Guide reviewed