Seguridad de agentes de IA: claves API, sandbox y límites
Seguridad de agentes de IA en la práctica: proteger claves API, configurar permisos y sandbox en Claude Code, límites de gasto y escaneo de secretos. Paso a paso.
Este artículo en otros idiomas:العربيةDeutschEnglishFrançaisItaliano日本語Polski简体中文
En este artículo
- ¿Por qué la seguridad de agentes de IA se ha vuelto urgente?
- Paso 1: ¿cómo configurar los permisos en Claude Code?
- Paso 2: ¿cómo activar el sandbox?
- Paso 3: ¿dónde guardar las claves API?
- Paso 4: ¿cómo configurar límites de gasto?
- Paso 5: ¿cómo detectar secretos antes de que se filtren?
- ¿Qué vigilar con los servidores MCP?
- Preguntas frecuentes
La seguridad de agentes de IA se reduce a tres cosas: el agente solo ve lo que necesita, las claves API no están donde el agente (o un atacante) pueda leerlas y cada clave tiene un límite de gasto. A continuación, cinco pasos que podemos completar en una tarde: permisos, sandbox, orden con las claves, límites y escaneo de repositorios.
¿Por qué la seguridad de agentes de IA se ha vuelto urgente?
Las últimas semanas han dado ejemplos de sobra. Tras la filtración de OpenCode, varios usuarios mostraron facturas por el uso ajeno de sus claves. En el ciberataque con IA a más de 100 empresas, los agentes entraron casi sin intervención humana, y en paneles de Cairn expuestos había cientos de secretos. Además, la filtración de Meta Muse demostró que incluso una función de «compartir chat» puede revelar más de lo que parece.
El 21 de octubre llegó otro caso: según SafeDep, la versión 1.107.0 de la popular biblioteca LiteLLM llegó a PyPI con un stealer que recopilaba, entre otras cosas, claves SSH, credenciales de la nube, secretos de CI/CD y claves de proveedores de LLM, además de una puerta trasera. Los atacantes tenían las credenciales de GitHub CLI de tres desarrolladores. PyPI retiró esa versión ese mismo día, y la 1.106.2, entre otras, está limpia.
Un agente se diferencia de un chat en que ejecuta acciones: lee archivos, lanza comandos, visita páginas web. OWASP describe dos riesgos principales:
- Inyección de prompts. Según OWASP, en la variante indirecta el modelo acepta instrucciones «from external sources, such as websites or files». Basta un README o una página con una instrucción oculta para que el agente haga algo que nunca le pedimos.
- Agencia excesiva («excessive agency»). OWASP enumera tres causas: demasiadas funciones, demasiados permisos y demasiada autonomía. En el avance de la lista de 2026, este riesgo subió al tercer puesto.
OWASP mantiene además una lista Top 10 para aplicaciones agénticas, cuyo primer puesto es «Agent Goal Hijack», es decir, el secuestro del objetivo del agente.
La regla de oro de ambas listas es la misma: los permisos mínimos que basten para la tarea y la aprobación de una persona para las acciones arriesgadas.
Paso 1: ¿cómo configurar los permisos en Claude Code?
Lo mostraré con Claude Code (lo expliqué desde cero en mi tutorial de Claude Code), pero la misma lógica sirve para otros harnesses de agentes.
Los permisos se definen en settings.json como reglas allow, ask y deny. Según la documentación, el orden es fijo: «deny, then ask, then allow», así que la denegación siempre gana. Para empezar, bloqueemos el acceso a los secretos. Este ejemplo viene directamente de la referencia de configuración:
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Read(./config/credentials.json)",
"Bash(curl *)"
]
}
}
Ojo: las reglas deny tienen límites, y la documentación los menciona sin rodeos:
- No se aplican a comandos que leen archivos sin nombrarlos, como
grep -r pattern ., ni a subprocesos arbitrarios. Bash(curl *)coincide con el comando de forma literal, así que no detendrá/usr/bin/curlnish -c 'curl …'.- Un archivo
.claudeignoreno tiene ningún efecto; sus entradas hay que pasarlas a reglasReaddentro dedeny.
Por eso las reglas son la primera capa, no toda la protección. Los permisos actuales se comprueban con el comando /permissions.
Lo segundo es el modo de trabajo. Claude Code tiene los modos default, acceptEdits, plan, auto, dontAsk y bypassPermissions. Sobre el último, la documentación dice: «Only use this mode in isolated environments like containers or VMs». En un ordenador compartido podemos desactivarlo por completo poniendo permissions.disableBypassPermissionsMode en "disable".
Paso 2: ¿cómo activar el sandbox?
El sandbox es una frontera que vigila el propio sistema operativo, así que funciona donde las reglas deny no llegan. Según la documentación del sandbox, viene desactivado por defecto. Se activa con un comando en la sesión:
/sandbox
o poniendo sandbox.enabled en true en ~/.claude/settings.json. En macOS funciona sin más; en Linux y WSL2 necesita dos paquetes:
sudo apt-get install bubblewrap socat
En Windows sin WSL2 no hay sandbox y los comandos se ejecutan sin aislamiento.
Qué aporta el sandbox una vez activado:
- Los comandos solo escriben en el directorio de trabajo y en archivos temporales.
- El tráfico de red pasa por un proxy local, y la lista de dominios permitidos (
network.allowedDomains) empieza vacía. - Sin embargo, pueden leer casi todo el disco, incluidos
~/.sshy~/.aws/credentials. Esas rutas hay que bloquearlas a mano confilesystem.denyReado con la seccióncredentials, porque, como dice la documentación, «There is no built-in credential deny list».
Dos observaciones de la documentación. Primero, el sandbox solo cubre los comandos de shell: las herramientas Read, Edit, Write y WebFetch, los hooks y los servidores MCP locales funcionan fuera de él. Segundo, dominios amplios como github.com en la lista de permitidos pueden abrir una vía para la exfiltración de datos. Quien quiera aislarlo todo a la vez debería ejecutar el agente entero en un contenedor o una máquina virtual.
En Codex de OpenAI, el equivalente son los modos read-only, workspace-write y danger-full-access, con la red desactivada por defecto. La opción --yolo (alias de --dangerously-bypass-approvals-and-sandbox) desactiva tanto las aprobaciones como el sandbox, así que dejémosla para los contenedores.
Paso 3: ¿dónde guardar las claves API?
La regla más sencilla: la clave no va al código ni al repositorio. Anthropic recomienda no escribir la clave directamente en el código ni en archivos de configuración y añadir los archivos .env a .gitignore. OpenAI aconseja pasar las claves mediante variables de entorno o un gestor de secretos y rotarlas con regularidad.
En la práctica:
- Claves separadas para desarrollo, pruebas y producción (también lo recomienda Anthropic). Así una filtración no lo tumba todo.
- La clave del agente es una clave aparte con su propio límite, no la principal.
- Tras una filtración, revocamos la clave de inmediato y solo después buscamos la causa.
Curiosamente, GitHub detecta por sí mismo parte de las filtraciones. Si una clave de Claude acaba en un repositorio público, GitHub avisa a Anthropic, que desactiva la clave automáticamente.
Paso 4: ¿cómo configurar límites de gasto?
Un límite no evita la filtración, pero acota la factura si la clave cae en malas manos.
- Anthropic. En la Claude Console entramos en la página Billing (
platform.claude.com/settings/billing) y, en la sección Spend limits, hacemos clic en Adjust limit o Set limit. También se pueden fijar límites por workspace, salvo en el predeterminado. - OpenAI. En la configuración del proyecto entramos en Limits, fijamos un Monthly spend limit y activamos Enforce a hard limit. Atención: las alertas de gasto («Spend alerts do not enforce a cap») no bloquean nada, y el propio límite actúa con retraso, así que el gasto puede superarlo ligeramente.
Un buen hábito es un proyecto (o workspace) por agente, cada uno con su clave y su límite.
Paso 5: ¿cómo detectar secretos antes de que se filtren?
Los agentes escriben mucho código y hacen commits con gusto, así que conviene tener un sistema automático que detenga una clave antes del push.
- Push protection en GitHub. Según la documentación, bloquea los pushes con secretos antes de que lleguen al repositorio. En cuentas de usuario está activada por defecto para repositorios públicos; a nivel de repositorio viene desactivada y requiere GitHub Secret Protection.
- Gitleaks en local. Se instala con
brew install gitleaksy escanea un directorio o el historial de git (README):
gitleaks dir -v .
gitleaks git -v .
- TruffleHog comprueba además si el secreto encontrado sigue funcionando (README). Con esta herramienta NorForge verificó que parte de los secretos de los paneles de Cairn estaban activos:
trufflehog filesystem path/to/dir
¿Qué vigilar con los servidores MCP?
Un servidor MCP es código que se ejecuta con nuestros permisos. La documentación de Claude Code recomienda escribir servidores propios o usar solo los de proveedores de confianza, y advierte de que Anthropic no audita los servidores MCP.
Las buenas prácticas de seguridad de MCP (versión borrador de la especificación) añaden algunos detalles concretos:
- El cliente debería mostrar el comando completo que arranca un servidor local, sin recortar. El ejemplo de ataque de la especificación es un
npxinocente tras el que se esconde uncurlque envía~/.ssh/id_rsaa un servidor ajeno. - Los servidores locales conviene ejecutarlos en un sandbox con permisos mínimos y mediante el transporte
stdio. - Un servidor no debe aceptar tokens que no se emitieron para él (el llamado «token passthrough» está prohibido).
- Los permisos OAuth se conceden de forma gradual, sin ámbitos amplios como
*,allofull-access.
Preguntas frecuentes
¿Bastan las reglas deny de Claude Code para proteger un archivo .env?
No del todo. Bloquean las herramientas integradas y los comandos reconocidos como cat, pero no grep -r ni subprocesos arbitrarios. La protección completa a nivel de sistema solo la da el sandbox con filesystem.denyRead.
¿Qué hacer si se ha filtrado una clave API?
Revocarla de inmediato en el panel del proveedor, generar una nueva, sustituirla en todas las aplicaciones y revisar el consumo reciente de la cuenta. Más detalles en el artículo sobre la filtración de OpenCode.
¿Qué es la inyección de prompts en los agentes de IA?
Son instrucciones ocultas en contenidos que lee el agente (páginas, archivos, correos). El agente puede ejecutarlas como si fueran nuestras. Por eso las acciones arriesgadas deberían requerir nuestra aprobación y el agente no debería tener acceso a secretos.
¿Funciona el sandbox en Windows?
En Claude Code, solo a través de WSL2. En Windows nativo los comandos se ejecutan sin sandbox.