Last updated on

Deja de meter API keys en .env: 5 pasos para conectar el nuevo Secret Vault externo de Hermes v0.19


¿Cuántas API keys tienes ahora mismo en tu archivo ~/.hermes/.env? OpenAI, Anthropic, GitHub, Telegram, Discord, Cloudflare, AWS — cada vez que añades una nueva integración, pegas otra línea SOME_KEY=sk-.... Luego revisas .gitignore tres veces antes de commitear, te copias el archivo por Slack cuando cambias de máquina y lo vuelves a pegar en los secretos de CI. Peor aún, cada persona del equipo guarda una copia local, así que nadie sabe qué versión es la actual, quién cambió qué o si alguna key se filtró.

Hermes Agent v0.19.0 convierte este desorden en una abstracción limpia: SecretSource. Permite que Hermes lea API keys de un vault externo al iniciar, con soporte nativo para Bitwarden Secrets Manager y 1Password. Guardas un único token de arranque en .env y dejas que el vault almacene el resto. Las keys ya no tienen que vivir en archivos .env en texto plano.

Este post te da una migración práctica en 5 pasos. No necesitas refactorizar todo de golpe: puedes mover primero las keys de mayor riesgo y mantener un camino de rollback abierto.

Para el resumen completo de v0.19.0, consulta nuestras notas de la versión v0.19.0 y la guía de skill combos.


Por qué .env no es la solución a largo plazo

.env es ideal para prototipos, pero se queda corto cuando Hermes se conecta a una docena de herramientas y servicios:

  1. Riesgo de expansión. Cada vez que copias .env a otra máquina, contenedor o entorno de CI, creas otra superficie de fuga. GitHub escanea millones de secretos subidos accidentalmente cada año.
  2. Sin trazabilidad. .env no te dirá quién cambió qué key ni cuándo. Una key puede rotarse y el resto del equipo solo se entera cuando algo deja de funcionar.
  3. Rotación dolorosa. La rotación trimestral de tokens significa editar N archivos y N puntos de inyección de variables de entorno, luego rezar para que no se haya pasado nada por alto.

Un vault externo de secretos no se limita a “ocultar texto plano”: convierte los secretos en recursos controlados, auditables y gestionados de forma centralizada. SecretSource de Hermes v0.19.0 conecta esa idea directamente al arranque del agente, así que el agente lee valores del vault como si fueran variables de entorno ordinarias.


Qué puede hacer SecretSource de Hermes v0.19.0

Según las notas de la versión v0.19.0 y la documentación oficial de Secrets, la interfaz SecretSource proporciona:

  • Múltiples vaults a la vez. Bitwarden Secrets Manager y 1Password pueden activarse simultáneamente. También hay un source genérico command para cualquier vault que imprima líneas KEY=VALUE.
  • Precedencia determinista. Hermes resuelve conflictos con una jerarquía clara: mapeos env: explícitos (1Password, command source) ganan a volcados masivos de proyectos (Bitwarden); dentro del mismo tipo, decide la orden de la lista opcional secrets.sources; los valores de .env y shell ganan por defecto, salvo que el source tenga override_existing: true.
  • Advertencias de conflicto. Si una fuente posterior también reclama una variable que ya proporcionó una fuente anterior, Hermes te avisa en lugar de elegir en silencio.
  • Trazabilidad de variables. Cada variable inyectada registra de qué fuente vino, así que el comando status y los logs de arranque muestran el origen.
  • Arranque no bloqueante. Si el vault no está accesible o la autenticación falla, Hermes imprime una advertencia con la acción recomendada y continúa con las credenciales que .env ya tuviera.

Eso significa que puedes escribir una configuración como esta sin poner OPENAI_API_KEY en .env en absoluto:

secrets:
  onepassword:
    enabled: true
    env:
      OPENAI_API_KEY: "op://Private/OpenAI/api key"
      ANTHROPIC_API_KEY: "op://Private/Anthropic/credential"
    override_existing: true

Las siguientes cinco secciones muestran cómo hacerlo real.


Paso 1: Actualiza a Hermes v0.19.0 y verifica el CLI

SecretSource es una funcionalidad de v0.19.0, así que empieza comprobando tu versión:

hermes --version

Luego confirma que el subcomando secrets existe:

hermes secrets --help

Deberías ver listados bitwarden, onepassword y otros helpers. Si estás por debajo de v0.19.0, ejecuta el instalador:

# macOS / Linux / WSL2
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash

# Windows (PowerShell)
iex (irm https://hermes-agent.nousresearch.com/install.ps1)

Paso 2: Elige un vault y autentícate

Hermes no gestiona la autenticación por ti; se apoya en el flujo oficial de cada vault. Tienes que configurarlo en la máquina donde se ejecuta Hermes.

Opción A: Bitwarden Secrets Manager

Necesitas una machine account en Bitwarden Secrets Manager, no la vault de contraseñas de consumidor. La machine account está diseñada para cargas de trabajo no interactivas.

  1. En la web app de Bitwarden, cambia a Secrets Manager.
  2. Crea un Project (por ejemplo, Hermes keys).
  3. Añade tus provider keys como secrets. El Nombre del secret se convierte en el nombre de la variable de entorno que Hermes espera: OPENAI_API_KEY, ANTHROPIC_API_KEY, TELEGRAM_BOT_TOKEN, etc.
  4. Ve a Machine accounts → New machine account y dale acceso de lectura al proyecto.
  5. En Access tokens, crea un token (empieza por 0., no se puede recuperar después) y cópialo.

Guarda ese token en ~/.hermes/.env como BWS_ACCESS_TOKEN:

BWS_ACCESS_TOKEN=0.xxx...

El binario bws se descargará automáticamente en ~/.hermes/bin/ la primera vez que Hermes lo necesite — no hace falta brew, apt ni sudo.

Opción B: 1Password

Instala el CLI oficial de 1Password (op) y verifica que funciona:

op --version
op whoami

Para portátiles / uso interactivo, inicia sesión con op signin o habilita la integración CLI en la app de 1Password. Hermes pasará tus variables de sesión al subproceso op.

Para servidores / CI / cron, crea una service account, dale acceso de lectura al vault correspondiente y guarda el token en ~/.hermes/.env:

OP_SERVICE_ACCOUNT_TOKEN=ops_...

Nota de seguridad: El token de arranque (BWS_ACCESS_TOKEN o OP_SERVICE_ACCOUNT_TOKEN) es a su vez un secreto de alto valor. Mantén .env fuera del control de versiones y restringe los permisos del archivo.


Paso 3: Ejecuta el asistente de configuración y configura el source

Hermes incluye un CLI dedicado para cada source. El asistente escribe en ~/.hermes/config.yaml (o en ~/.hermes/profiles/<profile>/config.yaml si usas un perfil con nombre).

Bitwarden

Ejecuta el asistente de forma interactiva:

hermes secrets bitwarden setup

O en modo no interactivo:

hermes secrets bitwarden setup \
  --access-token "$BWS_ACCESS_TOKEN" \
  --server-url https://vault.bitwarden.com \
  --project-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

La configuración resultante se parece a esto:

secrets:
  bitwarden:
    enabled: true
    project_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    server_url: "https://vault.bitwarden.com"
    access_token_env: BWS_ACCESS_TOKEN
    override_existing: true
    cache_ttl_seconds: 300

1Password

Ejecuta el asistente:

hermes secrets onepassword setup

O con un service-account token:

hermes secrets onepassword setup \
  --account my.1password.com \
  --token-env OP_SERVICE_ACCOUNT_TOKEN \
  --token "$OP_SERVICE_ACCOUNT_TOKEN"

Luego mapea cada variable de entorno a una referencia op://:

hermes secrets onepassword set OPENAI_API_KEY    "op://Private/OpenAI/api key"
hermes secrets onepassword set ANTHROPIC_API_KEY "op://Private/Anthropic/credential"
hermes secrets onepassword set TELEGRAM_BOT_TOKEN "op://Private/Telegram/token"

La configuración resultante:

secrets:
  onepassword:
    enabled: true
    env:
      OPENAI_API_KEY: "op://Private/OpenAI/api key"
      ANTHROPIC_API_KEY: "op://Private/Anthropic/credential"
      TELEGRAM_BOT_TOKEN: "op://Private/Telegram/token"
    service_account_token_env: OP_SERVICE_ACCOUNT_TOKEN
    override_existing: true
    cache_ttl_seconds: 300

Usar ambos sources a la vez

Puedes habilitar ambos simultáneamente. Controla el orden con la lista sources:

secrets:
  sources: [onepassword, bitwarden]
  onepassword:
    enabled: true
    env:
      OPENAI_API_KEY: "op://Private/OpenAI/api key"
  bitwarden:
    enabled: true
    project_id: "..."

Recuerda que los sources con mapeos explícitos (1Password) tienen prioridad automática sobre los volcados masivos (Bitwarden), independientemente del orden. Dentro del mismo tipo, gana el primero en la lista.


Paso 4: Migra las API keys en texto plano al vault

4.1 Inventaría las keys de .env

Lista los secretos que Hermes usa actualmente, agrupados por impacto:

  • Model API keys: OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, etc.
  • Platform tokens: TELEGRAM_BOT_TOKEN, DISCORD_BOT_TOKEN, SLACK_BOT_TOKEN
  • Cloud credentials: AWS_ACCESS_KEY_ID, CLOUDFLARE_API_TOKEN, GCP_API_KEY
  • Third-party tools: GitHub PATs, Sentry DSNs, Stripe keys, etc.

4.2 Crea los secretos en el vault

Bitwarden: en el proyecto que seleccionaste, crea un secret por variable de entorno. El nombre debe coincidir exactamente con lo que Hermes espera, por ejemplo OPENAI_API_KEY. Cuando ejecutes hermes secrets bitwarden sync, Hermes listará las variables que puede resolver.

1Password: crea items y campos que correspondan a tus referencias op://vault/item/field. Por ejemplo, si mapeaste OPENAI_API_KEY a op://Private/OpenAI/api key, crea un item llamado OpenAI en el vault Private con un campo api key.

Sugerencia de orden de migración: Mueve primero las keys de mayor impacto (Stripe, claves equivalentes a root de AWS, keys principales de proveedores de modelos) y luego las de solo lectura de menor riesgo.

4.3 Reduce .env y crea un example.env

Una vez que una key vive en el vault, bórrala o coméntala en .env. Mantén solo el token de arranque que el source necesita:

# ~/.hermes/.env
BWS_ACCESS_TOKEN=0.xxx...
# o para 1Password:
# OP_SERVICE_ACCOUNT_TOKEN=ops_...

Luego crea un example.env con los nombres de variables y comentarios, pero sin valores reales:

# example.env — los valores reales están en tu vault externo
OPENAI_API_KEY=see-vault
ANTHROPIC_API_KEY=see-vault
TELEGRAM_BOT_TOKEN=see-vault

Los nuevos miembros del equipo sabrán qué variables se esperan y qué vault consultar, sin que nadie les envíe un .env real.


Paso 5: Verifica, rota y mantén un camino de rollback

5.1 Verifica que la integración está activa

Bitwarden:

hermes secrets bitwarden status
hermes secrets bitwarden sync        # dry-run: previsualiza lo que se aplicaría
hermes secrets bitwarden sync --apply  # exporta al shell actual

1Password:

hermes secrets onepassword status
hermes secrets onepassword sync        # dry-run
hermes secrets onepassword sync --apply  # exporta al shell actual

Inicia un nuevo proceso de Hermes (o un cron job, o el servicio gateway) para que coja los valores resueltos. Puedes confirmar la procedencia en el log de arranque o en el comando status del source.

5.2 Configura recordatorios de rotación

La mayoría de vaults permiten añadir un campo o nota con la fecha de rotación. Configura un recordatorio en el calendario cada 90 días. Cuando cambie una provider key, actualízala solo en el vault — nada más. El siguiente inicio de Hermes usará el valor nuevo.

Si el token de arranque filtra o expira, rótalo sin reejecutar todo el asistente:

hermes secrets bitwarden token
hermes secrets onepassword token

Ambos comandos prueban el token antes de guardarlo, así que un error de copia no romperá la configuración actual.

5.3 Mantén un camino de rollback

No saques todas las keys de golpe. Una secuencia más segura:

  1. Migración canario: Mueve una key no crítica (por ejemplo, una API de búsqueda de solo lectura) al vault y verifica.
  2. Observación con dual-write: Mantén el vault y .env poblados, pero activa override_existing: true en el source. Observa durante unos días.
  3. Eliminación limpia: Una vez estable, borra las líneas correspondientes de .env y deja solo el token de arranque.

Si algo falla, el rollback más rápido es deshabilitar el source:

hermes secrets bitwarden disable
hermes secrets onepassword disable

Hermes vuelve inmediatamente a su comportamiento anterior.


Errores comunes

  1. Poner secretos reales en config.yaml. config.yaml debe contener solo referencias (op://...) y project IDs; los valores reales deben permanecer en el vault.

  2. Guardar el token de arranque del vault en un .env compartido y commitearlo. BWS_ACCESS_TOKEN y OP_SERVICE_ACCOUNT_TOKEN son tokens de alto valor. Mantén .env fuera del control de versiones y restringe los permisos del archivo.

  3. Pensar que .env deja de tener efecto automáticamente. Por defecto, .env y las variables de shell ganan. Si un source tiene override_existing: false y aún hay viejas keys en .env, Hermes seguirá usando las de .env. Cuando quieras que el vault sea la fuente de verdad, activa override_existing: true.

  4. Ignorar las advertencias de conflicto. Cuando la misma variable aparece en varias fuentes, Hermes te avisa. No silencies la advertencia hasta confirmar qué fuente debe ganar, o usa secrets.preserve_existing para dejar variables específicas en .env.

  5. Usar desbloqueo interactivo en un servidor. op signin o sesiones BW_SESSION son válidos para portátiles, pero cron, gateway y CI deben usar service accounts o machine accounts con tokens no interactivos.

  6. Olvidar actualizar example.env. Una vez que los secretos son externos, example.env se convierte en la única documentación de las variables esperadas. Manténlo sincronizado con la estructura real del vault.


Combínalo con aprobaciones más inteligentes

Sacar las keys de .env es la mitad estática de la historia de seguridad. La v0.19.0 también activa por defecto las Smart Approvals: cuando Hermes quiere ejecutar un comando marcado, un revisor LLM independiente lo evalúa en lugar de pedirte que apruebes uno por uno. Combinado con el vault externo de secretos, obtienes dos capas de protección:

  • Seguridad estática: los secretos no terminan en disco en texto plano, no se propagan entre máquinas y son auditables.
  • Seguridad dinámica: las operaciones riesgosas reciben una segunda opinión, así que una sola llamada a herramienta excesiva no puede exfiltrar una key.

Resumen

SecretSource de Hermes v0.19.0 traslada la gestión de API keys de “copiar y pegar en .env” a “inyectar desde un vault externo bajo demanda”. Cinco pasos:

  1. Actualiza a v0.19.0 y confirma que hermes secrets existe.
  2. Autentícate con Bitwarden Secrets Manager o 1Password, y guarda el token de arranque en .env.
  3. Ejecuta el asistente y configura el source en config.yaml.
  4. Migra las keys de .env al vault, dejando solo el token de arranque.
  5. Verifica con status / sync, rota desde el vault y mantén un camino de rollback abierto.

Tu .env puede reducirse de docenas de líneas secretas a un único token de arranque, mientras Hermes sigue obteniendo cada secreto que necesita al inicio. La incorporación de nuevos miembros al equipo ya no implica pasarse archivos secretos, y la rotación de tokens ya no significa revisar una docena de configuraciones locales.

Referencias: