Hermes Agent hermes-agent.nousresearch.com ↗
Self-hosted multi-channel agentic harness. Four entry points: CLI, Gateway (20+ messaging platforms), ACP stdio/JSON-RPC, batch runner. Pairs with Hermes 3/4 LLMs (high steerability, low refusal). Seven terminal backends. SECURITY.md (rewritten 2026-05): "OS-level isolation is the only load-bearing trust boundary" — in-process approval gates, redaction, regex scanners are explicitly out-of-scope. v0.14.0 (2026-05-16) "security wave" ships redaction default-on, Discord guild scoping, WhatsApp stranger-rejection, sudo-bypass detection, supply-chain advisory checker. Anything < v0.14.0 leaks credentials in chat output by default.
HERMES_REDACT_SECRETS was off by default and outbound chat messages bypassed redact_sensitive_text in gateway platform adapters (Issue #17691 + Issue #23810). v0.14.0 closes the headline issue — upgrade or set HERMES_REDACT_SECRETS=1 and audit gateway platform adapters on older versions. The same release also fixed a CVSS 8.1 cross-guild Discord DM bypass.Version Pinning / Install Provenance / Model Selection
Hermes ships from github.com/NousResearch/hermes-agent under MIT; current stable v0.14.0 / v2026.5.16 (2026-05-16, "security wave"). The default installer is a curl | bash from hermes-agent.nousresearch.com/install.sh — convenient, but bypasses signature verification. Prefer cloning at a tagged release. v0.14.0 also adds a built-in supply-chain advisory checker that scans every install for unsafe dependency versions; run it after each upgrade. The [all] extras were restructured so heavy/risky backends (Hindsight client, image gen, voice/TTS) are lazy-installed on first use — pin a lean extras set unless you need them.
git clone --branch v2026.5.16 https://github.com/NousResearch/hermes-agent.git
cd hermes-agent && git verify-tag v2026.5.16 && ./setup-hermes.sh
hermes config set model.default nousresearch/hermes-4-405b
hermes config set model.provider main
hermes security advisories checkTip: never curl | bash to production; pin a git tag, audit the installer, pin model IDs. Anything < v0.14.0 leaks credentials into chat output by default — upgrade as a priority, or at minimum set HERMES_REDACT_SECRETS=1 and audit gateway adapters.
Server / API Exposure (Gateway, ACP, Batch)
CLI is local-only, but the Gateway is a persistent server that connects outward to messaging platforms — meaning anyone who DMs your bot is a potential prompt source. ACP runs over stdio (safe). Run the Gateway as a non-root user, on a dedicated host or VM, with outbound egress filtered to provider APIs only.
# ~/.hermes/config.yaml
gateway:
unauthorized_dm_behavior: ignore
terminal:
backend: dockerTip: treat the Gateway like a public-facing bot — separate host, dedicated UNIX user, egress allowlist, no local terminal backend.
Authentication (Gateway Authorization + DM Pairing)
Hermes does not use OAuth/SSO for the agent itself; it authorizes inbound users through a 6-step check chain. Default is deny. Use explicit allowlists; never set *_ALLOW_ALL_USERS=true in production. The DM-pairing flow issues 8-char codes for unknown users that the owner must approve out-of-band.
# ~/.hermes/.env
TELEGRAM_ALLOWED_USERS=123456789,987654321
GATEWAY_ALLOWED_USERS=123456789
# NEVER:
# GATEWAY_ALLOW_ALL_USERS=true
hermes pairing list
hermes pairing approve telegram ABCD1234
hermes pairing revoke telegram 555555Tip: explicit per-platform allowlists + unauthorized_dm_behavior: ignore; audit hermes pairing list weekly. v0.14.0 scopes Discord role allowlists to their guild (closes a CVSS 8.1 cross-guild DM bypass) and makes WhatsApp reject messages from unknown contacts by default.
Isolation / Sandboxing of Tool Execution
Seven terminal backends. The local default is unsandboxed — only protected by in-process "dangerous command" heuristics which SECURITY.md explicitly disclaims as non-boundaries. Switch to docker (or modal / daytona / vercel_sandbox for cloud) so the container becomes the actual trust boundary. execute_code and MCP subprocesses can still reach host state — only whole-process wrapping closes that gap.
terminal:
backend: docker
timeout: 180
container_cpu: 1
container_memory: 5120
container_disk: 51200Tip: Docker terminal backend for tools and run the whole Hermes process inside its own container for defense in depth. Container-backend caveat (community audit #7826, finding C3): containerized backends skip all in-process approval checks by design — so the container itself must be tightly configured (read-only root, dropped caps, no host mounts, no SSH-agent forwarding). Operators cannot lean on the approval prompt there. Pair with explicit HERMES_WRITE_SAFE_ROOT (opt-in by default — finding H4).
Tool Allowlist / Function-Calling Restrictions
70+ tools auto-register from tools/registry.py across ~28 toolsets. The Hermes 4 model emits XML <tool_call> blocks with high reliability — anything you leave enabled, the model will use.
agent:
disabled_toolsets:
- memory
- browser
- image_generationTip: start from a minimal allowlist (deny-by-default toolset list) and re-enable only what a given workflow demands. v0.14.0 closed three known bypasses of the dangerous-command detector and now flags sudo -S plus stdin-fed / askpass-stripped sudo as DANGEROUS; unnecessary shell=True subprocess calls were removed across the codebase to shrink shell-injection surface. The in-process gate is hardened but still not load-bearing per SECURITY.md — OS isolation is the only trust boundary.
Credential / API Key Handling
Hermes stores secrets in ~/.hermes/.env (auto-routed by hermes config set) and OAuth tokens in ~/.hermes/auth.json. Critically, execute_code and terminal strip API keys from child-process env by default; only vars in required_environment_variables (skill manifest) or terminal.env_passthrough are forwarded.
chmod 700 ~/.hermes && chmod 600 ~/.hermes/.env ~/.hermes/auth.json
hermes config set OPENROUTER_API_KEY sk-or-...Tip: chmod 600 the env file, audit terminal.env_passthrough and every skill's required_environment_variables, rotate provider keys quarterly, scope each key (OpenRouter sub-keys per skill). v0.14.0 flips HERMES_REDACT_SECRETS to default-on and routes all outbound chat messages through redact_sensitive_text in gateway platform adapters; hermes debug share also redacts payloads before upload. TOCTOU races in auth.json + MCP OAuth flow were closed in the same release.
Plugin / MCP / Tool Registry Vetting
Plugins load from three sources at import time: ~/.hermes/plugins/, .hermes/plugins/, and pip entry points — each is arbitrary Python executed in-process. Skills from the community Skills Hub are flagged as the top supply-chain risk. MCP servers get no default authentication or capability scoping.
ls ~/.hermes/plugins/ ~/.hermes/skills/
pip list | grep -i hermes
hermes config edit # inspect mcp: sectionTip: treat plugins and skills as code dependencies — git-pin, code-review, never auto-update from the Hub; run MCP servers themselves in containers. v0.14.0 sanitizes tool error strings before re-injection into model context (closes prompt-injection via crafted stderr), covers remaining SSRF fetch paths in the skills hub, and gates plugin API routes behind dashboard authentication — so dashboard credentials are now a higher-value target (use strong auth + non-default bind). Persistent skills (community audit #7826, finding C4): writeable ~/.hermes/skills/ enables cross-session prompt-injection persistence — make it read-only or audit weekly for new files.
Prompt Injection Defense (and the Hermes-LLM Tradeoff)
Hermes 4 is explicitly tuned for high steerability and low refusal — it follows system prompts strictly, including malicious ones. This makes prompt injection from retrieved context (web pages, memory, AGENTS.md, .cursorrules, SOUL.md) more dangerous than against more refusal-heavy models. Hermes Agent includes the tirith pre-exec scanner, SSRF blocking, and context-file injection scanning.
security:
tirith_enabled: true
tirith_timeout: 5
tirith_fail_open: false # FAIL CLOSED in production
allow_private_urls: false
approvals:
mode: manual # never `off`; `smart` only with audit
timeout: 60Tip: approvals.mode: manual, tirith_fail_open: false, never disable SSRF protection, treat every retrieved document as hostile input.
Updates / Model Upgrades / Telemetry
Updates flow through hermes update. Tirith itself auto-installs from GitHub releases with SHA-256 checksum verification on first use. Model upgrades through the provider abstraction are silent if you use floating aliases — pin model versions. The SOUL.md / personality system is part of the supply chain.
hermes update
hermes doctor
git -C ~/.hermes/skills log --onelineTip: stage updates in a non-production profile first; subscribe to NousResearch/hermes-agent releases. CVE-2026-7396 (WeChat adapter path traversal) is the only public CVE to date — assume more will land.
Logging / Monitoring / Audit Trail
Hermes writes to ~/.hermes/logs/ and stores sessions in ~/.hermes/sessions/; tool calls and approvals flow through the event hooks system, which can dispatch to webhooks. Memory writes hit a SQLite + FTS5 store — invaluable for forensics, but also the prime injection target.
hooks:
on_tool_call:
- webhook: https://siem.internal/hermes
on_approval_request:
- webhook: https://siem.internal/hermes/approvalsTip: ship ~/.hermes/logs/ and tool-call hooks to your SIEM, snapshot the SQLite memory DB daily for tamper detection, alert on approvals.mode changes and any /yolo toggle.