Learn Hermes Agent Advanced: Automation, Integrations & Production Security and Production Hardening

Security and Production Hardening

Advanced 🕐 28 min Lesson 15 of 16
What you'll learn
  • Explain the layered gateway authorization check and the role of DM pairing codes
  • Choose the appropriate command approval mode (manual/smart/off) and understand the hardline blocklist that applies regardless of mode
  • Explain why local backend checks for dangerous commands while Docker/Singularity/Modal/Daytona skip that check
  • Identify the categories of commands flagged as dangerous, and the SSRF protections applied to any URL-fetching tool
  • Work through the production deployment checklist before exposing a gateway, scheduled job, or API server beyond personal supervised use

Why This Lesson Comes Near the End, Not the Start

Every individual lesson in this track has mentioned a piece of security behavior in passing -- backup-before-write for memory, credential stripping in code execution, deny-by-default gateway access, blocked paths for context references. This lesson pulls all of it into one place and adds the parts that only matter once you put the pieces together: an agent running unattended, reachable from outside, connected to external tools.

Gateway Authorization: A Layered Check

When a message arrives on any messaging platform, Hermes checks authorization in a specific order: per-platform allow-all flags first, then DM pairing approvals, then platform-specific allowlists, then global allowlists, and only after all of those fail does it default to deny. DM pairing works through short, unambiguous codes -- 8 characters drawn from a 32-character alphabet specifically chosen to avoid easily-confused characters, expiring after 1 hour, approved by the bot owner via CLI.

Command Approval: Three Modes

  • manual -- always prompts you before running a potentially risky command
  • smart -- an auxiliary LLM assesses risk and decides whether to prompt
  • off -- disables the approval check entirely

Regardless of which mode you choose, a hardline blocklist exists underneath all of them, covering catastrophic operations -- rm -rf /, fork bombs, filesystem formatting. This blocklist cannot be bypassed even with YOLO mode active or a permissive user allowlist configured. Some things Hermes will simply refuse to do, full stop.

Sandboxing: Where the Boundary Actually Lives

Docker-backed execution runs with dropped Linux capabilities, no-new-privileges restrictions, a 256-process limit, and size-limited tmpfs mounts using rw,nosuid,noexec flags. There is a deliberate split in how dangerous-command checking works depending on backend: the local backend actively checks for dangerous commands before running them, while Docker, Singularity, Modal, and Daytona skip that check entirely -- because in those cases the container itself is the security boundary, and a command-pattern check would be redundant on top of actual process isolation.

What Counts as "Dangerous"

The detection system flags recursive deletes, world-writable permission changes, SQL DROP/TRUNCATE statements, attempts to overwrite files under /etc/, commands that disrupt running services, shell piping patterns like curl | sh, and privilege escalation attempts.

SSRF Protection

Any tool capable of fetching a URL -- web extraction, browser automation, MCP HTTP servers -- validates the destination before connecting. Blocked: private networks (RFC 1918 ranges), loopback addresses, link-local addresses, and cloud metadata endpoints (the kind of internal address that, if reachable, can leak cloud credentials). A DNS resolution failure is treated as blocked by default, rather than silently allowed through.

Prompt Injection Defense

Context files from Hermes Agent Fundamentals are scanned for hidden instructions, suspicious HTML comments, credential theft patterns, and invisible Unicode characters before they are ever included in a system prompt. A file that trips these checks is blocked outright, with a warning shown to you -- it does not load silently and quietly do something unexpected.

MCP Credential Filtering

MCP server subprocesses, from Lesson 6, receive only a minimal safe set of environment variables -- PATH, HOME, LANG, TERM, and similar -- plus whatever you explicitly configured for that specific server. Error messages coming back from MCP tools are sanitized to redact GitHub personal access tokens, OpenAI keys, bearer tokens, and similar credential patterns before you ever see them, in case an underlying tool's error output happened to leak one.

The Production Deployment Checklist

If you are running Hermes connected to messaging platforms, on a schedule, or reachable via the API server from Lesson 7, this is the concrete list worth working through, not just reading:

  • Use explicit allowlists -- never set GATEWAY_ALLOW_ALL_USERS=true on anything reachable from outside your own devices
  • Prefer container backends (Docker and similar) over local execution for anything processing untrusted input
  • Set appropriate resource limits rather than relying on defaults tuned for personal, supervised use
  • chmod 600 your .env file -- it contains every secret Hermes has access to
  • Prefer DM pairing over hardcoded user IDs -- pairing codes expire and can be individually revoked, hardcoded IDs cannot
  • Audit your allowlists periodically -- access that made sense six months ago may not still be appropriate
  • Run as a non-root user, not as root, even though it may be more convenient initially
  • Monitor logs (hermes logs, from earlier in this track) rather than assuming silence means everything is fine
  • Keep Hermes updated regularly (hermes update) rather than running an old version indefinitely

For genuinely sensitive deployments, the documentation recommends going further: run the gateway on a separate machine from your primary workstation, using an SSH terminal backend, with connection details kept in .env rather than shared configuration -- network isolation as a real architectural choice, not just a setting.

The Underlying Principle

Every defense in this lesson follows the same shape: defaults that fail closed (deny, block, refuse) rather than fail open (allow, proceed, trust), with explicit, deliberate configuration required to widen access. That principle is worth carrying forward into anything you build with Hermes that this track did not specifically cover -- when you are not sure whether something should be restricted by default, restrict it, and open it up deliberately once you have actually thought through why.

The final lesson in this track ties everything from both Hermes Agent Fundamentals and everything covered here into one real, working capstone build.

Key takeaways
  • The hardline command blocklist (rm -rf /, fork bombs, filesystem formatting) cannot be bypassed by YOLO mode or a permissive allowlist -- some operations are refused unconditionally regardless of configuration
  • Local backend actively checks for dangerous commands; Docker/Singularity/Modal/Daytona skip that check because the container itself is the security boundary -- this is a deliberate design choice, not an inconsistency
  • SSRF protection blocks private networks, loopback, link-local, and cloud metadata addresses for any tool that fetches a URL -- and treats DNS failures as blocked rather than silently passing them through
  • Never set GATEWAY_ALLOW_ALL_USERS=true on anything reachable from outside your own devices -- this is the single most consequential checklist item for a production gateway
  • Every defense in Hermes follows the same shape: fail closed by default, require explicit configuration to widen access -- apply that same principle to anything this track did not specifically cover