Automated setup
The fastest way to get started:- Generates CA certificates (if not already present)
- Creates a scaffold
cordon.yaml - Generates a combined CA bundle (system CAs + Cordon CA)
- Writes proxy env vars to Hermes’s
~/.hermes/.env(HTTPS_PROXY,HTTP_PROXY,SSL_CERT_FILE,REQUESTS_CA_BUNDLE)
.env is backed up to .env.cordon.bak before any changes are made.
Global setup with background service
To install cordon as a background service that starts automatically:Remove the setup
Adding routes
After setup, editcordon.yaml to add routes for your LLM provider. Example for Anthropic:
Provider auto-detection
Hermes uses env vars to auto-detect which LLM provider to use. Since cordon injects the real API key at the network layer, Hermes still needs a dummy key to select the right provider. Add a placeholder to~/.hermes/.env:
Manual setup
If you prefer manual configuration, add these to~/.hermes/.env:
You must create a combined CA bundle manually if not using
cordon setup hermes. Concatenate your system CA bundle with the Cordon CA cert — see Combined CA bundle below.HERMES_HOME env var can override the default ~/.hermes/ path if Hermes is installed in a non-standard location.
How it works
Hermes uses Python’shttpx library for HTTP, which honors HTTPS_PROXY by default (trust_env=True). The OpenAI SDK, Firecrawl, Tavily, and Exa SDKs all use httpx or requests internally, so all HTTP traffic routes through cordon automatically. No code changes or monkeypatching required.
Cordon only MITMs connections to hosts with matching routes. All other traffic passes through as a transparent CONNECT tunnel — the upstream server’s real certificate is presented to the client, and no CA bundle configuration is needed for those connections.
Combined CA bundle
Python’sSSL_CERT_FILE replaces the default certificate store rather than appending to it. This means setting SSL_CERT_FILE to just the Cordon CA cert would break TLS for all non-proxied connections (the system CAs would be missing).
To solve this, cordon setup hermes generates a combined CA bundle that concatenates:
- Your system CA certificates (e.g., from
/etc/ssl/cert.pem) - The Cordon proxy CA certificate
combined-ca.pem) and both SSL_CERT_FILE and REQUESTS_CA_BUNDLE point to it.
REQUESTS_CA_BUNDLE is set separately because Python’s requests library does not read SSL_CERT_FILE — it has its own env var.
This is different from the Codex integration, where
SSL_CERT_FILE points directly to the Cordon CA cert. Codex uses Rust’s rustls, which adds custom CAs on top of the system trust store rather than replacing it.Sandboxed environments
Hermes supports Docker, Modal, and SSH sandboxed execution backends. These environments run in isolated network namespaces where127.0.0.1 refers to the container’s loopback, not the host. The cordon proxy running on the host is not reachable from inside these sandboxes without network bridging.
For local development (TERMINAL_ENV=local), cordon works out of the box. For sandboxed backends, a remote cordon proxy with network-accessible binding would be needed (not yet supported).
Workflow
Once configured, the workflow is:- Start cordon:
cordon start(or use the background service) - Start Hermes as usual
- When Hermes makes API calls to configured hosts, cordon transparently injects credentials
- Hermes never sees or logs real API keys
Troubleshooting
401 Unauthorized errors
- Wrong auth type: Anthropic uses
type: api_keywithheader_name: x-api-key, nottype: bearer. Check yourcordon.yamlroute configuration. - Missing dummy key: Hermes won’t select a provider without its API key env var set. Add
ANTHROPIC_API_KEY=dummy-replaced-by-cordonto~/.hermes/.env. - Stale secret: Secrets are resolved at cordon startup. If you changed the secret, restart cordon.
- Verify the secret is stored:
cordon secret set anthropic --config /path/to/cordon.yaml
Certificate errors
If you see SSL/TLS errors:-
Verify the combined CA bundle exists and is readable:
-
Verify the bundle contains both system CAs and the Cordon CA:
-
If the combined bundle is missing, re-run
cordon setup hermesto regenerate it.
Proxy not being used
Verify the env vars are in~/.hermes/.env:
load_hermes_dotenv(). If the file exists but Hermes isn’t routing through the proxy, ensure cordon is running:
Provider not detected
If Hermes can’t determine which LLM provider to use, it’s likely missing the dummy API key env var. Add the appropriate key to~/.hermes/.env:
Service restart required after config changes
Cordon resolves secrets eagerly at startup. If you add or change routes, secrets, or thecordon.yaml config, restart the proxy: