
aquaman v0.15.0
🔱 El único proxy de credenciales independiente para agentes de IA: aislamiento de «trae tu propia bóveda» y políticas de solicitud de mínimo privilegio. Tus claves se quedan donde ya las guardas, nunca en la memoria del agente. Compatible con 1Password, keychain, keepassxc y muchos otros.
🔱 Aquaman
🔱 El único proxy de credenciales independiente para agentes de IA: aislamiento con tu propia bóveda (bring-your-own-vault) y políticas de solicitud de mínimo privilegio. Tus claves permanecen donde ya las guardas, nunca en la memoria del agente. Compatible con 1Password, keychain, keepassxc y muchos otros.
Configuras Claude Code, OpenClaw o Hermes, y ahora estás mirando fijamente archivos .env con tus preciadas claves de API ahí en texto plano. Lees los artículos. Sabes lo que pasa cuando un agente sufre una inyección de prompt. Lo entendemos.
Aquaman soluciona esto con tres capas de defensa:
- Aislamiento de procesos: las claves de API viven en un proceso proxy separado que las inyecta en la salida (egress). El agente contiene un marcador, nunca una clave, así que incluso una RCE en el agente no puede leer ninguna. Los agentes de programación solo obtienen las referencias que declares, una orden a la vez.
- Políticas de solicitud: reglas por servicio controlan qué endpoints puede llamar un agente. Bloquea APIs de administración, impide eliminaciones, permite borradores pero deniega envíos. Las solicitudes denegadas nunca reciben credenciales reales.
- Auditoría a prueba de manipulación: cada uso de credenciales se registra con cadenas de hash SHA-256. Puedes demostrar qué se accedió y detectar manipulaciones a posteriori.
Elige tu camino
Aquaman se distribuye como cuatro paquetes coordinados, que comparten una bóveda + un daemon. Instala solo lo que necesites:
| Paquete | Qué hace | Cuándo instalarlo |
|---|---|---|
aquaman-proxy | Núcleo: bóveda, daemon, auditoría, políticas, CLI. La pieza que todos necesitan. | Siempre. |
aquaman-plugin | Adaptador para OpenClaw Gateway. Lanza el proxy al iniciar el Gateway; enruta el tráfico del modelo y de Telegram a través de él; 25 servicios integrados en 5 modos de autenticación. | Si ejecutas un OpenClaw Gateway. También disponible en https://clawhub.ai/plugins/aquaman-plugin |
aquaman-coder | Adaptador para agentes de programación con IA. Referencias aquaman://service/key con alcance de proyecto resueltas por cada llamada a la herramienta Bash. | Si usas Claude Code (hoy) - Codex / OpenCode / Cursor planificados. |
aquaman-hermes | Plugin de host de agente Hermes (Python, en PyPI). Apunta Hermes a un listener de loopback con opt-in y protegido por token a través de sus ANTHROPIC_BASE_URL/OPENAI_BASE_URL nativos; añade un comando /aquaman-status en sesión, una herramienta y una sonda de salud. El aislamiento es del lado del proxy; el plugin no contiene credenciales. | Si ejecutas el host de agente Hermes. pip install aquaman-hermes |
Una única CLI aquaman expone los cuatro: comandos de nivel superior para la bóveda y la auditoría, aquaman openclaw ... para la integración con OpenClaw, aquaman coder ... para la integración con agentes de programación (delega en aquaman-coder internamente) así como aquaman hermes ... para el paquete Python de Hermes.
Inicio rápido
aquaman help, aquaman doctor son tus amigos.
1. Solo la bóveda (solo el proxy + tus secretos)```bash
npm install -g aquaman-proxy aquaman setup # backend wizard + store keys aquaman daemon & # start the proxy aquaman credentials list # verify
El proxy escucha en `~/.aquaman/proxy.sock` (UDS, `chmod 0o600`). Apunta cualquier herramienta a `http://aquaman.local/<service>/<path>` y el proxy inyecta las cabeceras de autenticación para ese servicio desde el backend de vault que hayas elegido.
### 2. OpenClaw Gateway```bash
openclaw plugins install aquaman-plugin # 1. install plugin + proxy
openclaw aquaman setup # 2. backend + keys + plugin wire-up
openclaw # 3. done - proxy starts automatically
Solución de problemas: openclaw aquaman doctor.
¿Usas npm directamente? npm install -g aquaman-proxy && aquaman openclaw setup hace lo mismo: instala el CLI del proxy, almacena tus claves, instala el plugin en ~/.openclaw/extensions/aquaman-plugin/ y configura las credenciales (referencias SecretRef en OpenClaw ≥ 2026.6.5, el marcador de posición auth-profiles.json en versiones anteriores).
aquaman openclaw setup apunta models.providers.<svc>.baseUrl y channels.telegram.apiRoot al listener de loopback del proxy, porque el transporte de modelos de OpenClaw y sus canales construyen cada uno su propio cliente HTTP y omiten el interceptor de fetch. Los canales distintos de Telegram no exponen ninguna anulación de endpoint, por lo que sus tokens se almacenan y migran pero no se inyectan en la salida (consulta packages/plugin/README.md). Añade canales bajo la configuración del plugin en openclaw.json; entre los compatibles se incluyen Slack, Discord, Telegram, MS Teams, Matrix, LINE, Twitch, Twilio, BlueBubbles, Mattermost, Nostr, Tlon, Feishu, Google Chat, ElevenLabs, xAI, Cloudflare AI Gateway, Mistral, Hugging Face y más (25 en total).
3. Agentes de codificación con IA (Claude Code hoy)```bash
npm install -g aquaman-proxy aquaman-coder # 1. install daemon + adapter aquaman setup # 2. vault wizard aquaman daemon & # 3. start the proxy
aquaman coder project add my-app --path ~/code/my-app
--env ANTHROPIC_API_KEY=aquaman://anthropic/api_key
--env GITHUB_TOKEN=aquaman://github/token # 4. declare a project
aquaman coder setup claude-code # 5. wire Claude Code hooks
aquaman doctor # 6. verify - should show both vault + coder green
**Compruébalo tú mismo (el momento ajá de 30 segundos):** reinicia Claude Code, abre una nueva sesión dentro de `~/code/my-app` y pídele al agente que ejecute:```
printenv | grep ANTHROPIC_API_KEY
Lo verás en la transcripción:``` ANTHROPIC_API_KEY=[REDACTED:injected-value]
⏺ ANTHROPIC_API_KEY is set and available (injected via aquaman vault).
El proceso *hijo* vio la clave real (tus pruebas, compilaciones, servidores MCP, scripts de importación - cualquier cosa que realmente la necesite funciona). El *agente* - lo que decide qué código ejecutar en tu máquina - nunca ve el valor, y por lo tanto tampoco lo hace el historial de conversación, ni los registros del proveedor del modelo, ni nadie que luego haga una captura de pantalla de tu terminal.
**Úsalo también desde tu propia terminal.** El mismo wrapper funciona sin el agente. Solo tienes que hacer `cd` a un proyecto cubierto y prefijar tu comando:```bash
cd ~/code/
aquaman-coder exec -- python app/scripts/import.py
Misma inyección de env, misma redacción en stdout/stderr. Colócalo en objetivos de Makefile, alias de shell o runners de CI, en cualquier lugar donde de otro modo recurrirías a un archivo .env.
Cuando Claude Code ejecuta una herramienta Bash en ~/code/my-app, el hook de aquaman reescribe el comando mediante updatedInput.command para envolverlo bajo aquaman-coder exec. Ese wrapper:
- Resuelve cada referencia
aquaman://service/keya través del broker (POST /broker/resolvesobre UDS). Las credenciales se materializan para un comando, no para toda la vida del agente. - Canaliza stdout/stderr a través de un redactor que antepone un patrón basado en valores para cada valor resuelto: cualquier cadena que se haya inyectado queda redactada, independientemente de su forma (tokens de Atlassian, secretos de Notion, claves de API internas: ninguno de ellos necesita coincidir con un formato de proveedor conocido). Los patrones genéricos basados en forma (sk-ant-, ghp_, sk_live_, AKIA…, JWTs, bloques PEM, ATATT3xF…) siguen ejecutándose después como defensa en profundidad para secretos que el proceso hijo expone y que NO inyectamos.
- Limpia cuando el comando finaliza.
Sandbox de Claude Code: bloquea los sockets Unix por defecto, por lo que aquaman coder setup claude-code incluye en la lista de permitidos el socket del proxy en macOS (sandbox.network.allowUnixSockets). Linux y WSL2 ignoran esa lista, donde la única opción es sandbox.network.allowAllUnixSockets: true, lo que abre todos los sockets Unix a los comandos en sandbox.
4. Hermes (host de agente)
Hermes es un host externo (Python) sin hook de transporte para inyectar, por lo que el aislamiento se realiza del lado del proxy: el proxy expone un listener de loopback opcional, protegido por token, y Hermes se apunta a él a través de sus propias variables de entorno.```bash npm install -g aquaman-proxy # 1. install daemon aquaman setup # 2. vault wizard aquaman credentials add anthropic api_key sk-ant-... # 3. store a provider key
aquaman hermes setup # 4. enable loopback + write ~/.hermes/.env aquaman daemon & # 5. start the proxy (UDS + loopback) aquaman hermes doctor # 6. verify - listener + env + vault + Hermes
`aquaman hermes setup` habilita el listener de loopback, genera un token por instalación y escribe un bloque gestionado por aquaman en `~/.hermes/.env` (respetando `HERMES_HOME`): el `ANTHROPIC_BASE_URL`/`OPENAI_BASE_URL` nativo más un api_key de marcador de posición igual al token. Hermes envía el token como su clave de proveedor; el proxy lo elimina, inyecta tu credencial real del vault y reenvía upstream. Solo proveedores LLM (Anthropic, OpenAI) por ahora.
**Azúcar opcional en sesión** - el plugin de Python añade un comando `/aquaman-status`, una herramienta `aquaman_status` y una sonda de salud al inicio de sesión dentro de Hermes (no contiene credenciales):```bash
pip install aquaman-hermes # or: uv tool install aquaman-hermes
aquaman-hermes install # drops the plugin into ~/.hermes/plugins/aquaman/
hermes plugins enable aquaman
El plugin también registra una fuente de secretos aquaman (Hermes ≥ 0.18.1) para secretos de proyecto como GITHUB_TOKEN. Vincúlalos bajo secrets.aquaman.env en el config.yaml de Hermes, luego declara cada referencia con aquaman broker allow aquaman://github/token (requerido desde v0.15.0; aquaman hermes doctor lista cualquiera que hayas omitido). A diferencia de las claves LLM anteriores, estos valores sí entran en el env de Hermes. Consulta packages/hermes/README.md.
Cómo funciona```
Agent / OpenClaw / Coding Agent Aquaman Proxy ┌──────────────────────┐ ┌──────────────────────┐ │ │ │ │ │ ANTHROPIC_BASE_URL │═══ UDS / HTTP ════>│ Keychain / 1Pass / │ │ = aquaman.local │ │ Vault / Encrypted │ │ │<══════════════════ │ │ │ fetch() interceptor │═══ broker:resolve │ + Policy enforced │ │ (channel APIs) │ │ + Auth injected: │ │ │ │ header / url-path │ │ No credentials. │ ~/.aquaman/ │ basic / oauth │ │ No open ports. │ proxy.sock │ │ │ No keys to read. │ (chmod 0o600) │ │ └──────────────────────┘ └──┬─────────┬─────────┘ │ │ │ ▼ │ ~/.aquaman/audit/ │ (hash-chained) ▼ api.anthropic.com api.telegram.org slack.com/api …
1. **Store**: Las credenciales residen en el backend de vault que ya ejecutas - sin vault propio (Keychain, 1Password, HashiCorp Vault, Bitwarden, KeePassXC, systemd-creds, archivo cifrado).
2. **Policy**: El proxy verifica las reglas de método + ruta *antes* de tocar las credenciales. Las solicitudes denegadas reciben un `403`, nunca encabezados de autenticación reales.
3. **Inject**: El proxy busca la credencial y añade el encabezado de autenticación antes de reenviar. 25 servicios integrados, 4 modos de inyección de autenticación (header, URL-path, HTTP Basic, OAuth); un 5.º, `none`, es solo en reposo (el proxy rechaza el tráfico).
4. **Broker (coder + fuente de secretos de Hermes)**: `POST /broker/resolve` materializa una credencial por llamada de herramienta, con alcance al entorno de un solo comando. Solo `aquaman daemon` lo sirve, y solo para las refs que declaraste (`projects.yaml` o `aquaman broker allow`). El proxy del plugin de OpenClaw nunca lo sirve (v0.15.0+).
5. **Audit**: Cada uso de credencial se registra con cadenas de hash SHA-256.
En las rutas del proxy el agente ve un endpoint local más un marcador: el placeholder `aquaman-proxy-managed`, o el token de loopback, que solo funciona contra tu proxy local. Nunca una clave real. En la ruta del coder el comando *hijo* recibe los valores declarados y el agente ve la salida redactada.
## Security Model
| Capa | Qué hace | Qué detiene |
|---|---|---|
| **Aislamiento de procesos** | Credenciales en un proceso separado, accesibles a través de un socket Unix (`chmod 0o600`) o un listener de loopback protegido por token | Un agente comprometido no puede leer las claves proxeadas: espacio de direcciones distinto |
| **Alcance del broker** | Solo `aquaman daemon` entrega valores, y solo para las refs que declaraste; los proxies alojados en OpenClaw nunca lo hacen (v0.15.0+) | Un agente no puede extraer entradas arbitrarias del vault a través del socket |
| **Lista blanca de servicios** | `proxiedServices` controla a qué APIs puede llegar el agente | El agente no puede hablar con servicios que no autorizaste |
| **Políticas de solicitud** | Reglas de método + ruta por servicio, aplicadas antes de la inyección de credenciales | El agente puede llegar a Anthropic pero no a su API de administración; puede redactar correos pero no enviarlos |
| **Registro de auditoría** | Logs con cadenas de hash SHA-256 de cada uso de credencial | Forense post-incidente, detección de manipulación, evidencia de cumplimiento |
| **Broker por llamada de herramienta (coder)** | `aquaman-coder exec` materializa credenciales para un comando a la vez | Las credenciales no se dispersan por el entorno de shell del agente |
| **Redacción de salida (coder)** | `aquaman-coder exec` canaliza stdout/stderr a través de un redactor que elimina literalmente cada valor que acaba de inyectar - más patrones genéricos de proveedores como respaldo | Incluso credenciales arbitrarias y sin forma definida nunca llegan a la transcripción del agente |
### Transports and access control
| Ruta | Transporte | Control de acceso |
|---|---|---|
| Agentes de programación, cualquier cliente que pueda marcar un socket | Socket Unix `~/.aquaman/proxy.sock` | Permisos de archivo (`0600`): solo procesos ejecutándose como tú |
| Hermes (v0.13.0+), tráfico de modelo y Telegram de OpenClaw (v0.15.0+) | TCP de loopback `127.0.0.1:<port>` | Token por instalación, verificación en tiempo constante, bind de loopback |
Hermes y OpenClaw construyen cada uno su propio cliente HTTP y no pueden marcar un socket, así que usan el listener. Todo lo demás usa el socket.
El token es una capacidad para llegar al proxy local, no una credencial. Se genera por instalación, se almacena en `~/.aquaman/config.yaml` (`0600`), y el host lo envía como su api key de proveedor. El proxy lo verifica, lo elimina, e inyecta tu clave real. Telegram no tiene encabezado de autenticación, así que ahí el token viaja en el segmento de ruta `/bot<TOKEN>` en su lugar.
Trade-off: cualquier proceso local puede llegar a un puerto de loopback, incluidos otros usuarios, donde el `0600` del socket los deja fuera. El token es la puerta ahí, así que el listener permanece apagado hasta que `aquaman hermes setup` o `aquaman openclaw setup` lo active.
### Channel credentials on OpenClaw 2026.7.33+
| Canal | Salida a través del proxy |
|---|---|
| Telegram | Sí, desde v0.15.0 |
| Todo lo demás | No. Solo almacenamiento en vault y migración |
Cada canal construye su propio cliente HTTP por solicitud, así que el interceptor `fetch` del plugin ya no ve el tráfico de canales en estas versiones. Enrutar un canal requiere una anulación de endpoint por parte del host, y Telegram es el único que la tiene: `aquaman openclaw setup` apunta `channels.telegram.apiRoot` al proxy y reemplaza el token del bot con el token de loopback.
Para el resto, tu token permanece en el vault pero OpenClaw lo usa directamente, así que el proxy no está en la ruta y esas llamadas no se auditan. `aquaman openclaw doctor` lista cuáles de tus canales configurados están en cada grupo. Los proveedores de modelo no se ven afectados.
**Lo que el aislamiento entre el mismo usuario no puede hacer.** El `0o600` del socket mantiene fuera a otros usuarios, no a otros procesos ejecutándose como tú. Tal proceso puede enviar solicitudes a través del proxy mientras se ejecuta (limitado por la política de solicitud, registrado en el log de auditoría) y puede obtener las refs que declaraste, que es lo que significa declarar. No puede leer las claves que el proxy inyecta. Para una frontera más dura, ejecuta el agente como un usuario de SO diferente o en un sandbox.
Modelo detallado - detalles por integración (alcance del interceptor HTTP, perfiles de autenticación, hallazgos del escáner, nota del publicador de ClawScan) - vive en [`packages/plugin/README.md`](https://github.com/tech4242/aquaman/blob/main/packages/plugin/README.md) y [`packages/coder/README.md`](https://github.com/tech4242/aquaman/blob/main/packages/coder/README.md).
### Compliance posture
Aquaman incluye pruebas de conformidad ejecutables bajo `test/compliance/` mapeadas a:
- **MITRE ATLAS** v5.4.0: técnicas AML.T0055, T0012, T0062, T0090, T0098 (`test/compliance/atlas/`)
- **NIST SP 800-53 Rev 5**: IA-5, AC-3, AC-6, AU-2/9/10, SC-12/28, SI-10 (`test/compliance/nist/`)
Además de narrativas de alineación para CISA/Five-Eyes "Careful Adoption of Agentic AI Services" (abril de 2026), CSA MAESTRO, y OWASP Top 10 for Agentic Applications. Las pruebas se ejecutan como parte de `npm test`. Consulta [`docs/compliance/`](https://github.com/tech4242/aquaman/blob/main/docs/compliance) para los mapeos.
## Request Policies
Los scopes de OAuth no pueden distinguir entre "redactar un correo" y "enviar un correo". Ambos son `gmail.send`. Las políticas de solicitud cubren esa brecha.```yaml
# ~/.aquaman/config.yaml
policy:
anthropic:
defaultAction: allow
rules:
- method: "*"
path: "/v1/organizations/**"
action: deny # block admin/billing API
openai:
defaultAction: allow
rules:
- method: "*"
path: "/v1/organization/**"
action: deny
- method: DELETE
path: "/v1/**"
action: deny # no deletions
slack:
defaultAction: allow
rules:
- method: "*"
path: "/api/admin.*"
action: deny # Slack Web API admin methods
gmail:
defaultAction: allow
rules:
- method: POST
path: "/gmail/v1/users/*/messages/send"
action: deny # drafts ok, sending blocked
- Las rutas son la ruta completa de la API upstream después del prefijo del servicio: la Web API de Slack es
/api/<method>, la de Gmail es/gmail/v1/.... Los presets anteriores a la v0.15.0 usaban/admin.*y/v1/users/*/messages/send, que nunca coincidían con el tráfico real.aquaman doctorlos marca si todavía están en tu configuración. - Sin política = permitir todo (compatible con versiones anteriores)
- Gana la primera coincidencia: las reglas se evalúan de arriba a abajo, las solicitudes no coincidentes recaen en
defaultAction - Denegado antes de la autenticación: las solicitudes bloqueadas nunca obtienen credenciales reales
- Globs de ruta:
*coincide dentro de un segmento,**coincide con cero o más segmentos aquaman setupaplica valores predeterminados seguros para los servicios almacenados (anthropic,openai,slack,gmail).aquaman policy list/aquaman policy test <svc> <method> <path>para inspección / simulaciones.
Backends de credenciales
Trae tu propia bóveda - aquaman no tiene almacén propio. Elige el backend que ya uses; los secretos permanecen allí y el proxy los lee en su lugar.
| Backend | Ideal para | Configuración |
|---|---|---|
keychain | Desarrollo local en macOS (predeterminado) | Funciona sin configuración adicional |
encrypted-file | Linux, WSL2, CI/CD | AES-256-GCM, protegido con contraseña |
keepassxc | Usuarios existentes de KeePass | npm i -g kdbxweb argon2 (peers opcionales desde la v0.14.1), luego establece AQUAMAN_KEEPASS_PASSWORD o un archivo de clave |
1password | Uso compartido de credenciales en equipo | brew install 1password-cli && op signin. Para agentes desatendidos usa una cuenta de servicio (OP_SERVICE_ACCOUNT_TOKEN) |
vault | Gestión empresarial de secretos | Establece VAULT_ADDR + VAULT_TOKEN |
systemd-creds | Linux con systemd ≥ 256 | Respaldado por TPM2, no requiere root |
bitwarden | Usuarios de Bitwarden | bw login && export BW_SESSION=$(bw unlock --raw) |
aquaman setup detecta automáticamente un valor predeterminado sensato (macOS → keychain; Linux → keychain si hay libsecret, si no systemd-creds si systemd ≥ 256, si no encrypted-file).
encrypted-file es el último recurso para entornos Linux/CI sin interfaz gráfica y sin un llavero nativo. Para mayor seguridad en Linux, instala libsecret-1-dev (GNOME Keyring), usa systemd-creds (vinculación TPM2), o usa 1Password/Vault.
Caché de credenciales (v0.13.1+)
Los backends con un costo por acceso, como 1password (un aviso biométrico por lectura en modo aplicación de escritorio), bitwarden (~1-2 s de spawn de CLI) y vault (una ida y vuelta HTTP), se almacenan en caché en la memoria del daemon durante 15 minutos de forma predeterminada, de modo que una sesión de agente con mucha actividad desbloquea la bóveda una vez por ventana en lugar de una vez por solicitud. Los otros backends ya son rápidos o almacenan en caché internamente, por lo que la caché está desactivada para ellos de forma predeterminada. Ajusta con credentials.cacheTtlSeconds en ~/.aquaman/config.yaml (o AQUAMAN_CACHE_TTL); 0 lo desactiva.
El compromiso honesto: un aviso biométrico por acceso es una verificación de presencia del usuario, y la caché elimina la presencia por acceso durante la ventana del TTL. Para agentes desatendidos ese aviso nunca se responde, por lo que la bóveda se abandona en favor de un .env en texto plano, lo cual es estrictamente peor. La caché no mueve el límite de aislamiento: los valores viven solo en el proceso del proxy (donde ya transitan en cada solicitud), nunca se escriben en disco, y se invalidan inmediatamente cuando rotas mediante aquaman credentials add. Las escrituras siempre van a tu bóveda. Probado por conformidad en test/compliance/cache-residency.test.ts. Para cero avisos con 1Password, usa una cuenta de servicio con alcance a la bóveda aquaman; aquaman doctor te indicará dónde.
Licencia
MIT - consulta LICENSE.