Skip to content

Security

An agent with full system access is a powerful tool and a powerful liability. Hermes ships with several security layers that are on by default, secret redaction, command approval, and context file scanning, and several more you configure based on your risk tolerance. This lesson covers the full security surface and how to tune it for production.

Owl mascot

What you'll learn

  • Secret redaction is on by default, tool output is scanned for API keys, tokens, and secrets before it reaches the model
  • Command approval has three modes: smart (auto-approve safe, deny dangerous, prompt for uncertain), manual (always prompt), and off (YOLO)
  • The threat-pattern scanner inspects context files and tool output for prompt injection before they reach the model

The problem

An agent with terminal access and an API key to a model provider has two attack surfaces that a chatbot doesn't: it can execute commands on your system, and it can be tricked into doing so by malicious input. The security layers in Hermes are designed to make the first surface manageable and the second surface visible, without making the agent so locked down it can't do useful work.

Options & when to use each

LayerWhat it protectsDefaultWhen to change it
Secret redactionAPI keys, tokens, secrets in tool outputOnTurn off only for debugging credential-related issues
PII redactionUser IDs, phone numbers in gateway messagesOffTurn on for multi-user deployments where privacy matters
Command approvalDestructive shell commands (rm -rf, git reset --hard, etc.)Smart modeSwitch to manual for high-security environments; off for fully trusted scripts
Context file scanningPrompt injection in .hermes.md, AGENTS.md, etc.On (automatic)Can't be disabled, always scans
Shell hooks allowlistWhich shell integrations can firePrompted on first useManage via ~/.hermes/shell-hooks-allowlist.json
Container isolationFilesystem, network, and process boundariesOff (local backend)Enable Docker backend for any untrusted workload

Build it

Layer 1 , Secret redaction (verify it's on)

Ensure your configuration intercepts sensitive strings before they reach external APIs. This provides an essential safety net for local development and CI pipelines.

bash
hermes config set security.redact_secrets true

This is on by default. It scans every tool output, terminal stdout, read_file results, web content, subagent summaries, for strings that look like API keys, tokens, and secrets before they enter the conversation context. The scan runs before the model sees the output, so even if a file on disk contains a secret, the model never sees it.

Important: security.redact_secrets is snapshotted at import time. Toggling it mid-session (e.g., via export HERMES_REDACT_SECRETS=false from a tool call) will NOT take effect for the running process. Change it in config from a terminal, then start a new session. This is deliberate, it prevents an LLM from flipping the toggle on itself mid-task.

Layer 2 , Command approval

Control how strictly the agent executes terminal commands. The smart setting intercepts potentially destructive operations while permitting standard read actions.

bash
hermes config set approvals.mode smart

The three modes:

ModeBehaviorWhen to use
smartAuto-approve low-risk commands, deny high-risk, prompt for uncertainRecommended default. Balances safety with usability
manualAlways prompt for approval before executing any shell commandHigh-security environments, multi-user deployments, any situation where you want an audit trail
offSkip all approval promptsFully trusted, automated scripts. Equivalent to --yolo

Per-invocation bypass without changing config:

bash
hermes --yolo chat -q "Clean up old Docker images"
export HERMES_YOLO_MODE=1

Note: YOLO / approvals.mode: off does NOT turn off secret redaction. They are independent.

Layer 3 , PII redaction (gateway only)

Toggle privacy controls to anonymize data leaving the gateway. This step is critical if your logs or sessions interact with public models.

bash
hermes config set privacy.redact_pii true

When enabled, the gateway hashes user IDs and strips phone numbers from the session context before it reaches the model. This is separate from secret redaction and only applies to gateway messages.

Layer 4 , Container isolation

For any workload where the agent runs untrusted code or processes user-uploaded files, use the Docker backend with strict limits:

yaml
terminal:
  backend: docker
  docker:
    memory: "2g"
    cpus: "1.0"
    network: "none"
    user: "1000:1000"
    read_only: true  # filesystem is read-only except for mounted volumes
    tmpfs: "/tmp"    # temporary writable space

For maximum security with untrusted code execution, consider gVisor (runsc) instead of the standard Docker runtime:

bash
hermes config set terminal.docker.runtime "runsc"

gVisor provides microVM-level isolation, it intercepts all system calls rather than sharing the host kernel. The tradeoff is a slight performance penalty and more complex setup.

What goes wrong

MistakeHow you notice itThe fix
Secrets appearing in conversationHermes reads a .env file and echoes an API key in its responseVerify security.redact_secrets: true is set. The scanner runs before the model sees the output, but if a secret is in a format the scanner doesn't recognize, it won't be caught. Never store secrets in files the agent can read
Agent locked down too tightlyEvery command requires approval, slowing work to a crawlSwitch from manual to smart mode. Smart mode auto-approves commands it's confident are safe, so you only get prompted for genuinely risky operations
YOLO mode used accidentallyYou realize afterward that the agent ran commands you didn't reviewYOLO is per-invocation, it doesn't persist. If you want it permanently off, ensure approvals.mode is not set to off in config
Redaction toggle not taking effectYou changed security.redact_secrets but secrets still appearThe setting is snapshotted at process start. Exit Hermes and relaunch for the change to take effect

Confirm it worked

Test your security settings directly in the CLI. Make sure the outputs align with your expected configuration and safely block risky commands.

bash
# 1. Verify secret redaction is on
hermes config | grep redact_secrets

# 2. Verify approval mode
hermes config | grep "approvals.mode"

# 3. Test command approval: run a command that should trigger it
hermes chat -q "Delete the file /tmp/test_hermes_security.txt if it exists"

# 4. If approval mode is smart, harmless commands should auto-approve.
# A destructive command like 'rm -rf /' should be denied.

Next: MCP Servers , connecting Hermes to external tools through the Model Context Protocol.