Redact secrets from logs and downgrade PII log levels#468
Redact secrets from logs and downgrade PII log levels#468ChristianPavilonis wants to merge 3 commits intomainfrom
Conversation
aram356
left a comment
There was a problem hiding this comment.
Summary
This PR introduces a Redacted<T> wrapper type for secrets, downgrades PII/payload log levels from info!/debug! to debug!/trace!, and hard-caps the production log level to Info. Good foundational work — two issues need addressing before merge.
Blocking
1. PII/payload leak at WARN level in Prebid error path
crates/common/src/integrations/prebid.rs lines 879-884
log::warn! logs up to 1000 chars of raw response body on non-2xx status. This bypasses the debug/trace downgrades and will emit in production with the current Info max level. If Prebid returns echoed request/debug blobs, this can include user/device data.
Suggestion: only log the status code at warn! and move the body preview to trace!.
2. Insecure-secret sentinel checks are inconsistent
crates/common/src/settings.rs line 200 + crates/common/src/settings_data.rs line 37
See inline comments. validate_secret_key rejects "secret_key" (underscore) while settings_data.rs rejects "secret-key" (hyphen) — two different strings guarding against the same mistake with split behavior.
Non-blocking
See inline comments for details on each:
- ValidationError codes (
settings.rs:199):new()takes a code, not a human message - Missing regression test (cross-cutting): no test asserting
format!("{:?}", Settings)excludes secret literals across all secret-bearing fields — if a future field forgetsRedacted<T>, there is no safety net - build.rs #[path] coupling (
build.rs:9): fragile inclusion ofredacted.rs; needs a guard comment - Test code still logs synthetic ID (
synthetic.rs:266):log::info!("Generated synthetic ID: {}", synthetic_id)in test — minor inconsistency with PR goal - PII at debug level (
synthetic.rs:99): template input with raw IP/UA downgraded todebug!but nottrace!like other payload logs - Hard-capped log level (
main.rs:177): follow-up to make max level configurable for incident debugging - Non-constant-time auth comparison (
auth.rs:17): out of scope, follow-up forsubtle::ConstantTimeEq
CI Status
All 10 checks PASS: cargo fmt, cargo test, vitest, CodeQL, format-docs, format-typescript, Analyze (actions, javascript-typescript x2, rust).
- Split Prebid warn log so status stays at warn! and body moves to trace! - Consolidate secret-key placeholder checks into validate_secret_key - Use proper ValidationError codes (snake_case identifiers) - Remove redundant InsecureSecretKey error variant - Downgrade synthetic template input log from debug! to trace! - Add build.rs #[path] guard comment to redacted.rs - Downgrade test log from info! to debug!
Review feedback addressedAll blocking and non-blocking items from the review have been resolved in 544d386: Blocking fixes1. PII/payload leak at WARN level in Prebid error path ( 2. Inconsistent secret sentinel checks ( Non-blocking fixes3. ValidationError codes ( 4. PII at debug level ( 5. Guard comment on redacted.rs ( 6. Test log level ( Deferred to follow-up issues
All checks pass locally (fmt, clippy, 481 Rust tests, 239 JS tests, WASM build). |
Summary
Redacted<T>wrapper that prints[REDACTED]in Debug/Display while preserving transparent serde and.expose()access.debug!and payload logs totrace!so they no longer appear in production.DebugtoInfoto prevent verbose output in production by default.Changes
crates/common/src/redacted.rsRedacted<T>wrapper type with[REDACTED]Debug/Display, transparent serde,.expose(), and testscrates/common/src/lib.rsmod redactedcrates/common/src/settings.rsproxy_secret,secret_key,username,password,secret_store_idtoRedacted<String>; updated validatorscrates/common/build.rs#[path]for buildcrates/common/src/auth.rs.expose()for credential comparisoncrates/common/src/http_util.rs.expose()for proxy_secret accesscrates/common/src/settings_data.rs.expose()for secret_key comparisoncrates/common/src/request_signing/endpoints.rs.expose()for secret_store_idcrates/common/src/synthetic.rsinfo!todebug!crates/common/src/integrations/prebid.rsdebug!totrace!crates/common/src/integrations/aps.rsdebug!totrace!crates/common/src/integrations/adserver_mock.rsdebug!totrace!crates/fastly/src/main.rsDebug→Info; settings loginfo!→debug!AGENTS.mdtracingreference tologCloses
Closes #404
Test plan
cargo test --workspacecargo clippy --all-targets --all-features -- -D warningscargo fmt --all -- --checkcd crates/js/lib && npx vitest runcd crates/js/lib && npm run formatcd docs && npm run formatcargo build --bin trusted-server-fastly --release --target wasm32-wasip1fastly compute serveChecklist
unwrap()in production code — useexpect("should ...")logmacros (notprintln!)