Files
hermes-agent/tools
Frowtek 183712ab82 fix(delegation): redact credentials in live subagent transcripts
The live transcripts added with delegate_task write each child's events to
<hermes_home>/cache/delegation/live/<delegation_id>/. Nothing on that path is
redacted, and the rendered events are precisely the secret-bearing surfaces:
tool args, tool results and streamed assistant text.

That location is not incidental — delegate_tool.py:1620 documents cache/
delegation as "mounted read-only into remote backends", so every line lands
in a file readable from inside the sandbox.

Observed on the writer today:

    tool   | -> terminal(curl -H "Authorization: Bearer sk-ant-api03-...")
    result | terminal ok 0.4s: OPENAI_API_KEY=sk-proj-... AWS_SECRET_ACCESS_KEY=wJalr...

The same three values through the canonical redactor:

    curl -H "Authorization: Bearer ***" https://api.internal
    OPENAI_API_KEY=*** AWS_SECRET_ACCESS_KEY=***

Every other sink for this data already routes through that redactor — search
results via redact_sensitive_text(file_read=True), terminal output via
redact_terminal_output — so the transcript was the one place an operator's
keys reached disk in the clear.

Redact at three points, covering every artefact the dispatch writes into that
directory:

  * event() — every typed helper (assistant_text, thinking, tool_start,
    tool_result, marker, finalize, the stream flush) funnels through it, so
    one call covers them all and a helper added later cannot bypass it.
  * the .log header — written directly rather than through event(), and a
    caller can paste a key into the task text.
  * manifest.json — _write_manifest serialises the same goal, and the manifest
    sits in the same mounted directory, so redacting only the header would
    have left the credential exposed one file over.

force=True because this is a safety boundary and must redact even with the
global toggle off. On the (impossible-in-practice) import failure the line is
withheld instead of written raw: losing a debug line costs less than writing
a live credential into a sandbox-readable file.

Key names, tool names, statuses, durations and ordinary prose are untouched,
so tail -f stays as useful as before — pinned by its own test, alongside a
whole-directory sweep asserting no file under live/<id>/ carries the raw key.
2026-07-20 06:50:31 -07:00
..