Skip to main content

aquaman-hermes

Credential isolation for the Hermes agent host - using the vault you already have. API keys live in your existing backend (Keychain, 1Password, HashiCorp Vault, Bitwarden, KeePassXC, systemd-creds, or encrypted-file) and are injected by the aquaman proxy. They never enter the Hermes process, and you never copy them into a new store.

This is the optional, in-session "sugar" layer. The actual isolation is done by aquaman-proxy: it runs an opt-in loopback listener and Hermes is pointed at it via its native ANTHROPIC_BASE_URL / OPENAI_BASE_URL env vars (written to ~/.hermes/.env) plus a placeholder api_key that the proxy strips and replaces with the real credential. This plugin adds:

  • /aquaman-status: slash command showing proxy reachability + wiring.
  • aquaman_status: an agent-facing tool with the same info.
  • on_session_start: a one-shot health probe that warns if the proxy is down.
  • aquaman secret source (Hermes ≥ 0.18.1): resolves project/tool secrets (GitHub tokens, database URLs, anything under secrets.aquaman.env) from your vault at startup, through the proxy's token-gated broker. See below.

How it works

Hermes process                         aquaman-proxy (separate process)
┌────────────────────────┐             ┌────────────────────────────────┐
│ ANTHROPIC_BASE_URL =   │── HTTP ────▶│ 127.0.0.1:8585 loopback        │
│  http://127.0.0.1:8585 │  (loopback, │  • validates loopback token    │
│  /anthropic            │   token-    │  • injects real key from vault │
│ ANTHROPIC_API_KEY =    │   gated)    │  • forwards to api.anthropic   │
│  <loopback token>      │◀────────────│  • writes hash-chained audit   │
│ NO real credentials    │             └────────────────────────────────┘
└────────────────────────┘

Install

You need the proxy (aquaman-proxy, from npm) and this plugin (from PyPI):

# 1. Proxy + vault (Node)
npm install -g aquaman-proxy
aquaman setup                                   # pick a backend, store keys
aquaman credentials add anthropic api_key sk-ant-...

# 2. This plugin (Python)
pip install aquaman-hermes        # or: uv tool install aquaman-hermes
aquaman-hermes install            # drops the plugin into ~/.hermes/plugins/aquaman/
hermes plugins enable aquaman     # add to plugins.enabled

# 3. Wire Hermes at the proxy + start it
aquaman hermes setup              # writes ~/.hermes/.env, enables the loopback listener
aquaman daemon &                  # start the proxy

# 4. Verify
aquaman hermes doctor             # deep diagnostic (proxy side)
hermes                            # then run: /aquaman-status

aquaman-hermes install honors HERMES_HOME (the same var the Hermes CLI uses to relocate its config dir); it defaults to ~/.hermes.

Transport and access control

Hermes reaches the proxy over the token-gated loopback listener 127.0.0.1:<port>, because Hermes builds its own HTTP client and cannot dial a Unix socket. Since aquaman v0.15.0 OpenClaw's model traffic uses the same listener, for the same reason; coding agents still use the socket ~/.aquaman/proxy.sock (0600).

The token is a capability to reach the local proxy, not a credential: generated per install, stored in ~/.aquaman/config.yaml (0600) and in the managed block of ~/.hermes/.env, and stripped by the proxy before your real key is injected. Any local process can reach a loopback port, including other users, where the socket's 0600 shuts them out. The token is the gate there, and the listener stays off until you run aquaman hermes setup.

Project secrets (secret source, Hermes ≥ 0.18.1)

LLM keys are only half the problem. Agents also need GitHub tokens, database URLs, and other project secrets that usually end up in a plaintext .env. On Hermes ≥ 0.18.1 this plugin registers an aquaman secret source so those come from your vault instead. Bind them in ~/.hermes/config.yaml:

secrets:
  aquaman:
    enabled: true
    env:
      GITHUB_TOKEN: aquaman://github/token
      DATABASE_URL: aquaman://supabase/db_url

Then declare the same refs to the proxy. Since aquaman 0.15 the daemon hands out only refs you have declared, so a binding in Hermes' config alone is refused:

aquaman broker allow aquaman://github/token aquaman://supabase/db_url
aquaman hermes doctor   # flags any binding that isn't declared yet

At startup the source resolves each binding through the proxy's token-gated loopback broker (per-read, hash-chain audited) and hands the values to Hermes' secret orchestrator. Notes on the security model:

  • LLM provider keys are refused, by this source and by the proxy itself. ANTHROPIC_API_KEY / OPENAI_API_KEY bindings are rejected with a warning, and the proxy never hands out anthropic/openai keys over the loopback listener even if they are declared. Those stay on the loopback proxy path, where the real key never enters the Hermes process at all.
  • Project secrets resolved this way do live in Hermes' process env (that's what a Hermes secret source is). What you gain over a .env line: vault-at-rest storage, per-read tamper-evident audit, instant rotation, and no plaintext files on disk.
  • Fail-open by design: if the proxy is down, Hermes still starts (with a warning).
  • One bad ref never blocks the others; errors/warnings never contain the token.

On Hermes 0.19+ the source participates in the full orchestrator: mapped-vs-bulk precedence (an explicit env: binding outranks a bulk project dump), first-claim-wins across sources with conflict warnings, and (from Aquaman Proxy) provenance labels. Order it against other sources with secrets.sources: [aquaman, bitwarden]. The source passes Hermes' own secret-source conformance kit (see tests/test_conformance.py).

Timing caveat: plugin discovery runs later in Hermes' startup than the first load_hermes_dotenv() call, so a plugin-provided source is not consulted by the very first env load of the process that discovers it. It is consulted by every subsequently spawned Hermes process (gateway children, cron sessions, subagents). Bundled sources cover first-process bootstrap; that's a Hermes design property, not an aquaman gap.

Uninstall

hermes plugins disable aquaman
aquaman-hermes uninstall

Notes

  • The status/command/hook surface holds no credentials. It only reads the provider base-URL env vars and probes the proxy's token-exempt /_health endpoint. The secret source transits credentials only while handing them to Hermes' orchestrator.
  • It depends only on the Python standard library.
  • LLM providers wired via base-URL: Anthropic + OpenAI. Channels are out of scope for the Hermes path (no base-URL lever); project secrets go through the secret source.
  • Hermes >=0.17 "managed scope": a root-owned /etc/hermes/.env overrides ~/.hermes/.env. If an admin pins the ANTHROPIC_*/OPENAI_* vars there, the proxy is bypassed. aquaman hermes doctor detects and flags this.
  • With gateway.multiplex_profiles enabled (off by default), env is scoped per profile: add the aquaman block to each profile's env file.
  • Hermes 0.18's cron exfil guard refuses cron jobs that pair a named provider with an off-host base_url override; normal jobs inheriting the session runtime (the env vars aquaman writes) are unaffected.

Release files for aquaman-hermes 0.15.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aquaman-hermes 0.15.0
File Size Uploaded
aquaman_hermes-0.15.0.tar.gz 25.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aquaman-hermes 0.15.0
File Interpreter ABI Platform
aquaman_hermes-0.15.0-py3-none-any.whl Python 3 none any Details

Total release size: 40.1 kB

Release files / aquaman_hermes-0.15.0.tar.gz

Download URL aquaman_hermes-0.15.0.tar.gz
Size 25.1 kB
Tags Source
SHA-256 checksum
How to use checksums
cd498625307f02a31e7d390d0c38f90be0133ffc2cf52156b8b271e36ee525e3
BLAKE2b-256 checksum
How to use checksums
bf816b47bb191436128925885f53302b7827d0d70d4506e06c457afca7739636
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.

Transparency log

Release files / aquaman_hermes-0.15.0-py3-none-any.whl

Download URL aquaman_hermes-0.15.0-py3-none-any.whl
Size 14.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4782a4c84c87ec19669596cc341373e9e186bd2806db4b215390aecd7b483ec5
BLAKE2b-256 checksum
How to use checksums
5bdd3a7304c989934e7b1caabb8f5845d5785a1eb6b20d5668ca11eaa054dff3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.

Transparency log

Release history Release notifications | RSS feed

0.16.0

2 release files

This release

0.15.0 This release

2 release files

0.14.1

2 release files

0.14.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page