Skip to content

fix(security): redact secrets from context compaction input and output#9200

Closed
entropidelic wants to merge 5 commits into
mainfrom
compaction-secrets-preservation
Closed

fix(security): redact secrets from context compaction input and output#9200
entropidelic wants to merge 5 commits into
mainfrom
compaction-secrets-preservation

Conversation

@entropidelic

@entropidelic entropidelic commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

During context compaction, conversation turns are serialized and sent to an auxiliary LLM for summarization. If
secrets appeared in the conversation (API keys from env/printenv output, config file reads, terminal commands), they were sent verbatim to the auxiliary model which may be a different provider and could be preserved in the summary text that persists across compactions via _previous_summary.

This PR applies redact_sensitive_text() at the compaction boundary: on serializer input (message content + tool call arguments), on the summarizer LLM's output, and adds prompt-level instructions as defense-in-depth.

Type of Change

  • 🔒 Security fix
  • ✅ Tests (adding or improving test coverage)

Changes Made

  • agent/context_compressor.py: Import redact_sensitive_text from agent.redact
  • agent/context_compressor.py: Call redact_sensitive_text() on message content and tool call arguments in _serialize_for_summary() before they reach the auxiliary model
    • agent/context_compressor.py: Call redact_sensitive_text() on the summarizer LLM's output before storing in _previous_summary (closes the input→output loop)
    • agent/context_compressor.py: Add "NEVER include API keys, tokens, passwords, secrets, credentials" instruction to summarizer preamble, Critical Context template section, and focus topic guidance
    • tests/agent/test_context_compressor.py: Add TestSerializeRedactsSecrets (5 tests) — verifies secrets are stripped from tool results, user messages, assistant content, tool call arguments, and that non-secret content is preserved´
    • tests/agent/test_context_compressor.py: Add TestGenerateSummaryRedactsOutput (1 test) — verifies the summarizer LLM's output is redacted before storage in _previous_summary

How to Test

  1. Run the compressor test suite: uv run pytest tests/agent/test_context_compressor.py -q — all 46 tests should pass (40 existing + 6 new)
  2. Run the redact test suite to confirm no regressions: uv run pytest tests/agent/test_redact.py -q
  3. Manual: start a conversation, run echo OPENAI_API_KEY=sk-proj-abc123def456ghi789jkl012, continue until compaction triggers, then verify the summary does not contain the key value

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: Install hook files modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

@entropidelic entropidelic marked this pull request as ready for review April 14, 2026 14:36
@OutThisLife

Copy link
Copy Markdown
Collaborator

i like this one

teknium1 pushed a commit that referenced this pull request Apr 20, 2026
Three-layer defense against secrets leaking into compaction summaries:
1. Input redaction: redact_sensitive_text() on message content and tool
   call arguments in _serialize_for_summary() before sending to summarizer
2. Prompt instructions: NEVER include API keys/tokens/passwords in the
   summarizer preamble, template Critical Context section, and focus topic
3. Output redaction: redact_sensitive_text() on the summary output and
   _previous_summary for iterative updates

Reuses existing agent/redact.py patterns (sk-*, ghp_*, key=value, etc).

Cherry-picked from PR #9200 by @entropidelic.
ulasbilgen pushed a commit to ulasbilgen/hermes-adhd-agent that referenced this pull request May 1, 2026
Three-layer defense against secrets leaking into compaction summaries:
1. Input redaction: redact_sensitive_text() on message content and tool
   call arguments in _serialize_for_summary() before sending to summarizer
2. Prompt instructions: NEVER include API keys/tokens/passwords in the
   summarizer preamble, template Critical Context section, and focus topic
3. Output redaction: redact_sensitive_text() on the summary output and
   _previous_summary for iterative updates

Reuses existing agent/redact.py patterns (sk-*, ghp_*, key=value, etc).

Cherry-picked from PR NousResearch#9200 by @entropidelic.
aj-nt pushed a commit to aj-nt/hermes-agent that referenced this pull request May 1, 2026
Three-layer defense against secrets leaking into compaction summaries:
1. Input redaction: redact_sensitive_text() on message content and tool
   call arguments in _serialize_for_summary() before sending to summarizer
2. Prompt instructions: NEVER include API keys/tokens/passwords in the
   summarizer preamble, template Critical Context section, and focus topic
3. Output redaction: redact_sensitive_text() on the summary output and
   _previous_summary for iterative updates

Reuses existing agent/redact.py patterns (sk-*, ghp_*, key=value, etc).

Cherry-picked from PR NousResearch#9200 by @entropidelic.
Luminet2023 pushed a commit to Luminet2023/hermes-agent that referenced this pull request May 1, 2026
Three-layer defense against secrets leaking into compaction summaries:
1. Input redaction: redact_sensitive_text() on message content and tool
   call arguments in _serialize_for_summary() before sending to summarizer
2. Prompt instructions: NEVER include API keys/tokens/passwords in the
   summarizer preamble, template Critical Context section, and focus topic
3. Output redaction: redact_sensitive_text() on the summary output and
   _previous_summary for iterative updates

Reuses existing agent/redact.py patterns (sk-*, ghp_*, key=value, etc).

Cherry-picked from PR NousResearch#9200 by @entropidelic.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
Three-layer defense against secrets leaking into compaction summaries:
1. Input redaction: redact_sensitive_text() on message content and tool
   call arguments in _serialize_for_summary() before sending to summarizer
2. Prompt instructions: NEVER include API keys/tokens/passwords in the
   summarizer preamble, template Critical Context section, and focus topic
3. Output redaction: redact_sensitive_text() on the summary output and
   _previous_summary for iterative updates

Reuses existing agent/redact.py patterns (sk-*, ghp_*, key=value, etc).

Cherry-picked from PR NousResearch#9200 by @entropidelic.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
Three-layer defense against secrets leaking into compaction summaries:
1. Input redaction: redact_sensitive_text() on message content and tool
   call arguments in _serialize_for_summary() before sending to summarizer
2. Prompt instructions: NEVER include API keys/tokens/passwords in the
   summarizer preamble, template Critical Context section, and focus topic
3. Output redaction: redact_sensitive_text() on the summary output and
   _previous_summary for iterative updates

Reuses existing agent/redact.py patterns (sk-*, ghp_*, key=value, etc).

Cherry-picked from PR NousResearch#9200 by @entropidelic.
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
Three-layer defense against secrets leaking into compaction summaries:
1. Input redaction: redact_sensitive_text() on message content and tool
   call arguments in _serialize_for_summary() before sending to summarizer
2. Prompt instructions: NEVER include API keys/tokens/passwords in the
   summarizer preamble, template Critical Context section, and focus topic
3. Output redaction: redact_sensitive_text() on the summary output and
   _previous_summary for iterative updates

Reuses existing agent/redact.py patterns (sk-*, ghp_*, key=value, etc).

Cherry-picked from PR NousResearch#9200 by @entropidelic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants