Skip to content

feat(security): mask opaque credential values in log output - #77014

Closed
andrexibiza wants to merge 2 commits into
NousResearch:mainfrom
andrexibiza:fix/security-redact-passwords-and-bws-token
Closed

feat(security): mask opaque credential values in log output#77014
andrexibiza wants to merge 2 commits into
NousResearch:mainfrom
andrexibiza:fix/security-redact-passwords-and-bws-token

Conversation

@andrexibiza

Copy link
Copy Markdown
Contributor

What changed and why

RedactingFormatter (used by every Hermes log handler) already ran the shape-based regex redactor — vendor prefixes (sk-, ghp_), auth headers, URLs — on every log record. But opaque credential values with no recognizable prefix passed through log output unmasked: MY_SERVICE_TOKEN=abc123randomstring, BWS_ACCESS_TOKEN, *_PASSWORD values.

This PR wires the exact-value pass (mask_known_secret_values) into RedactingFormatter.format(), so every log record also masks the literal values of credential-named env vars.

Why this matters to you as a user

A log line that happens to include a secret's value — an error message echoing a token, a debug line printing a connection string — no longer writes that value into your log files. The diagnostic text survives; the secret doesn't. This closes the value-in-logs half of the disclosure class for every Hermes user, not just BWS users.

Reproduction steps (current behavior on main)

  1. export MY_SERVICE_TOKEN=opaque-secret-value-xyz
  2. Log a message containing that value (e.g. logger.warning("starting with opaque-secret-value-xyz")).
  3. Observe the gateway/log file — the value appears verbatim.

Current: opaque credential values written to logs.
Expected: value replaced with ***; surrounding diagnostic preserved.

How to test

  • scripts/run_tests.sh tests/agent/test_redact.py → 76 passed (3 new: opaque _TOKEN value, _PASSWORD value, and BWS_ACCESS_TOKEN value masked in formatted log records).

Platforms tested

  • Windows 11 (git-bash), Python 3.11, canonical scripts/run_tests.sh.
  • git diff --check clean; check-windows-footguns.py clean on changed files.

Stacking note (important)

This PR is stacked on #77012 (fix(security): mask secret values in secret-source status lines), which introduces mask_known_secret_values in agent/redact.py. Because the fork-based base branch isn't addressable upstream, this PR currently targets main and therefore includes #77012's commit in its diff. Please review/merge #77012 first, then this one — after #77012 lands on main, this PR can be rebased and its diff shrinks to exactly the formatter wiring + tests. The formatter change itself does not depend on anything else.

Related

The startup status block in env_loader prints error, remediation-hint,
warning, and conflict lines straight to stderr. The merged secret-name
suppression (NousResearch#60295/NousResearch#69054) removed the applied-name list, but a source
error or warning that echoes a secret VALUE would still print it.

This change routes all four status-line types through a value masker:
- agent.redact.mask_known_secret_values() masks the exact values of
  credential-named env vars (opaque tokens with no vendor prefix)
- env_loader._mask_secret_text() additionally masks every value applied
  from external secret sources this process (Bitwarden/1Password), which
  is the authoritative set for what the status line is about

Why this matters to users: secret names already stopped being printed;
now secret values cannot leak through error or warning text either. If a
backend echoes a key back in an error message, you see the diagnostic
without the key.

Tests: 67 passed across env_loader + secret-sources suites (2 new
regression tests: value in warning masked, value in error masked) plus
the existing 76-test redact suite.
RedactingFormatter already ran the shape-based regex redactor
(vendor prefixes, auth headers, URLs) on every log record. Opaque
credential values with no recognizable prefix — MY_SERVICE_TOKEN=abc123,
BWS_ACCESS_TOKEN, *_PASSWORD vars — passed through log output unmasked.

This wires the exact-value pass (mask_known_secret_values, added in the
sibling status-line PR) into RedactingFormatter.format(), so every log
record also masks the literal values of credential-named env vars.

Why this matters to users: a log line that happens to include a secret's
value — an error echoing a token, a debug line printing a connection
string — no longer writes that value to your log files. The diagnostic
text survives; the secret doesn't.

Stacked on fix/security-secret-source-status-formatter (NousResearch#77012) which
adds mask_known_secret_values to agent/redact.py. This PR contains only
the formatter wiring + tests on top of that base.

Tests: 76 redact tests pass (3 new: opaque value, *_PASSWORD value, and
BWS_ACCESS_TOKEN value masked in log records); 99 across the redact +
env_loader suites via scripts/run_tests.sh.
@andrexibiza

Copy link
Copy Markdown
Contributor Author

Closing: this change is being folded into #77012 instead of stacked. The formatter wiring uses the same mask_known_secret_values function added there — keeping it as a separate stacked PR pollutes the review diff. Will land as an additional commit on #77012 once #77012's base is clean.

@andrexibiza andrexibiza closed this Aug 2, 2026
@andrexibiza
andrexibiza deleted the fix/security-redact-passwords-and-bws-token branch August 2, 2026 18:41
@alt-glitch alt-glitch added type/security Security vulnerability or hardening comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard area/auth Authentication, OAuth, credential pools P3 Low — cosmetic, nice to have sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data labels Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants