Hermes Atlas
Guide · updated October 10, 2026

How to run Hermes Agent securely

Short answer

To run Hermes Agent safely, keep its commands away from your main machine with a separate server, VM or Docker terminal backend, leave dangerous-command approval on, and let only approved users reach its messaging gateway through allowlists or DM pairing. Then restrict file writes, keep secrets in ~/.hermes/.env with tight permissions, run as a non-root user and update regularly.

What can Hermes Agent do on your machine?

On the default local terminal backend, Hermes Agent runs commands as your user account, with the same file access you have. That is what makes it useful, and it is why the docs describe a layered security model rather than a single switch:

  1. User authorization: who can talk to the agent
  2. Dangerous command approval: a human check before destructive commands
  3. File write safety: a denylist and an optional write sandbox
  4. Container isolation: hardened Docker, Singularity and Modal sandboxes
  5. MCP credential filtering: MCP servers get a filtered environment
  6. Context file scanning: prompt-injection checks on project files
  7. Cross-session isolation: sessions cannot read each other's data
  8. Input sanitization: validated working-directory parameters

Profiles are not one of these layers. A profile separates Hermes state, but it does not stop the agent from reading folders outside its profile.

Where should you run Hermes Agent?

Run it on a separate server or VM, or send its commands to a container, whenever it handles anything beyond personal experiments. The terminal backend decides where commands execute:

Backend Isolation Dangerous command check Best for
local None, runs on the host Yes Development, trusted users
ssh Remote machine Yes Running on a separate server
docker Container Skipped, the container is the boundary Production gateways
singularity Container Skipped HPC environments
modal Cloud sandbox Skipped Scalable cloud isolation
daytona Cloud sandbox Skipped Persistent cloud workspaces
vercel_sandbox Cloud microVM Skipped Cloud execution with snapshots

Switch backends with one command:

hermes config set terminal.backend docker   # Docker isolation
hermes config set terminal.backend ssh      # a remote server

For the SSH backend, the docs put the connection details in ~/.hermes/.env so they are not shared with profile exports:

TERMINAL_SSH_HOST=agent-worker.local
TERMINAL_SSH_USER=hermes
TERMINAL_SSH_KEY=~/.ssh/hermes_agent_key

This keeps the gateway's messaging connections on one machine and the agent's command execution on another.

How do command approval modes work?

Hermes checks every command against a list of dangerous patterns, and approvals.mode in ~/.hermes/config.yaml decides what happens on a match.

Mode What happens
smart (default) An auxiliary model assesses risk. Low-risk commands run, clearly dangerous ones are denied, uncertain ones prompt you
manual You are always asked
off No checks at all, the same as --yolo
approvals:
  mode: smart          # smart | manual | off
  timeout: 300         # seconds to wait before denying
  cron_mode: deny      # cron jobs that hit a dangerous command
  unattended_mode: deny  # webhook and API sessions

If nobody answers within the timeout, the command is denied. In the CLI you can approve once, for the session, always, or deny. On messaging platforms you reply yes or no. Patterns you approve with "always" go into command_allowlist in config.yaml, so review that list now and then with hermes config edit. hermes approvals suggest proposes allowlist entries from your history, never proposes destructive classes, and changes nothing until you pass --apply.

Patterns that trigger approval include recursive deletes, chmod 777, SQL DROP TABLE, piping curl output into a shell, writes into /etc/ or ~/.ssh/, and stopping system services or containers.

What are YOLO mode and the hardline blocklist?

YOLO mode skips approval prompts for one session, and the hardline blocklist is a floor that still applies when YOLO is on. You turn YOLO on with hermes --yolo, the /yolo toggle or HERMES_YOLO_MODE=1, and Hermes shows a red banner and a status bar marker while it is active.

The hardline blocklist refuses a small set of catastrophic commands no matter what: rm -rf / and its variants, fork bombs, mkfs on a mounted root device, dd onto a physical disk, and piping untrusted URLs into sh at the top level of the filesystem. There is no override flag. Run such commands outside the agent if you need them.

You can add your own permanent blocks with approvals.deny. These glob patterns are checked before YOLO and mode: off, and they apply on every backend, containers included:

approvals:
  deny:
    - "git push --force*"
    - "dd if=* of=/dev/*"

Always quote the patterns in YAML. The docs are clear that deny rules are a command policy, not an operating-system sandbox, so pair them with real isolation.

How do you harden the Docker backend?

The Docker backend already starts every container with strict defaults, and you control the resource limits and which secrets enter the container. By default each container runs with all Linux capabilities dropped except a few needed to write mounted folders and manage file ownership, no-new-privileges, a limit of 256 processes, a size-limited /tmp and a noexec /var/tmp.

terminal:
  backend: docker
  docker_forward_env: []      # keep secrets out of the container
  container_cpu: 1            # CPU cores
  container_memory: 5120      # MB
  container_disk: 51200       # MB
  container_persistent: true  # false = workspace is lost on cleanup

Any variable you add to docker_forward_env is readable by code in the container, which could leak it. For Docker you can also enable the egress credential-injection proxy with hermes egress setup && hermes egress start, so the sandbox only sees opaque proxy tokens instead of your real API keys.

How do you control who can message your agent?

The gateway denies everyone until you allow them. With no allowlists and no allow-all setting, all users are refused and the gateway logs a warning at startup. Add allowed user IDs to ~/.hermes/.env:

TELEGRAM_ALLOWED_USERS=123456789,987654321
DISCORD_ALLOWED_USERS=111222333444555666
GATEWAY_ALLOWED_USERS=123456789   # checked on every platform

Never set GATEWAY_ALLOW_ALL_USERS=true in production.

DM pairing is the more flexible option. An unknown user who messages the bot gets an 8-character code, and you approve it from the CLI:

hermes pairing list
hermes pairing approve telegram ABC12DEF
hermes pairing revoke telegram 123456789

Codes expire after an hour, requests are rate-limited, and repeated failed approvals trigger a lockout. Set unauthorized_dm_behavior to pair, ignore or decline globally or per platform.

How do you limit where the agent can write files?

Hermes blocks the write_file and patch tools from writing to credential stores such as ~/.ssh/, ~/.aws/, ~/.kube/, /etc/sudoers, ~/.netrc and Hermes' own .env, with no approval prompt and no override. The one softer case is the SSH client config, ~/.ssh/config, which goes through an approval prompt instead. To go further, set HERMES_WRITE_SAFE_ROOT so those tools can only write inside the directories you list:

export HERMES_WRITE_SAFE_ROOT=/path/to/project:/home/you/.hermes

Include the Hermes home as above, or the agent cannot update its own cron jobs and skills. Separate multiple roots with : on Unix or ; on Windows. The official Docker image sets this to /opt/data automatically.

These guards cover the file tools only. The terminal tool runs as the same user and can still change those files through shell commands, so treat write safety as a way to prevent accidents, not as containment.

What else should you lock down?

A few settings matter once the agent is reachable by others:

  • Keep security.allow_private_urls off on public gateways, so web tools cannot reach private networks or cloud metadata addresses.
  • Use security.website_blocklist to keep web and browser tools away from internal sites.
  • Give each MCP server only the variables it needs in its env block. Other secrets are stripped from MCP subprocesses.
  • Do not start hermes dashboard --host 0.0.0.0 on a shared host. Its plugin routes, including the kanban board, are unauthenticated.
  • Review any handler.py before placing it in ~/.hermes/hooks/. The gateway loads that folder at startup with no extra prompt.

What should you check before going to production?

Work through this list, based on the docs' gateway deployment checklist, before you expose an agent to other people:

  1. Set explicit allowlists or use DM pairing. Never use GATEWAY_ALLOW_ALL_USERS=true.
  2. Use terminal.backend: docker, another sandbox, or ssh to a separate machine.
  3. Set CPU, memory and disk limits for the container.
  4. Keep API keys in ~/.hermes/.env and run chmod 600 ~/.hermes/.env. Never commit it.
  5. Keep docker_forward_env empty unless a task needs a specific credential.
  6. Leave approvals.mode on smart or manual. Keep off and YOLO for disposable environments.
  7. Review command_allowlist in config.yaml periodically.
  8. Set terminal.cwd so the agent does not start in a sensitive directory.
  9. Run the gateway as a non-root user.
  10. Check ~/.hermes/logs/ for unauthorized access attempts.
  11. Run hermes update regularly for security fixes.

FAQ

Is it safe to run Hermes Agent on my laptop?

On the local backend, Hermes runs commands with your user account's permissions. Command approval and the file write denylist reduce accidents but are not a sandbox, so use a Docker backend or a separate machine for anything you do not fully trust.

What does smart approval mode do?

Smart mode, the default, asks an auxiliary model to assess each dangerous command. Low-risk commands run, clearly dangerous ones are denied, and uncertain ones prompt you for a decision.

Does YOLO mode turn off every safety check?

No. YOLO mode skips approval prompts for the session, but the hardline blocklist and your approvals.deny rules still block their commands.

Who can message my Hermes bot by default?

Nobody. If you have set no allowlists and no allow-all option, the gateway denies every user and logs a warning, so you must add user IDs or approve users through DM pairing.

Why does Hermes skip dangerous-command checks in Docker?

With the docker, singularity, modal, daytona or vercel_sandbox backends, the container is treated as the security boundary, so destructive commands cannot harm the host. Your approvals.deny rules still apply on every backend.

Sources

Repos to try next

Browse the category