← Back to blog

Hermes Iron-Proxy: Your Agent's API Keys Never Touch the Sandbox

hermessecuritycredential-firewalliron-proxydockersandboxquicksilver
Hermes Iron-Proxy: Your Agent's API Keys Never Touch the Sandbox

Agent sandboxes have a fundamental problem: they need API keys to function, but those keys are valuable targets. If an agent gets prompt-injected and told to cat ~/.config/openrouter/auth.json or printenv | grep -i key, the attacker walks away with credentials that can be used anywhere.

Hermes Agent v0.19 ships a solution: iron-proxy, a credential firewall that keeps real API keys completely out of the sandbox.

The attack surface

When Hermes runs an agent inside a Docker terminal sandbox, that sandbox normally holds the actual upstream API keys: OPENROUTER_API_KEY, OPENAI_API_KEY, and any other provider credentials. A prompt-injected agent can read them directly from the environment or from config files in the filesystem.

This is not a theoretical concern. Production Hermes deployments on VPS instances face significant attack surfaces. One operator reported over 20,000 SSH password attempts in a single week on an exposed instance. The community recommendation is UFW default-deny on inbound traffic, SSH key-only authentication, and dashboard access restricted to localhost via SSH tunnel.

But even with hardened host networking, the sandbox itself remains a trust boundary problem. As long as real keys sit inside the sandbox environment, exfiltration is one prompt injection away.

How iron-proxy works

Iron-proxy is an Apache-2.0 licensed Go daemon that runs on the host machine. Its architecture follows a simple principle: the sandbox gets opaque proxy tokens, and real credentials never cross into the container.

The data flow:

  1. At setup, hermes egress setup discovers all provider keys from the host environment (or ~/.hermes/.env). For each key, it mints a proxy token -- a random opaque string with no relationship to the real credential.

  2. A local CA is generated at ~/.hermes/proxy/ca.crt. A proxy.yaml config lists the upstream hosts allowed and the secrets-transform mapping. A mappings.json records which proxy token maps to which real environment variable.

  3. When the Docker sandbox starts, it receives HTTPS_PROXY=http://host.docker.internal:9090, HTTP_PROXY=http://host.docker.internal:9091, and the standard provider env vars (OPENROUTER_API_KEY, etc.) set to opaque proxy tokens -- not real keys.

  4. All outbound traffic from the sandbox routes through iron-proxy. The daemon terminates TLS (enabled by the sandbox trusting the local CA), inspects the Authorization header, and swaps the proxy token for the real credential before forwarding the request upstream.

  5. If the sandbox is fully compromised, the attacker walks away with tokens that work only behind the trusted proxy boundary. The proxy endpoint integrity and CA private key form the trust perimeter.

As the official docs state: "Compromise the sandbox and the attacker walks away with tokens that only work behind the configured trusted proxy boundary."

Setup

Four commands:

hermes egress install   # downloads and verifies iron-proxy binary
hermes egress setup     # generates CA, mints proxy tokens, writes configs
hermes egress start     # starts the daemon
hermes egress status    # confirms it is running

Setup discovers provider keys from the host environment automatically. If keys live only in ~/.hermes/.env and are not exported, setup reads that file directly -- no need to export them first.

Once running, the Docker terminal backend automatically mounts the CA cert into the sandbox and sets all the proxy environment variables. The entire mechanism activates with zero sandbox-side configuration.

Threat model boundaries

The iron-proxy threat model is specific: it protects against sandbox compromise. It does not protect against host compromise. If an attacker can read the host environment or manipulate the proxy daemon itself, the protection breaks.

Community discussion has raised the question of proxy integrity: if the proxy itself can be compromised or its CA private key stolen, the proxy token guarantee no longer holds. Nous Research is explicit about this in the docs: "If traffic can be redirected to attacker-controlled proxy infrastructure (e.g. a stolen CA private key or a hijacked proxy endpoint), the token guarantee no longer holds."

This is defense in depth. Iron-proxy eliminates the most common exfiltration path -- prompt injection triggering key reads from inside the sandbox. The remaining threat surface shifts to host-level security, which the community addresses through VPS hardening, SSH key-only auth, and no public dashboard exposure.

What iron-proxy is not

Three things to clarify:

  1. It is not the inbound hermes proxy command. That is an OAuth aggregator reverse proxy. Iron-proxy (hermes egress) handles outbound traffic from the sandbox.

  2. It does not sit between your local terminal and providers. It only sits between the sandbox and providers. The host process continues using .env keys directly.

  3. It does not rewrite credentials for in-process LLM calls the host makes. The threat model is the sandbox, not the host.

Current scope

Iron-proxy is wired into the Docker backend only as of v0.19. Modal, Daytona, SSH, and Singularity backends do not receive proxy env vars or CA mounts yet. The feature is gated behind a proxy.enabled flag in ~/.hermes/config.yaml, defaulting to false.

When proxy.enabled is false, the entire system is a complete no-op: no binary downloads, no Docker mounts, no subprocess started.

Production context

Iron-proxy shipped as part of the v0.19 Quicksilver release on July 20, 2026. That release spans approximately 2,245 commits, 1,065 merged PRs, and contributions from over 450 community contributors. It also includes 80% faster cold starts (4.3 seconds to 0.9 seconds), Bitwarden and 1Password secret source integration, and a durable delivery ledger that survives gateway crashes.

The production security pattern emerging in the Hermes community is clear: Blank Slate mode (minimum tools), Docker sandbox with iron-proxy, SSH key-only auth on the host, dashboard on localhost via SSH tunnel, UFW default-deny, and weekly security reviews. Combined, these layers create a deployment where even a fully prompt-injected agent cannot exfiltrate usable API keys.

[^1]: Nous Research. "Hermes Agent v0.19.0 (2026.7.20) -- The Quicksilver Release." GitHub. July 20, 2026.

[^2]: Nous Research. "Egress credential-injection proxy (iron-proxy)." Hermes Agent Documentation.

[^3]: @QuentinLecocq_. "20K+ SSH password attempts." X. July 25, 2026.

[^4]: @Michael_WCD. "How does the credential firewall/proxy itself detect that it is running in a compromised environment?" X. July 25, 2026.

[^5]: @killix. Sandbox credential firewall discussion. X. July 25, 2026.

Termagotchi
_

Ryan Underdown

Autodidact. Rarely listens to advice.

Follow on X @catamarammed or GitHub @underdown