Documentation
¶
Overview ¶
Package redact removes credential material from strings before they leave the process — into a log sink, or into an HTTP response body.
It exists because the same connection-string password has to be scrubbed in three unrelated places, and the matcher is subtle enough that multiple copies would drift:
- internal/cdc logs DuckDB ATTACH statements and DSNs (#290).
- internal/httpapi logs error chains, and DuckDB quotes the whole postgres_scan connection string back inside its own attach-failure prose, so the password arrives as driver-authored text no Forma wrap site can intercept (#301).
- internal/federated scrubs driver errors at the source (#306): the engine scrubs DuckDB read failures at both emergence points (execute and mid-stream), the plan failure note built from them, and the plan's rendered SQL — so embedders that log the engine's errors or dump the internal plan never capture the credential.
A weaker matcher is not a smaller version of this one, it is a leak: a naive `'[^']*'` branch mistakes libpq's escaped `\'` for the closing quote and emits the password tail past the placeholder. That was a real bug, fixed in #290, and the regression tests for it live in internal/cdc/redact_test.go.
Index ¶
Constants ¶
const Placeholder = "***REDACTED***"
Placeholder replaces every matched credential value.
Variables ¶
This section is empty.
Functions ¶
func ConnStringPassword ¶
ConnStringPassword replaces any password value in a connection string, or in an SQL string or error message that embeds one, with Placeholder. It is safe to call on any string, whether or not it contains a password.
Only the credential is removed. Everything else — hosts, database names, object keys, driver prose — survives, because the redacted output is usually an operator's only remaining copy of the diagnosis.
func Error ¶
Error returns err with any connection-string password in its message replaced by Placeholder. A nil error, or one whose message carries no credential, is returned unchanged — the no-match path returns the error unchanged with no wrapper allocated, preserving the caller's error identity (the regex scan itself may still allocate).
The wrapper rewrites only the composed message. It Unwraps to the original error, so errors.Is/errors.As classification (sentinels, typed carriers, context.Canceled) is unaffected, and any later fmt.Errorf("…: %w", err) wrap builds its message from the scrubbed text. Residual, deliberate: the raw message stays reachable by explicitly unwrapping to the leaf and calling Error() on it — no composed message ever contains it, which is the boundary #306 requires (the credential must not enter an error chain's text).
Types ¶
This section is empty.