Hermes Agent
Hermes Agent runs as a gateway service with a terminal backend, a browser tool and MCP servers. This guide assigns the gateway host one policy and the terminal backend a second, so every destination the agent reaches is inventoried, held when first seen, and logged.
- Runs as
- systemd service, Hermes Desktop, or the official Docker image
- Configuration
- ~/.hermes/config.yaml, ~/.hermes/.env
- Terminal backend
- local, docker, ssh, singularity, modal, daytona, vercel_sandbox
- Covered here
- local, docker and ssh backends; the compose deployment
Configuration and reference code for Hermes Agent
Why
Hermes executes shell commands the model writes. The vendor egress guide for Docker routes HTTP through an allowlisting proxy and states that DNS resolution on the isolated network remains open. Agent DNS closes that gap and adds what a proxy allowlist cannot: an inventory per agent, a hold on first-seen destinations, and an event for every decision. The gateway and the terminal backend get separate policies because an approval for the model provider must not extend to whatever a shell command fetches.
Requirements
Two policies in the console, hermes-gateway and hermes-sandbox, each bound to its own site. The resolver pair and block page address of each site. Root on the host.
1. Assign the gateway host
The gateway, the local terminal backend and the browser tool all resolve through the operating system. No Hermes restart is needed.
[Resolve]
DNS=<primary resolver IP> <secondary resolver IP>
FallbackDNS=
DNSOverTLS=no
Domains=~.
2. Restrict DNS egress
Only the assigned resolvers may be asked for names. The counters record bypass attempts.
table inet securd {
chain output {
type filter hook output priority 0; policy accept;
ip daddr { <primary resolver IP>, <secondary resolver IP> } udp dport 53 accept
ip daddr { <primary resolver IP>, <secondary resolver IP> } tcp dport 53 accept
udp dport 53 counter drop
tcp dport 53 counter drop
tcp dport 853 counter drop
}
}
3. Assign the terminal backend
docker backend: Hermes starts a hardened container per task and does not pass a resolver, so the container takes the Docker daemon default. Set the default to the hermes-sandbox site. ssh backend: configure the worker VM with step 1 under the hermes-sandbox site and apply step 2 on it.
{
"dns": ["<sandbox primary resolver IP>", "<sandbox secondary resolver IP>"],
"dns-search": []
}
terminal:
backend: docker
docker_forward_env: [] # provider keys stay out of the sandbox
approvals:
unattended_mode: deny # cron, webhook and API sessions cannot self-approve
security:
allow_lazy_installs: false # no runtime pip installs from the gateway process
4. Compose deployment
The vendor compose file uses network_mode: host, so step 1 covers it. If you apply the vendor network isolation override, host networking is cleared; add dns to the gateway and proxy services.
services:
gateway:
dns:
- <hermes-gateway primary resolver IP>
- <hermes-gateway secondary resolver IP>
egress-proxy:
dns:
- <hermes-gateway primary resolver IP>
- <hermes-gateway secondary resolver IP>
5. Learn, then enforce
On hermes-gateway, import the scope template for the model provider and add the messaging platform and update hosts. Run both policies in Learn Only for seven days. Review Traffic Logs filtered on Greywall Event: New Query, approve what the agent needs, then set Default Action to Deny and Greywall Mode to Enforce.
| Policy | Approve |
|---|---|
| hermes-gateway | Model provider template; api.telegram.org, discord.com, gateway.discord.gg, slack.com, api.slack.com as configured; github.com and objects.githubusercontent.com for hermes update |
| hermes-sandbox | Only what the review shows. Package registries stay held unless the role installs software. |
Verify
Run on the gateway host and inside a terminal task. Confirm the test name in Traffic Logs on the policy that answered it.
getent hosts first-seen-$(date +%s).example # expected: <block page address>
dig +time=2 +tries=1 @8.8.8.8 example.com # expected: connection timed out
getent hosts api.openai.com # expected: a public address
Limits
The modal, daytona and vercel_sandbox backends run in vendor-managed sandboxes with no resolver control and are not covered. Keep security.website_blocklist, SSRF protection and approvals.deny on; they govern the tools and command text inside the process. Connections to a raw IP are governed by the egress firewall.
Vendor documentation this page was verified against
- Hermes Agent: Security (September 2026)
- Hermes Agent: Network Egress Isolation (Docker) (September 2026)
Vendor settings change. Securd behaviour on this page (the block page answer, the per-policy baseline, the DoH base) is a property of the product and does not.
Evaluate Agent DNS with your own agent traffic
Deploy on a single policy in learning mode and review the recorded destinations with your team.