Gestión de secretos para agentes de IA: credenciales efímeras, broker y mínimo privilegio
Un vault no vuelve seguro a un agente si puede pedir un secreto global. La arquitectura correcta emite una credencial efímera, limitada y atribuible a una intención concreta.
La gestión de secretos para agentes de IA consiste en permitir que un runtime autenticado obtenga acceso temporal, mínimo y trazable a una tool concreta, sin entregar API keys de larga duración al modelo, al prompt ni a los logs.
Threat model: qué intentamos contener
El atacante puede conseguir que el modelo elija una tool peligrosa, manipular contenido recuperado para pedir una acción o aprovechar un plugin comprometido. También puede observar trazas, errores, cachés o variables de entorno si el runtime las expone. No supongas que el prompt es un canal confidencial ni que el modelo distingue una instrucción legítima de una inyección.
Los objetivos son reducir el impacto de una tool mal seleccionada, impedir que un tenant use credenciales de otro, evitar secretos persistentes en procesos y registros, y poder responder a un incidente con revocación y evidencia. El sandbox y la autenticación del usuario son controles relacionados, pero no sustituyen el broker.
Un caso de fallo es un documento externo que convence al agente de llamar a `create_invoice` para otro tenant. La identidad de workload puede ser válida, pero la política debe rechazar el tenant, la operación o el importe antes de que exista una credencial con ese alcance.

¿Te está sirviendo? Hay una dosis cada semana
Te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.
Suscribirme gratisEjemplo TypeScript: broker cerrado y allowlist
El borde importante es un contexto confiable cerrado, allowlist por tool y tenant, TTL acotado y ningún secreto impreso. En producción, `issueCredential` llama al proveedor desde el backend; el agente no puede invocarlo directamente ni elegir una ruta arbitraria.
Puntos a revisar
Lo que conviene comprobar
type Tool = "crm.read" | "tickets.create"; type TrustedContext = Readonly<{ workload:string; tenant:string; environment:"staging"|"prod"; session:string; policyVersion:string }>; const ALLOW = { staging:{"crm.read":["tenant-a","tenant-b"],"tickets.create":["tenant-a"]}, prod:{"crm.read":["tenant-a"],"tickets.create":[]} } as const; async function getToolCredential(ctx:TrustedContext, tool:Tool){ if(!ctx.workload || !ctx.session || !ALLOW[ctx.environment][tool]?.includes(ctx.tenant as never)) throw new Error("policy_denied"); const ttlSeconds=tool==="crm.read"?300:60; const issued=await issueCredential({audience:`tool:${tool}`,subject:ctx.workload,tenant:ctx.tenant,environment:ctx.environment,scopes:[tool],ttlSeconds}); audit({event:"credential_issued",tool,tenant:ctx.tenant,workload:ctx.workload,session:ctx.session,ttlSeconds,policyVersion:ctx.policyVersion}); return issued; }El tipado no reemplaza la validación en runtime. Firma o atesta el contexto, valida que la sesión pertenece al workload y rechaza valores desconocidos. Para mutaciones, añade aprobación humana o límites de importe; una allowlist de nombres no basta si los argumentos pueden cambiar el alcance.
TTL, cache, rotación y revocación
El TTL debe corresponder al tiempo razonable de una operación, no a la comodidad del equipo. Una lectura de cinco minutos puede usar un token de pocos minutos; una acción crítica puede exigir uno de un solo uso. Vault modela leases renovables y revocables, pero renovar indefinidamente convierte una emisión temporal en acceso casi permanente.
Cachea solo en memoria del worker y por la combinación exacta de workload, tenant, entorno, tool, scopes y política. Nunca compartas un token entre tenants ni lo persistás en Redis sin cifrado, aislamiento y expiración; muchas veces es más seguro pedir otro token que construir una caché global difícil de invalidar.
La rotación del secreto raíz del proveedor y la rotación de credenciales emitidas son capas distintas. Automatiza la primera y usa expiración/revocación para la segunda. Ante incidente, revoca por lease, workload, tenant o versión de política, deshabilita emisión y fuerza reautenticación. Diseña la ruta de emergencia antes de necesitarla.
Cuando el broker falla, elige disponibilidad o seguridad de forma explícita. Para una lectura puedes reintentar una emisión idempotente con backoff; no uses el último secreto persistente como fallback silencioso. Para una mutación, marca estado desconocido y reconcilia antes de repetir. OpenTelemetry puede correlacionar spans, pero configura scrubbing de atributos.
Antipatrones
Guardar una API key en el prompt del sistema: puede aparecer en trazas, snapshots, evaluación, caché o debugging. El modelo tampoco necesita ver el valor para usar una tool bien diseñada.
Montar todo el vault en variables de entorno: cualquier dependencia, volcado o herramienta de diagnóstico puede leer secretos globales. Inyecta solo el token temporal de la operación y limpia memoria cuando sea posible.
Crear un endpoint `get-secret(name)` para el agente: es una API de exfiltración con otra forma. Publica capacidades de negocio estrechas; el adaptador obtiene internamente la credencial adecuada.
Confiar en que el modelo respetará una instrucción de no revelar secretos. Las instrucciones son defensa adicional, nunca autorización. La frontera debe existir fuera del modelo y probarse con tests.
Preguntas frecuentes
¿Un vault resuelve la seguridad de un agente?
No. Resuelve almacenamiento y parte de la emisión; la seguridad depende de identidad, política, alcance, expiración, backend y auditoría.
¿El agente debe recibir el token temporal?
Idealmente no: el runtime o adaptador lo usa en memoria. El modelo recibe el resultado mínimo de la tool.
¿Cuánto debe durar un TTL?
Lo mínimo compatible con la operación. Empieza corto, mide reintentos y usa renovación explícita solo cuando sea necesaria.
¿Puedo cachear credenciales?
Solo en memoria y con identidad, tenant, tool, entorno y política como clave; evita cachés compartidas difíciles de revocar.
¿Identidad administrada sustituye al broker?
No. Evita secretos estáticos para autenticar el workload, pero la autorización por intención sigue siendo necesaria.
¿Cómo demuestro que no se filtran secretos?
Busca patrones en logs y trazas, añade evals de exfiltración y verifica que los resultados solo contienen datos permitidos; no prometas ausencia absoluta.
Conclusión
Cada llamada de un agente debe poder responder quién pidió qué, para qué tenant y entorno, con qué permiso, durante cuánto tiempo y qué ocurrió después. Si la respuesta requiere inspeccionar una API key global, la arquitectura todavía no tiene una frontera suficiente.
Fuentes y referencias
También te puede interesar
OIDC y credenciales efímeras para agentesSandbox para agentes de IA: ejecución aisladaPrompt injection en agentes de IA: defensas y evalsMCP en producción: seguridad y permisosOpenTelemetry GenAI para agentes de IARecibe una lectura semanal de herramientas IA para devs
Cada semana te resumo herramientas de IA para devs, agentes, MCP, seguridad y workflows en un email de 5 minutos. En español y sin ruido.
Suscribirme gratis