Pegaste un hermes dump para pedir ayuda y te llevaba dentro tu propia API key


Son la una de la madrugada, tu cron job ha vuelto a fallar y haces lo de siempre: ejecutas hermes dump, lo pegas en un hilo de Discord junto con unas líneas de log y pides ayuda. Media hora después alguien te escribe por privado: «oye, tu clave de OpenRouter sigue ahí, en el primer bloque».

No es un caso hipotético. hermes dump existe precisamente para producir «un resumen compacto en texto plano de tu configuración que se pueda copiar y pegar en Discord/GitHub», y la parte más fácil de pegar imprimía textualmente la API key de cada provider de respaldo. La corrección (PR #127207, construida sobre #126132 y #126168) aterrizó en main el 2026-09-29 y convirtió la redacción, que antes era una única pasada en el momento de subir, en dos pasadas: una cuando se genera el dump y otra cuando sale de tu máquina.

Primero, entiende qué estás compartiendo en realidad

En Hermes hay dos rutas para compartir información, y es fácil confundirlas:

  • hermes dump imprime un resumen de configuración pensado para copiar y pegar. Por defecto muestra el estado de cada clave como definida/no definida; --show-keys muestra los cuatro primeros y los cuatro últimos caracteres.
  • hermes debug share empaqueta logs (las últimas 200 líneas de cada archivo de log por defecto), los sube a un servicio de paste e imprime un enlace.

El segundo comando merece una lectura atenta:

--lines LINES    Lines included per log file (default: 200)
--expire EXPIRE  dpaste.com fallback retention in days (minimum 1; default 1)
--local          Print the report locally instead of uploading
-y, --yes        Skip confirmation and upload (required in scripts/CI)
--no-redact      Disable upload-time secret redaction
--nous           Upload to Nous-internal storage (AWS S3), not a public paste

El destino del paquete cambia por completo el radio de impacto:

Destino Visibilidad Retención Se puede borrar
paste.rs enlace público se elimina a las 6 horas caduca automáticamente
dpaste.com (alternativa) enlace público los días indicados en --expire (por defecto 1) no se puede borrar
--nous (S3) solo personal de Nous y moderadores en la lista blanca, tras un visor con login de Google 14 días caduca automáticamente

Así que un paste público te da una ventana de seis horas, y si la subida acaba cayendo a dpaste, el enlace se queda ahí durante la retención que hayas pedido… y no puedes eliminarlo. Decidir esto antes de pulsar intro vale muchísimo más que cualquier limpieza posterior.

Qué falló: str() sobre un objeto que llevaba una clave

La causa raíz es casi de lo más mundano. Un bloque del dump renderizaba la lista de providers de respaldo como cualquier otro objeto:

overrides["fallback_providers"] = str(fallbacks)

str() expandía dócilmente el campo api_key de cada entrada, más cualquier credencial incrustada en su base_url (piensa en https://user:token@gateway). Y encima venía la segunda capa: _capture_dump() devolvía el paquete sin redacción alguna; la redacción en el momento de subir solo se aplicaba a las instantáneas de logs, así que la sección de configuración viajaba desnuda.

Puedes revisar un paquete que ya tengas con un solo grep (eso sí, no lo ejecutes en un canal público):

hermes dump | grep -n -i "api_key\|base_url\|token\|signature"

Si ves un valor api_key: sk-... completo en lugar de ***, ese paquete no es seguro para publicar.

Después del arreglo: dos pasadas forzadas y tres formas que antes se colaban

El parche hace tres cosas, y cada una explica por qué volver a pegar es seguro.

Uno: el dump se redacta cuando se construye. Ahora las entradas de providers de respaldo pasan primero por un enmascarado a nivel de campo y después por una pasada de texto forzada con las reglas estrictas de credenciales en URL activadas:

overrides["fallback_providers"] = redact_sensitive_text(
    str(_mask_fallback_keys(fallbacks)), force=True, redact_url_credentials=True
)

Dos: la frontera de subida vuelve a redactar por su cuenta. _capture_dump() ahora fuerza la redacción del dump y respeta --no-redact, de modo que aunque quien lo invoque se olvide, el paquete se revisa una vez más antes de salir. Las claves de firma de la nube también entran en el ámbito: X-Goog-Signature de GCS, sig de Azure SAS y X-Amz-Signature cuentan todos como credenciales de URL.

Tres: el enmascarado por campo cierra tres puntos ciegos de la redacción de texto. Este es el sutil, y el más útil de entender. Las reglas de texto por sí solas se dejaban tres formas de api_key:

  • una clave numérica sin comillas (un entero YAML, no una cadena);
  • una clave escrita como mapping en lugar de escalar;
  • una clave que ya contenía ***, que el redactor da por ya enmascarada.

De ahí el orden: primero enmascarar por nombre de campo, después convertir las entradas en texto. Si inviertes el orden, sigues filtrando.

Qué hacer en tu propia máquina

Tres hábitos que solo desde este parche son seguros de dar por hechos:

  1. Prefiere --nous antes que un paste público. Cuando alguien necesita leer tus logs, hermes debug share --nous los deposita en un almacenamiento que exige login para verse y que se autodestruye a los 14 días. Recurre al paste público solo si la otra persona no tiene acceso interno, y asume la ventana de seis horas.
  2. No tires de --no-redact a la ligera. Significa «no redactar antes de subir», y el comando imprime un aviso aclarándolo. Úsalo solo cuando hayas revisado el contenido línea por línea y necesites de verdad los bytes en bruto (por ejemplo, para perseguir un prefijo de token que el enmascarado ocultó).
  3. Pega el dump en los issues, nunca el config.yaml. El dump está diseñado para informar de definido/no definido; el archivo de configuración lo lleva todo. Es la misma regla que explicamos en la guía para exportar sesiones: la redacción en cualquier ruta de exportación o de compartición es lo predeterminado, y lo único que tienes que hacer es no desactivarla.

Merece la pena aclarar una cosa: --show-keys tampoco «muestra tus claves»; enseña los cuatro primeros y los cuatro últimos caracteres para que confirmes cuál clave está en uso, no para copiarla.

Comprobar tu propia instalación

Si compartiste un paquete antes de finales de septiembre, dos minutos de comprobación salen baratos:

hermes --version                          # v0.21.5 or later main already carries the fix
hermes dump | grep -c "api_key: \*\*\*"   # expect greater than 0, i.e. field masking is live

Si el primer comando indica una build más antigua, actualiza y vuelve a comprobar. Y si ya hay un enlace público de dpaste por ahí suelto, el único remedio real es rotar esa clave en el provider: justo por eso mirar antes de pegar vale más que cualquier parche.

Para el resto de la maquinaria —espejos de sesión, reglas de salida de los chats de plataforma y de bot— consulta el artículo sobre los carriles de redacción; la lista completa de flags está en hermes dump y hermes debug.

La versión corta

  • La lista de providers de respaldo de hermes dump imprimía los valores de api_key y las credenciales dentro de base_url, por una llamada a str() sumada a una ruta de dump sin redactar.
  • Ahora hay dos pasadas forzadas: una cuando se genera el dump (enmascarado por campo más reglas estrictas de credenciales en URL) y otra en la frontera de subida (consciente de --no-redact).
  • Las tres formas que se le escapaban a la redacción de texto —claves numéricas, claves como mapping y claves que ya contenían ***— quedan cubiertas al enmascarar primero por nombre de campo.
  • Para logs compartidos, prefiere --nous (privado, 14 días); los paste públicos te dan seis horas, y la alternativa de dpaste no se puede borrar.
  • --no-redact significa «renunciar a la protección», no «más detalle». Pega el dump, no tu archivo de configuración.