fix(security): redact reasoning display and session exports; cover Google OAuth client secrets - #82895
fix(security): redact reasoning display and session exports; cover Google OAuth client secrets#82895vgarde wants to merge 2 commits into
Conversation
…ogle OAuth client secrets (NousResearch#20785)
|
suggesting changes The new export redaction runs after JSONL/Markdown serialization ( The new reasoning/export call sites ( Security evidence:
Not checked:
Signed: GPT-5.6-sol-xhigh in Codex |
d4b934b to
93e57d8
Compare
|
Addressed all review points — pushed as 1. Structured redaction before serialization. Added 2. 3. Regression tests.
Verification: 102/102 |
Summary
Closes the remaining short-term item from #20785: the May fix enabled secret redaction for chat output, tool output, and logs, but reasoning/thinking blocks were never covered, and Google OAuth client secrets (
GOCSPX-…format) were missing from the redactor's pattern set entirely.Root cause
gateway/run.pyandcli.pyprependlast_reasoning(the model's scratch thinking) to user-facing output with noredact_sensitive_textpass. Since reasoning is display-only text that the model produces while echoing things it saw in context, any credential in context can surface verbatim in chat. Reproduction confirmed against v0.20.0 (2026.8.3)."client_secret": "GOCSPX-…"matched neither_JSON_FIELD_RE(key names list only matched the bare wordsecret, notclient_secret) nor any prefix token. Verified by feeding the exact Google OAuth JSON shape throughredact_sensitive_text— the value came back unredacted. These secrets sit ingoogle_client_secret.jsonin every user's Hermes home, so any tool output or reasoning echoing one would leak it.hermes sessions exportwrites raw transcripts —render_sessions_exportinhermes_cli/session_export.pyemitted session data with no redaction, so reasoning fields (stored raw by design for API replay) could leak into exported JSONL/Markdown.Changes
agent/redact.py: addGOCSPX-[A-Za-z0-9_-]{10,}prefix pattern (Google OAuth client secret); addsecret_key,client_secret,app_secretto_JSON_KEY_NAMESso"client_secret": "…"JSON fields redact.gateway/run.py: redactdisplay_reasoningbefore rendering the thinking block (all platforms).cli.py: redactdisplay_reasoningbefore rendering the CLI reasoning box.hermes_cli/session_export.py: runredact_sensitive_textover rendered exports (JSONL and Markdown). Redaction replaces matches with a plain placeholder, so JSON/Markdown structure is preserved.Verification
python -m py_compilepasses on all four files.redact_sensitive_text: DeepSeeksk-…, Firecrawlfc-…, GoogleAIza…, Google OAuth JSON (client_secret), JWT/Bearer, andKEY=*** env assignments all mask; ordinary words (Secretary,tokenizer`) are untouched (no false positives).Notes
reasoning_contentecho-back for multi-turn reasoning; scrubbing at display/export time is the correct layer.