feat(postgres): capture application_name in the request log for connection tracing - #58
Conversation
|
Claude finished @andybons's task in 3m 52s —— View job Review complete
Note: SummarySolid, well-scoped change. Confirmed the security-relevant separation holds throughout:
One observation, not a blocking issue: the PR frames this as closing a "log-injection vector," but the two handlers this repo actually wires up ( Also very minor: the CHANGELOG entry says " Test coverage is thorough and test-first per No inline comments filed — didn't find anything rising to a fix-worthy defect. |
What
Captures the client-supplied Postgres
application_namestartup parameter into the canonical request log, so a Postgres connection can be traced to the originating box via a client-chosen slug — the Postgres analogue of HTTPcapture_headers.Two tracing signals now sit side by side on the Postgres log line:
run_id— the trusted, authenticated identity (from the run token), already present.application_name— a free-form, client-set correlation slug (viaPGAPPNAME,application_name=…, oroptions), new here. It also already flows through to Neon, so the same slug surfaces inpg_stat_activity.How
RequestLogData.ApplicationName, set once at the Postgres log-entry construction so it feeds every exit path (success, policy-deny, no-resolver, upstream-fail) — denied connections stay traceable.application_nameslog attribute, non-empty-gated likerun_id/client_ip.proxy.SanitizeLogValue(256-byte UTF-8-safe bound, strips control chars, fixes invalid UTF-8) — it's client-controlled text, so this closes the log-injection vector. Sanitization applies to the log only; the value forwarded upstream to Neon is untouched.capture_headerstruncation now routes through the sameSanitizeLogValue. Behavior change there is strictly an improvement — same 256-byte bound, now also strips control chars (the same injection vector it previously passed through).application_nameis a correlation slug, not identity — nothing keys auth/policy off it;run_idremains the trusted identity.Review
Opus-reviewed (ship): sanitization verified against adversarial inputs (embedded
\n+forged log line, NUL, C0/C1 controls, invalid UTF-8, 10KB → 256 bytes at a rune boundary); confirmed the capture_headers refactor is a non-regressing improvement; confirmed the upstream-forwarded value is the raw one while the log gets the sanitized one (load-bearing test). Mutation-checked (neutering the control-char strip turns the tests red).Tests
Test-first: clean/absent/sanitized+truncated capture, denied-connection capture, forwarding-unaffected guard, and
SanitizeLogValueunit tests — the sanitization test encodes a forgedrun_id=fake-admin-runinjection payload.go test -race ./..., vet, gofmt clean.CHANGELOG
v0.20.0.