Skip to content

Security: HERMES_REDACT_SECRETS off-by-default exposes API keys in user-visible Telegram/Discord chat output #17691

@frogwraps

Description

@frogwraps

Summary

In a vanilla Hermes deployment, HERMES_REDACT_SECRETS is OFF by default. As a result, when an end user converses with the agent through the gateway (Telegram, Discord), Hermes routinely echoes back live API key values as part of its visible chat responses (and writes them verbatim into /root/.hermes/sessions/*.json). For non-technical users this is invisible until something is breached.

Reproduction (real-world deployment)

Production Hermes Agent v0.11.0 on a Hostinger KVM2 VPS (Ubuntu 24.04), HERMES_REDACT_SECRETS not set in ~/.hermes/.env.

Scanning conversation history for the exact values of credentials present in ~/.hermes/.env (read each KEY=VALUE from .env, grep -F for the value across session files):

  • 24 distinct env-defined credentials were found leaked
  • 345 files in ~/.hermes/sessions/ and ~/.hermes/memories/ contained at least one credential value
  • Top hit-counts for genuinely sensitive keys:
    • OPENROUTER_API_KEY: 412 occurrences
    • GHL_AUTH_TOKEN: 80
    • BRAVE_API_KEY: 68
    • DATAFORSEO_PASSWORD: 66
    • VAPI_AUTH_TOKEN: 50
    • AI_GATEWAY_API_KEY: 24
    • GITHUB_PAT_HERMES: 20
    • HOSTINGER_API_TOKEN: 19
    • N8N_API_KEY: 17
    • PAPERCLIP_API_KEY: 2

The session JSONs are debug dumps (related to #8518) but the same content is also visible in the user-facing chat — meaning end users read their own keys back to themselves over Telegram/Discord, and the keys persist in any cloud chat backups (Telegram cloud, Discord servers).

Impact

  • User-visible leak vector: end users who never look at JSON dumps still see keys in their chat history.
  • Cloud transit: Telegram/Discord servers now hold copies of these keys.
  • No warning at gateway startup that redaction is off; user doesn't know to opt in until they audit.

Existing partial coverage

The redaction infrastructure is already excellent — agent/redact.py has thoughtful patterns for OpenAI keys, GitHub PATs, Slack tokens, AWS keys, JWTs, Telegram bot tokens, DB connection strings, etc. tools/send_message_tool.py already imports redact_sensitive_text. The only thing missing is making it on by default.

Suggested fix (priority order)

  1. Change default to ON. _REDACT_ENABLED = os.getenv('HERMES_REDACT_SECRETS', 'true').lower() in ('1','true','yes','on') (default 'true' instead of '').
  2. Loud opt-out warning. If user explicitly sets HERMES_REDACT_SECRETS=false, gateway logs a prominent warning at startup (Secret redaction DISABLED — API keys may appear in chat output and request dumps).
  3. Startup audit. On gateway start, scan ~/.hermes/sessions/*.json mtime <30 days for credential prefix patterns; if hits found and redaction is OFF, log a one-time recommendation.
  4. Documentation. README quickstart should explicitly call out the env var (currently only in code comments).

Related

Workaround (for users hitting this now)

echo 'HERMES_REDACT_SECRETS=true' >> ~/.hermes/.env
systemctl restart hermes-gateway
# Then audit and clean ~/.hermes/sessions/ if any historical hits found

Filed via gh CLI from a real affected user's VPS after a 24-cred / 345-file remediation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Critical — data loss, security, crash looparea/configConfig system, migrations, profilescomp/gatewayGateway runner, session dispatch, deliverytype/securitySecurity vulnerability or hardening

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions