Skip to content

fix: preserve AgentGuard CLI output across hosts - #147

Merged
Mr-Lucky merged 6 commits into
mainfrom
fix/agentguard-self-output-across-hosts
Oct 16, 2026
Merged

Mr-Lucky merged 6 commits into
mainfrom
fix/agentguard-self-output-across-hosts

Conversation

@Mr-Lucky

Copy link
Copy Markdown
Contributor

Summary

  • Prevent AgentGuard from blocking its own ordinary CLI commands across supported hosts.
  • Redact sensitive CLI results while preserving the saved activation URL, public key example, and structured result shape.
  • Keep Claude batch protection effective when an output rewrite fails, and add Hermes regression tests to CI.

Type

  • Bug fix
  • New feature / detection rule
  • Refactoring
  • Documentation

Testing

  • npm run build passes
  • npm test passes (full suite not run locally)
  • Manually tested the change

Targeted Node regression suites and all 47 Hermes Python tests passed.

Related Issues

Closes #

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

AgentGuard PR Review

This patch introduces a few concrete regressions and one security gap in the new “self-output” handling paths.

  1. severity: high — src/runtime/protect.ts / isStandaloneAgentGuardCliCommand and nativeAgentGuardSelfOutput

    • What can go wrong: the new exemption path is triggered for any shell command that starts with agentguard and is parsed as standalone. In nativeAgentGuardSelfOutput, a matching command now returns an allow/rewritten result even when the tool output contains sensitive text. If the command detection is bypassed or over-matched in a host integration, a malicious command could get its result rewritten instead of blocked, reducing the security boundary from “block unsafe output” to “redact and allow.”
    • Concrete fix: keep the self-output rewrite strictly behind a verified, host-specific ownership signal, not just command text. Require the runtime action to be positively identified as the exact AgentGuard CLI invocation from a trusted native hook path before rewriting, and fall back to normal blocking for any ambiguity.
  2. severity: high — src/adapters/openclaw-plugin.ts / pendingSelfResults comment and related new self-result logic

    • What can go wrong: the patch introduces persistence-side rewriting for OpenClaw/QClaw with a pending in-memory map keyed by session/tool state. If that state is not reliably tied to a verified pre-tool event and expires incorrectly, a persisted result from an unrelated or attacker-controlled tool call could be rewritten as AgentGuard-owned and bypass downstream inspection.
    • Concrete fix: bind persisted-result rewriting to an immutable tool-call identifier captured from a verified AgentGuard invocation, and reject rewriting if the persisted event cannot be cryptographically or structurally linked to the original call. Do not rely on session-local mutable state alone.
  3. severity: medium — src/runtime/protect.ts / formatCodexHookResult and formatClaudeHookResult

    • What can go wrong: both hooks now return “allow”/replacement payloads for AgentGuard self-output even when the original tool output contained unexpected secrets. That means tests or downstream consumers that relied on a block decision for unmasked secrets will no longer receive a security signal, potentially letting unsafe command outputs proceed further than intended.
    • Concrete fix: preserve a distinct security result for “self-output rewritten after sensitive content found” so callers can still distinguish “redacted for display” from “safe to proceed.” If the host cannot handle that distinction, keep blocking behavior for non-exactly-matched activation-link cases.
  4. severity: medium — plugins/hermes/bridge.py and plugins/hermes/plugin.py / redact_self_output fallback

    • What can go wrong: if the redaction subprocess fails, the code returns a generic user-facing string instead of failing closed. That can hide operational failures and make the tool output look sanitized even when the redactor is unavailable or misconfigured, which is risky for a security boundary.
    • Concrete fix: in transform hooks, prefer returning None or a hard failure that prevents model ingestion when redaction cannot be performed. Only emit fallback text if it is guaranteed to contain no sensitive content and is clearly marked as a failure state.
  5. severity: low — src/tests/codex-hooks.test.ts, src/tests/claude-code-lifecycle.test.ts, and other updated tests

    • What can go wrong: several tests were changed from “block on unexpected secret” to “rewrite and allow,” but some assertions still only check redacted substrings. This can mask regressions where the hook starts returning permissive outputs for non-AgentGuard commands or compound commands.
    • Concrete fix: add explicit assertions that compound/non-standalone commands still block, and that only the exact saved activation URL is exempt. Keep a dedicated test for “unexpected secret in AgentGuard output still signals a security event” so redaction changes don’t silently weaken enforcement.

@Mr-Lucky
Mr-Lucky merged commit 6accba3 into main Oct 16, 2026
1 of 4 checks passed
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