Hermes Agent

Hermes extends exact-value redaction into file reads

Hermes Agent has two competing implementations for exact-value secret masking in file-read paths, plus a separate patch that makes terminal provider failures name the provider, model and endpoint. The security work is opt-in and runs before the ordinary redaction gate; one variant closed while another remained open.

← Back to homeOriginal source ↗

NousResearch/hermes-agent PR #72807 is the inspected primary source: “fix(security): apply secret redaction to config files read via file_read tool (#72778).” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- NousResearch/hermes-agent PR #72807 was created 2026-07-27T18:07:20Z and was open at inspection; its title is “fix(security): apply secret redaction to config files read via file_read tool (#72778).” - NousResearch/hermes-agent PR #78054 was created 2026-08-03T23:18:24Z and was closed at inspection; its title is “fix(security): add security.literal_secrets config to redact exact strings in file_read mode (#72778).” - NousResearch/hermes-agent PR #66352 was created 2026-07-17T14:28:33Z and was open at inspection; its title is “fix(agent): include provider/model/endpoint in terminal API failure messages.” - The repository reported 224899 stars, 27235 open issues, default branch main, and last push 2026-08-04T00:19:52Z. - The latest tagged-release baseline checked was v2026.8.3 published 2026-08-03T16:57:52Z.

What changed

NousResearch/hermes-agent PR #72807 reports: Summary Adds an opt-in redaction.literal_secrets config list that lets users specify exact strings (and/or ${ENV_VAR} references) to be redacted by exact substring match in redact_sensitive_text(). This runs **before** the enable-gate, so it covers ALL paths including file_read, where the ENV/JSON-assignment regex passes are intentionally skipped for false-positive avoidance. Fixes #72778 Changes agent/redact.py Added module-level _literal_secrets: list[str] and _literal_secrets_loaded flag Added _ensure_literal_secrets() — one-time lazy loader from config.yaml (redaction.literal_secrets), with ${ENV_VAR} reference resolution Added set_literal_secrets() — explicit programmatic setter for tests Injected literal secrets masking at the top of redact_sensitive_text(), **before** the force or _REDACT_ENABLED gate Updated docstring to document the new feature tests/agent/test_redact.py Added TestLiteralSecrets class with 9 tests covering: Basic exact-substring masking Empty list (passthrough) Multiple secrets file_read=True path Global redaction disabled (before-enable-gate behavior)

NousResearch/hermes-agent PR #78054 reports: Summary Fixes issue #72778: The path (used by,, ) skips ENV assignment and JSON field redaction, causing secrets in config files (, JSON configs) to leak. Changes 1. ****: Added to the default security config 2. ****: Updated security config comments with documentation for 3. ****: Added function that loads and expands references from config Applied literal secrets redaction BEFORE the enable gate so it covers paths Uses sentinel mask to prevent round-trip corruption 4. ****: Added comprehensive test class (6 tests) How it works Users can now configure exact strings to redact in their config: These are redacted by exact substring match **before** the global redaction gate, so they work even when: (which skips ENV/JSON passes) Global is set The text doesn't

NousResearch/hermes-agent PR #66352 reports: Fixes #66351 Problem When an API call exhausts its retries during a chat session, the user sees e.g.: with no indication of which provider/model/endpoint failed. The retry loop already prints this context on every attempt, but only via _buffer_vprint (verbose log output) — chat sessions never see it. The internal logger.error also carries provider=... model=..., but the user-facing final_response dropped it. (The Client error:... text itself is httpx's HTTPStatusError string bubbling through _summarize_api_error().) Change agent/conversation_loop.py** — append provider/model/endpoint to final_response on both terminal error paths: **Retry-exhausted** — the "API call failed after N retries:..." message now ends with (provider:..., model:..., endpoint:...) **Non-retryable abort** — immediate hard-4xx failures get the same context suffix gateway/run.py** — raise _looks_like_gateway_provider_error's length heuristic from 400

Why it matters

Config files are precisely where name-pattern redaction is least reliable: a secret can sit in YAML or JSON without looking like an environment assignment. Exact-value masking closes that gap, but duplicated implementations and config namespaces need reconciliation before operators can rely on one contract. The operator test is whether persisted state, execution authority and the visible user outcome describe the same event after retries, restarts or delegation.

Current

The primary record was open when captured on 2026-08-04. The release baseline was v2026.8.3 published 2026-08-03T16:57:52Z. Repository metadata, pull requests, issues, release records, Google News discovery, Hacker News discovery, Lobsters, Metamesh and the rendered ClawCharts row were checked. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/NousResearch/hermes-agent/pull/72807. Supporting records are https://github.com/NousResearch/hermes-agent/pull/78054 and https://github.com/NousResearch/hermes-agent/pull/66352. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts, reproductions and deployment observations remain attributed to their authors unless explicitly identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Choose one configuration namespace and loader, test exact-value masking across every file tool, and keep richer terminal diagnostics sanitized on chat surfaces. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently after intervention.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.