hermes - 💡(How to fix) Fix Pre-send secret redaction hook + piiapi-filter skill

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

try: from agent.redact import redact_sensitive_text as _rst for _msg in api_messages: if isinstance(_msg.get("content"), str): _msg["content"] = _rst(_msg["content"]) elif isinstance(_msg.get("content"), list): for _part in _msg["content"]: if isinstance(_part, dict) and "text" in _part: _part["text"] = _rst(_part["text"]) except Exception: pass # Non-fatal — redaction must never block the API call

Fix Action

Fix / Workaround

gateway/run.py — Removed dead dispatch (marked cli_only)

Complete Patch

Full diff (including the skill SKILL.md) is attached. Apply with:

git apply piiapi-filter-patch.diff

Code Example

try:
    from agent.redact import redact_sensitive_text as _rst
    for _msg in api_messages:
        if isinstance(_msg.get("content"), str):
            _msg["content"] = _rst(_msg["content"])
        elif isinstance(_msg.get("content"), list):
            for _part in _msg["content"]:
                if isinstance(_part, dict) and "text" in _part:
                    _part["text"] = _rst(_part["text"])
except Exception:
    pass  # Non-fatal — redaction must never block the API call

---

CommandDef("piiapi", "PIIAPI filter — toggle outbound secret redaction and set sensitivity",
           "Tools & Skills", cli_only=True, args_hint="[on|off|status|low|medium|high]",
           subcommands=("on", "off", "status", "low", "medium", "high")),

---

"piiapi_filter": False,  # Auto-load piiapi-filter skill at startup

---

git apply piiapi-filter-patch.diff
RAW_BUFFERClick to expand / collapse

piiapidiff.txt

piiapi-filter-issue.md

Suggestion: Pre-send secret redaction hook + piiapi-filter skill

Problem

Hermes already has agent/redact.py with 25+ regex patterns for masking API keys, tokens, passwords, and PII. But redact_sensitive_text() is only applied to assistant responses (after the model replies) and some tool output paths. User messages, the system prompt, and many tool results go to the cloud model completely raw.

For users on cloud providers that may train on prompts (free-tier OpenRouter, DeepSeek, Gemini, Claude, etc.), this means secrets, credentials, and PII can enter training pipelines unintentionally.

Proposed Solution

Two complementary layers:

Layer 1 — Mechanical (1 hook, ~6 lines): Add a redact_sensitive_text() call at the top of build_api_kwargs() in agent/chat_completion_helpers.py. This catches ALL outbound messages — user messages, system prompt, tool results, assistant content — in one pass before they reach any API transport. Controlled by the existing security.redact_secrets config gate.

Layer 2 — Behavioral (skill): A piiapi-filter skill that instructs the agent to self-police file reads, terminal output, git diffs, and memory for secrets before presenting them.

CLI integration:

  • /piiapi slash command (on/off/status/low/medium/high)
  • security.piiapi_filter: false config option for auto-start

Files Changed

agent/chat_completion_helpers.py — Pre-send redaction hook

try:
    from agent.redact import redact_sensitive_text as _rst
    for _msg in api_messages:
        if isinstance(_msg.get("content"), str):
            _msg["content"] = _rst(_msg["content"])
        elif isinstance(_msg.get("content"), list):
            for _part in _msg["content"]:
                if isinstance(_part, dict) and "text" in _part:
                    _part["text"] = _rst(_part["text"])
except Exception:
    pass  # Non-fatal — redaction must never block the API call

hermes_cli/commands.py — CommandDef

CommandDef("piiapi", "PIIAPI filter — toggle outbound secret redaction and set sensitivity",
           "Tools & Skills", cli_only=True, args_hint="[on|off|status|low|medium|high]",
           subcommands=("on", "off", "status", "low", "medium", "high")),

hermes_cli/config.py — Config option

"piiapi_filter": False,  # Auto-load piiapi-filter skill at startup

cli.py — Handler + auto-start

  • _handle_piiapi_command() — full handler with on/off/status/sensitivity
  • Auto-start: if CLI_CONFIG.security.piiapi_filter is true, preloads the skill at startup

gateway/run.py — Removed dead dispatch (marked cli_only)

Complete Patch

Full diff (including the skill SKILL.md) is attached. Apply with:

git apply piiapi-filter-patch.diff

Dependencies

  • The piiapi-filter skill must be installed to ~/.hermes/skills/security/piiapi-filter/SKILL.md for the /piiapi on command to work
  • The skill is purely behavioral — the pre-send hook works independently

Known Design Constraints

  1. Sensitivity levels (low/medium/high) control conversational warnings, not mechanical redaction — the hook always runs at full strength
  2. No code_file exemption — API_TIMEOUT=30 style code may trigger false env-assignment redaction in rare cases
  3. CLI-only for now — gateway not wired
  4. /piiapi off removes from preloaded list but skill content persists in system prompt until /reset
  5. Anthropic multi-part content blocks (type: "image", type: "tool_use") not recursed — low risk since text in those blocks still passes through standard patterns

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING