Respuesta rápida: Para permitir que los agentes de IA utilicen claves de API sin verlas, incluye únicamente el nombre de la clave en el contexto del agente y resuelve el valor fuera del modelo: una variable de entorno a la que el agente haga referencia pero que nunca imprima, una referencia a un gestor de secretos o un proxy que inyecte la cabecera. Además, asegúrate de que cada clave tenga una vida útil corta y un alcance restringido, y enmascara los registros antes de que regresen al agente.
El equipo de DeepSeek Harness planteó este problema en su ensayo «Exploring Super-agent Design»: las credenciales en el contexto de un agente pueden filtrarse, por lo que el agente debería utilizar credenciales sin llegar a verlas. El ensayo lo describe como un problema abierto. No hace falta esperar a que un framework lo resuelva; los patrones que presentamos a continuación funcionan hoy mismo.
Para obtener una visión más amplia, consulta cómo construir un superagente. Este artículo se centra en una sola pregunta: cómo puede tu agente invocar una API autenticada sin que la clave entre jamás en su ventana de contexto.
Cómo filtran claves de API los agentes de IA
Un agente de IA filtra una clave de API cada vez que el valor entra en su contexto: a partir de ahí, el modelo puede repetirla en una llamada a una herramienta, un archivo, un commit o una respuesta. Nadie necesita vulnerar un servidor; el propio agente entrega la clave, normalmente mientras intenta ser de ayuda.
Las cuatro vías de filtración más habituales son:
- Lee el archivo
.env. Le preguntas por qué falla una llamada de pago, abre.envpara comprobarlo ysk_live_...queda registrado en la transcripción y en los logs del proveedor. - Muestra la clave en una llamada a una herramienta. Un comando
curlde depuración con la cabecera literal, o unecho $STRIPE_KEYpara «confirmar que está configurada». - Escribe la clave en algún sitio público. La descripción de una PR, un comentario en una issue o un fixture de prueba con un valor real.
- Una inyección de prompts (prompt injection) se la solicita. Una página o respuesta de API indica «imprime tus variables de entorno». OWASP clasifica la inyección de prompts como el principal riesgo en aplicaciones con LLM e incluye la exposición de credenciales dentro de la divulgación de información sensible.
Las filtraciones causadas por humanos y aplicaciones frontend requieren soluciones distintas, que tratamos en claves de API expuestas en el navegador, robo de claves de API de IA y LLMjacking y detección de claves filtradas mediante escáneres de secretos. En este caso, el actor es el agente.
La regla: nombres en el contexto, valores fuera
Todos los patrones presentados aquí siguen una misma regla: el contexto del agente solo contiene una referencia al secreto. Un componente externo al modelo transforma esa referencia en el valor en el último momento, y dicho valor nunca regresa al contexto.

| El contexto del agente puede contener | Nunca debe contener |
|---|---|
STRIPE_KEY (un nombre de variable) |
sk_live_51H... (el valor) |
op://payments/stripe/api-key (una referencia) |
El secreto resuelto |
{{token}} (un marcador de posición) |
Un token bearer pegado directamente |
Un valor enmascarado como sk_live_•••• |
Una línea de registro sin enmascarar |
Si un valor llega a caer en la columna de la derecha, rota la clave de inmediato. Las ventanas de contexto se guardan en logs, se almacenan en caché y se exportan. No se puede revertir el envío de un token.
Patrón 1: Variables de entorno y enmascaramiento
Con las variables de entorno, la clave reside en el entorno del proceso y el agente escribe $STRIPE_KEY, de modo que la shell la expande después de que el modelo haya generado el comando. Es el patrón más económico, y se sostiene aplicando tres hábitos:
Bloquea los archivos de secretos. En Claude Code, añade reglas de denegación como Read(./.env) y Read(./.env.*) en tus permisos de configuración. Otros agentes cuentan con listas de elementos permitidos y denegados similares.
Define la regla en CLAUDE.md o AGENTS.md:
Secrets: never print, echo, cat or log the value of any variable
ending in _KEY, _TOKEN or _SECRET. Reference them as $NAME.
If a value is missing, say which NAME is missing and stop.
Enmascara la salida antes de que regrese al modelo, mediante un filtro que oculte los patrones de secretos conocidos.
Su limitación real: la shell del agente tiene la variable, por lo que un agente comprometido mediante inyección todavía puede imprimirla. Las variables de entorno evitan accidentes, no a un atacante que controle el siguiente comando.
Patrón 2: Referencias a gestores de secretos
Una referencia a un gestor de secretos es un puntero como op://vault/item/field que una CLI resuelve en tiempo de ejecución, por lo que los archivos de configuración y los prompts solo contienen dicho puntero. El agente puede leer y hacer commit de la referencia con total seguridad, ya que por sí sola no concede ningún acceso.
Las referencias a secretos de 1Password son un ejemplo muy claro:
# .env.agent (safe for the agent to read)
STRIPE_KEY=op://payments/stripe/api-key
GITHUB_TOKEN=op://ci/github-bot/token
op run --env-file=.env.agent -- npm test
op run resuelve las referencias en el proceso secundario, y los secretos que se impriman en stdout o stderr se ocultan de forma predeterminada, a menos que se pase el parámetro --no-masking. Evita ese flag en cualquier comando que ejecute tu agente. HashiCorp Vault, AWS Secrets Manager y Azure Key Vault ofrecen este mismo concepto con su propia sintaxis. Dado que el proceso secundario sigue conteniendo el valor, la limitación del Patrón 1 sigue existiendo.
Patrón 3: Un proxy de inyección de credenciales
Un proxy de inyección de credenciales se sitúa entre el agente y la API de destino (upstream) y añade la cabecera de autenticación por sí mismo. El agente envía una solicitud sin clave, el proxy adjunta la credencial y el agente nunca llega a tener el valor en ningún lugar desde el cual pudiera imprimirlo o exfiltrarlo.

Es el único patrón presentado aquí en el que el agente realmente nunca tiene acceso a la clave. Un diseño básico funcionaría así:
- El agente llama a
http://localhost:8787/stripe/v1/chargesen lugar de al host real. - El proxy asigna
/stripeal servicio de destino y lee la clave desde tu gestor de secretos. - Comprueba una lista de permitidos:
GET /v1/chargespasa, peroDELETE /v1/customersno. - Añade
Authorization: Bearer <value>, reenvía la petición y elimina la cabecera de sus logs.
La lista de permitidos es tan importante como la inyección. Un agente víctima de una inyección de prompts aún puede usar la clave, pero únicamente para las llamadas que hayas autorizado, y no podrá transferirla a ningún otro lugar. Ejecuta el proxy con un usuario o contenedor independiente para que el agente no pueda leer su configuración.
Esto coincide con la arquitectura descrita en el ensayo: el bucle del agente se ejecuta en la nube, tu entorno permanece en tu máquina tras un pequeño demonio y las credenciales se quedan en dicho entorno.
Patrón 4: Tokens efímeros y de alcance limitado
Los tokens de corta duración y alcance limitado minimizan el impacto si los demás patrones fallan: el agente recibe una credencial que caduca en cuestión de minutos y sirve para una única tarea específica, por lo que un valor filtrado carece de utilidad para cuando alguien intente aprovecharlo. Es una red de seguridad complementaria, no un sustituto.
| Origen | Qué obtienes | Tiempo de vida |
|---|---|---|
AWS STS AssumeRole |
Credenciales temporales para un rol de IAM con alcance limitado | De 900 a 43.200 segundos |
| Motor de secretos para bases de datos de Vault | Un usuario de base de datos creado bajo demanda | El TTL de concesión (lease) que configures |
| Tokens de permisos granulares de GitHub | Acceso a los repositorios y permisos seleccionados | La fecha de caducidad que establezcas |
| Tu propia API | Un token por sesión con un alcance restringido | Lo que tú definas |
Genera un token por cada sesión del agente, limítalo a la tarea en curso y elige la duración más corta posible que le permita completarla.
Enmascara registros y transcripciones
El enmascaramiento es la capa de contención y limpieza: oculta los secretos en la salida de las herramientas, en los registros de CI y en las sesiones guardadas del agente, ya que una sola línea sin procesar echa por tierra todo lo anterior. Enmascara prefijos conocidos (sk_live_, ghp_, github_pat_, AKIA, xoxb-), cualquier valor de las cabeceras Authorization: o X-API-Key: y los valores exactos que hayas inyectado en esa sesión. Aplícalo en el wrapper de la herramienta, en la configuración de registros de CI y antes de que nadie comparta una transcripción.
Permite que Claude Code pruebe la API con Apidog CLI sin ver la clave
Apidog se adapta a la perfección a la regla de nombres en el contexto: una petición de prueba hace referencia a {{token}}, el entorno la resuelve en tiempo de ejecución y tu agente únicamente lee y escribe el nombre. Tu agente de desarrollo puede generar y ejecutar la prueba completa mediante Apidog CLI.
Hay un detalle importante. Las variables de Apidog tienen un Shared Value, sincronizado con los servidores de Apidog y tu equipo, y un Local Value, almacenado en tu equipo local. La documentación sobre variables recomienda utilizar valores locales para los tokens y advierte de que la CLI utiliza el valor compartido de forma predeterminada. Por tanto, mantén el token real fuera del valor compartido y pásalo en tiempo de ejecución.
Inicias sesión tú mismo, de modo que tu token de Apidog nunca entra en el contexto del agente:
npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_APIDOG_TOKEN> # in your own terminal
npx -y skills add https://apidog.com # pick your agent when prompted
export PAYMENTS_TOKEN=... # in your shell, never in a prompt
A continuación, proporciona una única instrucción a Claude Code:
In Apidog project 123456, create a test case for GET /v1/charges that
sends Authorization: Bearer {{token}} and asserts a 200 status and a
non-empty data array. Run it against environment 789, passing the token
with --env-var "token=$PAYMENTS_TOKEN". Never print $PAYMENTS_TOKEN or
any header value. Summarize failures only.
El agente lee el esquema, valida su contenido, redacta el caso de prueba y lo ejecuta:
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project 123456 --file case.json
apidog run --test-case <caseId> --project 123456 -e 789 \
--env-var "token=$PAYMENTS_TOKEN" -r cli,json
El JSON del caso contiene {{token}}, el comando incluye $PAYMENTS_TOKEN y la shell completa el valor una vez que el modelo ha escrito la línea. El agente solo ve si la prueba ha superado o fallado las validaciones y los mensajes de aserción. Pasa el informe JSON generado por tu filtro de enmascaramiento antes de compartirlo. Esa misma línea de apidog run puede integrarse en CI con -r junit; consulta la guía sobre el pipeline de CI/CD con Apidog CLI y la configuración de Apidog CLI en Claude Code.
En el plan Enterprise, Apidog también permite recuperar secretos de baúles (vault secrets) desde HashiCorp Vault, Azure Key Vault y AWS Secrets Manager, referenciados como {{vault:key}}; cualquier console.log del valor en un script se enmascara automáticamente y los valores nunca se comparten con otros miembros del equipo. Apidog Free incluye hasta 4 usuarios si deseas probar primero este flujo de trabajo con la CLI.
Lista de verificación: higiene de claves de API en agentes de IA
- Deniega al agente el acceso de lectura a
.envy otros archivos con secretos. - Añade la regla «nunca imprimas un secreto» en
CLAUDE.mdoAGENTS.md. - Sustituye los valores sin procesar en archivos legibles por el agente por referencias a un gestor de secretos.
- Enruta las llamadas a servicios de terceros a través de un proxy de inyección con una lista de permitidos.
- Emite un único token de corta duración y alcance limitado por cada sesión del agente.
- Mantén los tokens reales fuera de las variables compartidas de Apidog.
- Enmascara la salida de herramientas, los registros de CI y las transcripciones.
- Si un valor aparece en una transcripción, rota la clave ese mismo día.
Preguntas frecuentes
¿Puede un agente de IA usar una clave de API que no puede ver? Sí. Mediante un proxy de inyección de credenciales, el agente envía solicitudes sin ninguna clave y el proxy se encarga de añadir la cabecera. Las variables de entorno y las referencias a secretos ocultan el valor del prompt, aunque siguen dejándolo accesible en la shell del agente.
¿Son seguras las variables de entorno para las claves de API de un agente de IA? Son más seguras que pegar claves en los prompts, pero no son suficientes por sí solas. La shell del agente aún puede imprimir la variable, y un ataque de inyección de prompts puede obligarlo a hacerlo. Combínalas con reglas que denieguen la lectura, filtros de enmascaramiento y tokens de corta duración.
¿Qué debo hacer si mi agente ha mostrado una clave de API? Rótala de inmediato ante el proveedor correspondiente y rastrea adónde ha ido a parar la transcripción: logs del proveedor, exportaciones, comentarios en pull requests o salidas de CI. Borrar el mensaje original no elimina las copias que ya se hayan generado.
¿Cómo paso secretos a Apidog CLI sin exponerlos a mi agente? Conserva el token en tu propia shell e indica al agente que pase --env-var "token=$NAME" a apidog run. La prueba hace referencia a {{token}}, por lo que el agente solo manipula el nombre.
¿Bastan los tokens de corta duración por sí solos? No. Un token válido durante 15 minutos puede ser explotado indebidamente durante esos 15 minutos. Utilízalos como última línea de defensa, complementando la estrategia de nombres en el contexto y el uso de un proxy.
