You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(usersecrets): redact secret DDL anywhere in a multi-statement query (#769)
* fix(usersecrets): redact secret DDL anywhere in a multi-statement query
RedactForLog only classified the statement head, so a client could prefix
any leading statement (e.g. "SELECT 1; CREATE PERSISTENT SECRET foo (...,
SECRET 'realKey')") and the head no longer classified as secret DDL — the
query, including credential literals, was returned verbatim and written to
logs, OTel spans, the persisted query log, and pg_stat_activity. This
violates the "Never log/store secret statement text" invariant.
RedactForLog now splits the query on top-level semicolons (reusing the
existing literal/identifier/comment-aware tokenization, not a naive
strings.Split) and, if ANY top-level segment classifies as CREATE SECRET,
replaces the whole query with the fixed redaction placeholder. The
single-statement fast path is unchanged. Over-redaction is intentional:
false positives only cost log fidelity, never credential exposure.
Also fixes the same head-only blind spot in the Flight SQL ingress
RejectPersistentSecretDDL check via a new ContainsPersistentSecretDDL
helper that scans every top-level statement.
Generated-By: PostHog Code
Task-Id: 96557416-3af0-4633-bcf0-164d1e64cf22
* fix(usersecrets): redact secret literals echoed in error messages
RedactForLog scrubs the query attribute, but engine error messages echo
the offending SQL verbatim (DuckDB: `LINE 1: ... SECRET 'literal'`), so a
failed CREATE SECRET leaked the credential through the unredacted error
sinks even though the query text was redacted:
msg="Query execution errored." query="CREATE TEMPORARY SECRET badt (…redacted)"
error="...Parser Error: ... SECRET 'realkey' BOGUS)"
This violated the same "never log/store secret statement text" invariant
the PR set out to enforce, just via the error channel instead of the
query channel. Reproduced live against the multi-tenant cluster.
Add usersecrets.RedactErrorForLog(query, errMsg): when the originating
query carries CREATE SECRET DDL (head or any top-level statement, shared
tokenizer with RedactForLog so they can't drift), the whole error is
replaced with a fixed placeholder. Over-redaction only costs diagnostic
detail, never credential exposure; non-secret errors pass through.
Apply it at every sink that logs a query's error: logQueryError and
logQueryFinished (slog `error` attr) and logQuery (query-log `Exception`
column), each classifying against the original query before it is
replaced with the redacted form.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
"persistent secrets are managed via the PostgreSQL protocol on this deployment; CREATE/DROP PERSISTENT SECRET is not supported over Flight SQL (a secret created here would not survive the session)")
0 commit comments