Para clientes en nuestro Programa de Verificación de Ciberseguridad, proporcionamos un nuevo clasificador de escape de sandbox en la API para monitorear y reducir el abuso. Este artículo explica por qué los agentes autónomos necesitan un aislamiento fuerte, cómo el diseño de referencia los aísla, y cómo definir el alcance y supervisar compromisos que requieren acceso a la red.
Este clasificador está en beta privada.
Para obtener una descripción general de todos los recursos disponibles, consulta Mejores prácticas de contención de agentes: introducción (beta privada).
Descripción general
En una ejecución autónoma, ningún humano aprueba las llamadas de herramientas del agente, y el agente puede ejecutar código objetivo. Recomendamos ejecutar agentes autónomos en un sandbox fuerte que coloque un kernel virtualizado por hardware entre el host y tanto el agente como el código objetivo. No uses Docker/runc desnudo, y nunca uses
--privilegedo networking de host.El diseño de referencia ejecuta cada agente en su propia microVM (Kata Containers con Firecracker) en una red interna. Requiere un host Linux con KVM, lo que limita los hosts que pueden ejecutarlo. Kata ha descontinuado el runtime del que depende Firecracker.
Nunca montes rutas que contengan credenciales (como
~/.aws,~/.ssh, o.env) en el entorno del agente. Mantén la credencial del modelo-API fuera del entorno del agente también: haz que un proxy de credenciales separado la mantenga y la agregue a cada solicitud de modelo (consulta El proxy de credenciales).Deniega la salida por defecto. En el diseño de referencia, las llamadas de modelo pasan a través del proxy de credenciales, y el proxy de salida rechaza todos los demás destinos a menos que los incluyas en la lista de permitidos.
Prueba tu sandbox en cada host antes de confiar en él, y nuevamente cada vez que el sandbox o el modelo cambien.
Para compromisos que requieren acceso a la red, establece el alcance en las instrucciones del agente, aplícalo en la red, y mantén los agentes autónomos alejados de sistemas en vivo de alto impacto (consulta Alcance y supervisión).
Guía de sandboxing
Propiedades a las que apuntar
Si construyes tu propio sandbox, estas son las propiedades que proporciona el diseño de referencia. El resto de este artículo describe una forma de obtenerlas.
Cada agente tiene su propio kernel de invitado, que no comparte con el host.
Las herramientas de archivo y shell del agente ven solo el sistema de archivos del invitado. Ningún directorio del host se comparte en el invitado.
La credencial del modelo-API no está en el entorno del agente ni en su disco. Un proxy fuera del sandbox la agrega a cada solicitud.
El agente no tiene acceso a internet. La salida se aplica fuera del invitado, y todos los destinos se rechazan a menos que estén en una lista de permitidos.
El servicio de metadatos en la nube no se puede alcanzar desde el agente.
Cada agente tiene un límite de turnos, y un límite de tiempo si lo estableces.
Sin modo privilegiado, capacidades agregadas, paso de dispositivos o networking de host.
El orquestador se ejecuta en el host de confianza y escribe las transcripciones allí.
Directrices generales
Un sandbox fuerte es más importante para ejecuciones autónomas, donde los agentes ejecutan código objetivo y ningún humano aprueba cada acción
Ejecuta agentes autónomos en sandboxes fuertes, y reflexiona sobre qué efectos secundarios podría causar un proceso en ese sandbox. Los modelos fronterizos son cada vez mejores para encontrar caminos creativos alrededor de restricciones: la misma propiedad que los hace cazadores de vulnerabilidades efectivos significa que pueden tomar acciones inesperadas contra su propio entorno de ejecución. Esto no es hipotético. Anthropic ha publicado ejemplos de modelos que trabajan alrededor de restricciones débiles para completar una tarea (consulta Cómo contenemos a Claude en todos los productos).
Concretamente, no ejecutes agentes autónomos de búsqueda de vulnerabilidades en Docker/runc desnudo, y especialmente no con --privileged o networking de host. Los contenedores estándar comparten el kernel del host, por lo que un exploit del kernel dentro del contenedor es un compromiso del host. Recomendamos colocar un kernel virtualizado por hardware entre el código objetivo y el host, lo que significa ejecutar el agente en una máquina virtual. Donde eso no sea posible, usa un host bare-metal dedicado que no contenga nada más. Si construyes tu propio sandbox, recomendamos Firecracker en Linux, Hyper-V en Windows, y una VM basada en el framework Hypervisor en macOS. El diseño de referencia usa Firecracker.
Bloquea toda la salida del sandbox. El agente alcanza la API del modelo solo a través de un proxy que agrega la credencial y se ejecuta fuera del sandbox, por lo que el sandbox no necesita una ruta directa al host de la API. Instala cada herramienta, paquete y dependencia antes de que comience la ejecución, para que nada necesite ser descargado durante ella.
El uso interactivo, con un humano en el bucle, generalmente conlleva menos riesgo, pero aún recomendamos un sandbox para él. Si conduces un agente interactivamente desde Claude Code en una laptop, ya sea revisa cada uso de herramienta (modo manual), o confía en el clasificador de permisos de modo automático y haz que un humano apruebe cada acción que alcance fuera del repositorio. El modo automático elimina solicitudes de permiso rutinarias: aprueba lecturas y ediciones de directorio de trabajo automáticamente y envía todo lo demás a un clasificador de fondo que tiene como objetivo bloquear acciones destructivas, irreversibles o fuera de tarea. Es una verificación de mejor esfuerzo. Puede perder cosas, y en trabajo de seguridad también puede rechazar algunos pasos legítimos. Modo automático describe cómo funciona, qué esperar de él, y cómo configurarlo para tu entorno.
Nunca montes rutas que contengan credenciales como ~/.aws, ~/.ssh, o .env en el entorno del agente. Lo mismo aplica para la credencial que usan las propias llamadas de modelo del agente. Mantenla fuera del sandbox, y haz que un proxy que el agente no pueda leer la agregue a cada solicitud (consulta El proxy de credenciales). No conectes agentes a servidores MCP o herramientas con acceso de escritura a estado externo como correo electrónico, almacenamiento en la nube, o infraestructura de producción.
Divide cada ejecución en una fase de configuración y una fase de ataque con diferentes políticas de red
Este es un patrón que pone en práctica las directrices anteriores. La fase de configuración tiene acceso a internet saliente y un humano en el bucle que aprueba cada llamada de herramienta. En ella el agente extrae dependencias, construye el objetivo, y establece su sandbox a partir de un documento de especificación. La fase de ataque no tiene acceso general a internet. Toda la salida pasa a través de un proxy de lista de permitidos que permite solo los hosts nombrados en el compromiso, por lo que el proxy también aplica el alcance. Las llamadas de modelo pasan a través del proxy de credenciales separado. El agente puede entonces sondear el objetivo sin supervisión. El proxy contiene el tráfico propio del agente. No contiene tráfico que un objetivo en red envía en nombre del agente.
Incorpora las dependencias que el agente necesita repetidamente en la imagen de configuración, para que las ejecuciones de fase de ataque no necesiten acceso a internet en absoluto. Alcance las credenciales por objetivo, para que un agente que trabaja en un objetivo no pueda usarlas contra otro. Mantén el modo automático de Claude Code activado dentro del sandbox durante la fase de ataque y describe el sandbox a su clasificador. Consulta Modo automático.
Limita cada ejecución, y conoce tu interruptor de emergencia
Dale a cada agente un presupuesto explícito, para que una ejecución que exceda su prueba prevista se detenga por sí sola y no cuando alguien lo note. Aplica un límite de turnos duro en cada agente. Cuando un agente lo agota, termina la ejecución y no otorgues más turnos automáticamente. Relanzar con un límite más alto es el punto en el que una persona decide continuar. Limita las ejecuciones en tiempo también. Termina una sesión que exceda su límite de tiempo de la misma manera: la ejecución es final y nunca se reanuda, y el proceso del agente se detiene, incluso cuando el límite se alcanza en medio de un comando de larga duración. Si un límite se establece en un valor que no se puede leer, rechaza lanzar en lugar de ejecutar sin límite. Establece los límites deliberadamente para el compromiso y no aceptes un valor predeterminado generoso. Emparéjalos con la cadencia de monitoreo en monitoreo sin conexión de transcripciones de agentes, para que un lote largo se observe cada una o dos horas y no solo al final. Sabe cómo detener un solo agente sin detener el lote. En una configuración basada en Docker eso es docker rm -f <agent-container>. El orquestador debe registrar esa ejecución como fallida y continuar con el resto del lote.
Para más orientación, lee dos recursos de Anthropic. Despliegue seguro de agentes de IA cubre opciones de aislamiento, proxying de credenciales, y endurecimiento del sistema de archivos. El retrospectivo de ingeniería Cómo contenemos a Claude en todos los productos cubre qué funcionó y qué no cuando estos mismos mecanismos se ejecutaron en producción.
Alcance y supervisión
El sandbox limita lo que un agente puede alcanzar. Para pruebas de penetración, red team, y otros compromisos que requieren acceso a la red, las prácticas a continuación limitan lo que se le pide y se le permite hacer al agente. Dependen de tus objetivos y tu equipo, por lo que las herramientas no pueden poner la mayoría de ellas en su lugar para ti.
Establece el alcance en las instrucciones del agente
Antes de una ejecución, dile al agente cuáles objetivos están en alcance, qué acciones se permiten, dónde está el límite de la red, y qué está fuera de alcance. Expresa cada restricción como intención ("no accedas a hosts fuera de 10.0.3.0/24") y no como una afirmación sobre el entorno ("no puedes alcanzar internet"), para que la instrucción siga siendo válida si el entorno está mal configurado. Haz esto también para trabajo local en sandbox: dile al agente que no use acceso a internet, aunque el sandbox lo bloquee. La descripción que das al clasificador de modo automático es algo diferente. Establece hechos sobre la máquina (consulta Modo automático).
Aplica el mismo alcance en la red
Donde puedas, ejecuta el agente dentro del mismo aislamiento descrito anteriormente, y lista de permitidos la salida solo a los objetivos en alcance (consulta Lista de permitidos de salida). El agente alcanza la API del modelo a través del proxy de credenciales, no a través de la lista de permitidos. Donde uno esté disponible, apunta el compromiso a un entorno de preparación o réplica que esté desconectado de la producción.
Intermediar el acceso al objetivo donde puedas
Dale al agente acceso a sistemas objetivo a través de algo que puedas observar, como un proxy de acceso o un conjunto definido de herramientas. Evita dejar que el agente escriba su propia herramienta con acceso general al objetivo. En un arnés personalizado, separa herramientas de solo lectura de herramientas que cambian estado, y supervisa el segundo grupo más de cerca. Considera analizar comandos riesgosos a medida que se proponen, y denegarlos o escalarlos a una persona.
Supervisa ejecuciones que tienen acceso a la red
Recomendamos que un ingeniero observe cada ejecución mientras se ejecuta, siguiendo llamadas de herramientas y actividad de red, y pueda detener la ejecución inmediatamente. Los agentes actúan a velocidad de máquina, por lo que la observación en vivo complementa los controles que actúan antes de que se ejecute una acción (listas de permitidos de red, herramientas intermediadas, y revisión de acciones que cambian estado). No los reemplaza. Para ejecuciones largas o autónomas donde la atención continua es impráctica, monitorea continuamente en software (consulta Monitoreo sin conexión de transcripciones de agentes).
Mantén agentes autónomos alejados de sistemas en vivo de alto impacto
No ejecutes agentes autónomos contra sistemas de producción en vivo donde una acción fuera de alcance podría poner en peligro la seguridad o la disponibilidad de servicios críticos, como sistemas OT/ICS, médicos, o de energía. Esto ya es la norma para pruebas dirigidas por humanos de tales sistemas, y se aplica igualmente aquí. Prueba contra una réplica, un banco de pruebas, o un gemelo digital, o durante una interrupción planificada. Donde el acceso en vivo es inevitable, limita el agente a actividad pasiva o de solo lectura y haz que una persona ejecute cada paso que cambia estado.
Prueba el sandbox antes de confiar en él
Antes de ejecutar compromisos reales desde un host, prueba su sandbox con los dos pasos a continuación. Haz esto antes del primer uso real, y nuevamente cada vez que cambies el modelo o el sandbox. Los cambios de sandbox incluyen un nuevo host, una nueva versión del hipervisor o runtime de contenedor, una configuración de red o proxy diferente, y una configuración de contenedor o compose editada.
Primero, haz que Claude revise la configuración
En una sesión interactiva de Claude Code en el host, pídele que lea la configuración del sandbox tal como está configurada en esta máquina e informe cualquier cosa que debilite el límite que describe este artículo. Señálale:
La configuración del hipervisor y el tiempo de ejecución del contenedor (para el diseño de referencia, el
configuration.tomlrenderizado de Kata y eldaemon.jsonde Docker);La red de los agentes y el proxy de salida tal como los reporta el tiempo de ejecución, y la lista de permitidos del proxy;
El proxy de credenciales tal como lo reporta el tiempo de ejecución, y el entorno de un contenedor de agente en ejecución (ver El proxy de credenciales abajo);
Cualquier archivo de composición u orquestación que inicie agentes u objetivos;
La lista de lo que está montado o transmitido a los invitados (ver Notas operativas abajo).
Este paso solo lee configuración y estado. No inicia un agente.
Luego, ejecuta una prueba de escape supervisada
Inicia el agente de prueba de la misma manera que inicias agentes de producción, y no con un comando construido manualmente, para que la prueba ejercite la ruta real. La sección Verifica el aislamiento tú mismo abajo cubre las verificaciones manuales del límite en su lugar. Dale al agente una única tarea: intenta alcanzar cualquier cosa fuera de su límite, y detente e informa tan pronto como algo tenga éxito. Nombra el límite concretamente en el mensaje: el host, otros contenedores, el socket del tiempo de ejecución del contenedor, el servicio de metadatos en la nube, y cualquier host que no esté en la lista de permitidos del proxy. Ejecuta esto solo bajo supervisión humana cercana, en un host sin acceso a internet más allá de la API del modelo y que estés preparado para reconstruir, para que un escape exitoso no cause daño. En metal desnudo, ejecuta la prueba dentro de una máquina virtual desechable. En una máquina virtual en la nube, usa una instancia nueva y destrúyela después. Observa la sesión mientras se ejecuta. Trata cualquier éxito como un bloqueador: corrige el host, repite la prueba, y no ejecutes compromisos desde ese host hasta que la prueba pase.
Después, lee toda la transcripción
Verifica qué intentó el agente así como si salió. Busca conexiones directas que no pasaron por el proxy, lecturas de archivos de credenciales o direcciones de metadatos, uso del socket del tiempo de ejecución del contenedor o sondeos de contenedores vecinos, escrituras fuera del propio sistema de archivos del contenedor, e intentos de cambiar la configuración o herramientas del propio agente. La prueba pasa cuando la transcripción muestra que cada uno de esos fue intentado y falló por la razón que esperas. Registra, para cada uno, si el sandbox o el clasificador de permisos lo detuvo. Un intento que el clasificador rechazó nunca llegó al sandbox, así que cúbrelo con las verificaciones manuales (ver Verifica el aislamiento tú mismo abajo). Una prueba que pasa es una barra mínima, no prueba de aislamiento.
Evita tareas imposibles, y revisa primero las ejecuciones fallidas
Confirma antes del lanzamiento que la tarea se puede completar tal como se da. Algunos ejemplos de tareas que no se pueden completar: un área de enfoque sin nada que encontrar, un objetivo que no es alcanzable, un error que no existe, o una herramienta que la tarea necesita que no está instalada. Siempre que cambies tu configuración o comiences un nuevo tipo de tarea, confirma antes del lanzamiento que el objetivo se construye y se puede alcanzar y que el agente tiene las herramientas que necesita. Por la misma razón, cuando revises un lote, lee las transcripciones de las ejecuciones que fallaron o no encontraron nada antes de las que tuvieron éxito.
Verifica el aislamiento tú mismo
Ejecuta estas verificaciones manualmente en cada host. La segunda columna describe la verificación para el diseño de referencia (Docker con el tiempo de ejecución de Kata y Firecracker). Adáptala a tu propio tiempo de ejecución.
Qué confirmar | Cómo | Resultado esperado |
Un kernel de invitado separado | Ejecuta | Las dos versiones difieren |
El monitor de máquina virtual está encarcelado en el host | Para un contenedor en ejecución, inspecciona el proceso de Firecracker: su directorio raíz, | Solo los archivos propios de la máquina virtual están bajo su raíz. |
Un archivo del host no es visible adentro | Crea un archivo en el host e intenta leerlo desde un contenedor aislado | No encontrado. Esta es una verificación básica que cualquier tiempo de ejecución debería pasar |
La salida es rechazada | Desde un contenedor de agente, solicita el host de la API del modelo y otro host público a través del proxy de salida | Ambos son rechazados, y el proxy de salida registra una línea de denegación para cada uno. Los agentes alcanzan el modelo solo a través del proxy de credenciales |
Sin credencial en el contenedor del agente | Mientras una ejecución está activa, enumera el entorno del contenedor del agente, filtrado por nombres de proveedores | Un marcador de posición, la dirección del proxy de credenciales, y configuración del proveedor. Sin clave real, token o archivo de credencial |
El diseño de referencia
Esta sección describe cómo la implementación de referencia cumple con la orientación anterior. La implementación no está incluida. Léela como un diseño que puedes copiar.
Cómo se aísla cada agente
Cada agente se ejecuta como claude -p dentro de su propia microVM, junto al binario de destino y la fuente. La microVM es un contenedor de Kata Containers respaldado por el monitor de máquina virtual Firecracker, registrado con Docker como un tiempo de ejecución. Las herramientas Read, Write y Bash del agente ven solo el sistema de archivos y el kernel de ese invitado.
La conexión entre un invitado y el host es deliberadamente pequeña. Consiste en KVM y los pocos dispositivos virtuales que Firecracker emula: dispositivos de bloque para el disco del contenedor, una interfaz de red, y un canal de control vsock que Kata usa para iniciar procesos dentro del invitado. El proceso de Firecracker en sí está confinado en el host. Se ejecuta en una "cárcel", que es un directorio chroot que contiene solo los archivos de esa máquina virtual, con su propio espacio de nombres de montaje, el espacio de nombres de red del contenedor, y el filtro seccomp integrado de Firecracker. Se contabiliza en el cgroup del contenedor. Lo que confías en el lado del host es KVM, Firecracker, y el proceso de tiempo de ejecución de Kata (el "shim" por contenedor que Docker habla, que se ejecuta como root).
El orquestador permanece en el host de confianza. Gestiona el ciclo de vida del contenedor, transmite transcripciones, y mueve archivos dentro y fuera con docker exec, que Kata sirve a través de su agente dentro del invitado. El iniciador inicia agentes solo dentro de este sandbox. Antes de que cualquier agente comience, verifica que el tiempo de ejecución del sandbox esté registrado, que /dev/kvm esté presente, y que el proxy de salida esté activo, y se niega a ejecutar de otra manera.
Lo que el sandbox cambia para cada superficie:
Superficie | Sin sandbox | Con sandbox |
Agente | sistema de archivos del host | solo sistema de archivos del invitado (el disco virtual propio del contenedor, bajo el kernel del invitado) |
Agente | solo shell del host | solo shell del invitado (kernel del invitado; el host es alcanzable solo a través de KVM y los dispositivos virtuales de Firecracker) |
Salida de red | lo que tenga el host | sin acceso a internet; solo llamadas de modelo, a través del proxy de credenciales |
Credencial de API de modelo | en el entorno del agente | no en el contenedor del agente; mantenido por un contenedor proxy de credenciales separado (ver El proxy de credenciales abajo) |
Acoplamiento de host | completo |
|
Verificaciones de permisos | solo clasificador de modo automático | clasificador de modo automático más el límite de microVM (ver Modo automático) |
Dónde se aplica cada propiedad: la virtualización de hardware proporciona el límite del kernel y del sistema de archivos. Las operaciones Read/Write/Bash del agente se ejecutan contra el kernel del invitado, y el proceso Firecracker detrás de él está encarcelado y confinado con seccomp en el host. La política de salida se aplica en el lado del host de la interfaz de red de la VM, mediante un puente Docker --internal (sin ruta predeterminada hacia afuera) y los dos proxies en esa red. El proxy de credenciales reenvía llamadas de modelo y nada más. El proxy de salida rechaza todos los demás destinos, porque su lista de permitidos está vacía a menos que la amplíes. El tráfico sale a través de la pila de red propia del invitado; el filtrado ocurre en los dos proxies.
El proxy de credenciales
La credencial para la API del modelo (tu clave de API, token OAuth, credencial de AWS o Google) nunca se coloca en un contenedor de agente. El orquestador en el host la lee y valida, y cada lanzamiento inicia un contenedor pequeño adicional, el proxy de credenciales, para mantenerla. El proxy está conectado a la red interna de los agentes, y los contenedores de agentes envían sus llamadas de modelo a él: su CLI claude obtiene la dirección del proxy como su URL base de API, y un valor de marcador de posición fijo donde normalmente iría la clave o el token. Esto sigue la mejor práctica de acceder a la API del modelo solo a través de un proxy, con la clave de API inyectada desde fuera del sandbox. En el diseño de referencia, el proxy es un contenedor separado en la red de los agentes, no un proceso en el localhost del agente. Para cada solicitud, el proxy:
Rechaza cualquier cosa que no sea una llamada de modelo al único punto final del proveedor para el que se configuró el lanzamiento (otras rutas y hosts obtienen un 403 y una línea de registro);
Elimina cualquier encabezado de autenticación que envió el contenedor;
Añade la credencial real: el encabezado de clave de API, un token portador (que el proxy actualiza a sí mismo cuando el token tiene corta duración), o una firma AWS SigV4 calculada sobre la solicitud exacta;
Reenvía la solicitud al proveedor sobre HTTPS con verificación de certificado, y transmite la respuesta de vuelta.
Para un contenedor de agente comprometido, esto significa que no hay clave, token o archivo de credencial para leer, copiar o enviar a ningún lado. Los servicios de metadatos en la nube también son inaccesibles desde el contenedor. Lo que el contenedor aún puede hacer es hacer llamadas de modelo a través del proxy, en tu cuenta, mientras la ejecución esté activa. Por esa razón, prefiere una credencial con alcance estrecho para ejecuciones de agentes, y rótala después de cualquier ejecución cuya transcripción muestre comportamiento inesperado. El proxy registra una línea por solicitud, con la dirección del cliente, método, ruta, estado y tamaño. No registra encabezados ni cuerpos. Guarda ese registro cuando finalice la ejecución (ver la sección Retención en Monitoreo sin conexión de transcripciones de agentes).
Cualquier cosa que el agente envíe a la API del modelo sale de tu red, en cuerpos de solicitud que el proxy no inspecciona ni registra.
Lo que cada lado mantiene, por ruta de autenticación:
Ruta | Lo que mantiene el proxy de credenciales | Lo que obtiene el contenedor del agente |
Clave de API | la clave | dirección del proxy + marcador de posición |
Token OAuth ( | el token | dirección del proxy + marcador de posición |
Federación de identidad de carga de trabajo (WIF) | el token de identidad, más el token de acceso que el proxy intercambia por él y actualiza. Con | dirección del proxy + marcador de posición |
perfil | el directorio de perfil, montado como solo lectura en el proxy | dirección del proxy + marcador de posición |
Bedrock | el token portador, o el conjunto de clave de acceso (el proxy firma cada solicitud) | dirección del proxy, |
Vertex | la clave de cuenta de servicio, más los tokens de acceso que el proxy acuña a partir de ella y actualiza | dirección del proxy, |
El contenedor proxy de credenciales es parte del lado de confianza de la configuración. Se ejecuta bajo runc simple en lugar del tiempo de ejecución del sandbox, como root con todas las capacidades eliminadas excepto la que necesita para leer los archivos montados, y con un sistema de archivos de solo lectura. Escucha solo en su dirección en la red interna de los agentes, y se conecta al proveedor directamente en lugar de a través del proxy de salida. El orquestador pasa la credencial al proxy en ejecución sobre docker exec. Para las rutas de archivo de token WIF y perfil, el directorio que contiene el token o perfil se monta como solo lectura en el proxy, que lee el archivo desde allí. La credencial no está en el entorno del contenedor proxy ni en su línea de comandos, por lo que docker inspect en él muestra los montajes y no un secreto.
Inicia un proxy por lanzamiento, y elimínalo cuando finalice la ejecución o se interrumpa. Busca proxies dejados atrás por una ejecución que fue eliminada, y elimínalos antes del siguiente lanzamiento.
El proxy de credenciales tiene dos efectos secundarios. Primero, se le da a la CLI de los agentes una dirección de API no predeterminada, por lo que algunas características de CLI que se aplican solo a la dirección predeterminada están desactivadas dentro de los contenedores de agentes. Su telemetría y verificaciones de actualización también se desactivan, porque de todos modos no tendrían ruta hacia afuera. Segundo, en Vertex el filtro de ruta del proxy es el control principal que impide que un contenedor de agente use el resto de la API de Vertex AI (ver Lista de permitidos de salida). Una verificación del alcance de IAM de la clave en el lanzamiento es una segunda capa.
Lista de permitidos de salida
La lista de permitidos del proxy de salida está vacía por defecto. Los contenedores de agentes alcanzan la API del modelo solo a través del proxy de credenciales (ver El proxy de credenciales). Cada lanzamiento inicia ese proxy para el proveedor que seleccionan tus credenciales, por lo que nada específico del proveedor se almacena en la configuración del sandbox. Todos los demás destinos que un agente solicita a través del proxy de salida, incluido el host de la API del modelo en sí, obtienen un 403 y una línea de denegación en su registro. Los valores de región que seleccionan los puntos finales de Bedrock y Vertex (AWS_REGION, CLOUD_ML_REGION) se verifican contra un patrón estricto antes de usarse, para que un valor mal formado no pueda enviar la credencial a un host diferente.
Vertex tiene un límite a tener en cuenta. …aiplatform.googleapis.com sirve toda la API de Vertex AI, por lo que una credencial que está autorizada para crear trabajos personalizados podría ejecutar un contenedor arbitrario con salida de internet completa en tu proyecto. Usa dos controles contra esto. Haz que el proxy de credenciales reenvíe solo llamadas de modelo de editor en tu proyecto configurado (…/publishers/anthropic/models/…:rawPredict, :streamRawPredict, y :countTokens) y rechaza todas las demás rutas. Y verifica el alcance de IAM de la clave en el lanzamiento y falla cerrado: rechaza ADC de usuario de gcloud, verifica una clave de cuenta de servicio con testIamPermissions, y recházala si contiene algún permiso de creación de carga de trabajo. Otorga a la cuenta un rol personalizado que contiene solo aiplatform.endpoints.predict. El servidor de metadatos, STS de Google y los puntos finales de credenciales de IAM no deben ser accesibles desde contenedores de agentes.
Si los agentes necesitan alcanzar hosts adicionales, como un espejo de paquetes o un objetivo en el alcance, añádelos a la lista de permitidos del proxy de salida como entradas host:port. Añade solo lo que necesita el compromiso (ver Alcance y supervisión).
No agregues el host de la API del modelo a esta lista. Los agentes no lo necesitan, porque sus llamadas de modelo pasan a través del proxy de credenciales. Agregarlo proporciona a los contenedores de agentes una ruta directa a la API, y el resto del diseño, incluido lo que se le dice al clasificador de permisos, asume que no tienen ninguna.
Cambiar la lista de permitidos significa reiniciar el proxy de salida, lo que interrumpe cualquier conexión de agente activa. Hazlo entre lotes en lugar de durante uno, y confirma después qué lista cargó el proxy.
Deriva el punto final del proveedor de tu configuración de credenciales e ignora una variable de URL base como ANTHROPIC_BASE_URL que se establece en el host: el proxy de credenciales siempre debe reenviar al punto final que seleccionan las credenciales.
Construir y operar un sandbox como este
Esta sección recopila lo que se aprendió al ejecutar agentes bajo Kata con Firecracker en la implementación de referencia. No es un conjunto de pasos de instalación.
Requisitos del host
El diseño de referencia necesita una máquina Linux física o una VM que pueda ejecutar VMs:
Linux x86_64 o aarch64 con KVM (
/dev/kvmpresente y utilizable): metal desnudo o una VM en la nube con virtualización anidada habilitada.GCE, Azure y AWS ofrecen virtualización anidada en tipos de instancia seleccionados (en AWS, por ejemplo, las familias C8i, M8i y R8i). Las instancias de metal desnudo de AWS (
*.metal) también funcionan.La virtualización anidada cuesta algo de rendimiento. No se espera que debilite el límite.
Almacenamiento de dispositivos de bloque para contenedores. Firecracker no puede compartir un directorio del host en un invitado; el único almacenamiento que puede adjuntar a una VM es un dispositivo de bloque. Los sistemas de archivos raíz de los contenedores, por lo tanto, deben existir como dispositivos de bloque en lugar del sistema de archivos de superposición habitual. Con Docker, el snapshotter
devmapperde containerd proporciona eso. Necesita Docker sin raíz (el diseño de referencia usa Engine 25 o más reciente) respaldado por el containerd del sistema (2.0 o más reciente).Acceso a la red saliente mientras construyes el host y las imágenes. Los agentes no obtienen esta salida.
No funcionará en:
un contenedor o un pod de Kubernetes, incluido Docker-in-Docker y ejecutores de CI basados en contenedores. El containerd del host, el demonio de Docker y el mapeador de dispositivos no se pueden configurar desde dentro de un contenedor, y KVM generalmente tampoco está disponible allí;
Docker sin raíz;
una VM sin virtualización anidada, que es la mayoría de los tipos de instancia en la nube de propósito general a menos que elijas uno que la ofrezca y la actives;
macOS o Windows, incluidos Docker Desktop y WSL2.
El diseño de referencia no admite hosts macOS o Windows
Su sandbox necesita KVM en un host Linux. Docker en una Mac se ejecuta dentro de una VM Linux compartida que monta el directorio de inicio del usuario y aloja el demonio de Docker, por lo que no puede proporcionar aislamiento de hardware por agente. Si trabajas en una Mac, ejecuta los agentes en un host Linux con KVM (metal desnudo o una VM en la nube con virtualización anidada) e impúlsalos a través de SSH. Si construyes tu propio sandbox en macOS o Windows, consulta los hipervisores nombrados en la sección Directrices generales anterior.
Cambiar el almacén de imágenes de Docker tiene un efecto secundario
Las imágenes y contenedores creados en el almacén anterior de Docker se vuelven invisibles para Docker después del cambio al snapshotter devmapper. Se quedan en el disco. Para verlos de nuevo, coloca ambas configuraciones de almacenamiento en daemon.json (storage-driver y features.containerd-snapshotter) de vuelta a lo que eran y reinicia Docker.
Configuración de Kata
Fija la versión de Kata y verifica su resumen antes de instalarlo. El diseño de referencia comienza desde el perfil de Firecracker de Kata y fija estas configuraciones en /etc/kata-containers/configuration.toml:
Configuración | Valor | Por qué |
| ruta al binario | Inicia Firecracker dentro de su jaula: un chroot con solo los archivos de la VM, su propio espacio de nombres de montaje, el espacio de nombres de red del contenedor y el filtro seccomp de Firecracker. Si se deja sin establecer, Kata ejecutaría Firecracker sin la jaula. |
|
| Un contenedor no puede cambiar ninguna configuración del hipervisor a través de anotaciones OCI. |
|
| El perfil seccomp de Docker para el contenedor también se aplica dentro del invitado, una segunda capa bajo el límite de la VM. |
|
| Firecracker y sus subprocesos de E/S se colocan en el cgroup del contenedor, por lo que la VM se contabiliza en el contenedor. Si el límite |
|
| Firecracker no puede agregar CPUs o memoria a una VM en ejecución, por lo que la VM se dimensiona una vez al arrancar desde los límites del contenedor. |
|
| Línea de base por VM; el |
|
| Sin consola en invitados y sin salida de consola de invitado en registros del host. |
|
| Desactivado, porque el templating de VM compartiría páginas de memoria de invitado entre VMs. |
|
| Entropía de host sin bloqueo para invitados. |
Los valores de kernel, image y kernel_params que vienen con la versión de Kata se mantienen tal como están.
Hacer el kernel e imagen del invitado inmutables
Cada VM arranca desde los mismos dos archivos, Kata los vincula en cada jaula, y el carcelero se inicia como root, por lo que los permisos de archivo ordinarios no detendrían un proceso Firecracker comprometido de reescribir la imagen desde la que arranca cada VM posterior. Establece la bandera inmutable en ambos (chattr +i). Borrar esa bandera requiere una llamada al sistema que el filtro seccomp de Firecracker no permite, diseñado para evitar que incluso root dentro de la jaula lo haga. Borra la bandera tú mismo antes de instalar una nueva versión de Kata. En un sistema de archivos sin soporte chattr, usa un montaje de vinculación de solo lectura en su lugar.
Dimensionamiento
Memoria
Cada VM de agente se dimensiona una vez, al arrancar: default_memory más el --memory del contenedor. Con una línea base de 4096 MiB y un límite de contenedor 4g, un agente es una VM de 8 GiB. El host asigna esa memoria a la VM conforme el invitado la usa, no toda al arrancar, pero planifica la cantidad completa por agente concurrente: diez agentes en paralelo pueden crecer hacia 80 GiB. Si el límite --memory del contenedor también limita la VM en su conjunto depende de cómo estén distribuidos los cgroups del host. Verifica cuál de estos se aplica en tu host:
El límite del contenedor se aplica a toda la VM. Un agente no puede usar más memoria del host que
--memoryaunque su VM sea nominalmente más grande, y una VM que exceda el límite se mata desde el lado del host.Nada en el host limita la VM por debajo de su tamaño de arranque. El uso de memoria de un agente está limitado por el tamaño de la VM (
default_memory+--memory) y el asesino de falta de memoria del kernel del invitado.Un cgroup padre la limita a un valor diferente.
No hemos confirmado este comportamiento en todo tipo de host. De cualquier forma, dimensiona el host por tamaño de VM.
CPUs
Cada VM obtiene default_vcpus. Firecracker no puede agregar CPUs a una VM en ejecución, así que para objetivos con mucha compilación aumenta el valor antes del lanzamiento; el máximo es 32 por VM.
Disco
Cada imagen y cada contenedor obtiene un disco virtual de un grupo delgado de device-mapper, que respalda el almacén de imágenes. Si el grupo se llena, las escrituras dentro de contenedores fallan con errores de E/S o sin espacio. Si el sistema de archivos que contiene el grupo se llena primero, el grupo se vuelve de solo lectura y cada contenedor en él falla. Libera espacio con docker rmi y docker system prune (los bloques liberados vuelven al grupo). sudo dmsetup status <pool> muestra el uso. Para un host de larga duración, un grupo delgado LVM en un disco dedicado es el mejor diseño.
Tiempo de arranque
Cada inicio de agente arranca un kernel de invitado. Eso toma bien menos de un segundo en metal desnudo y unos pocos segundos bajo virtualización anidada, lo cual es pequeño comparado con los tiempos de ejecución del agente.
Endurecimiento del host
Dedica el host a este trabajo.
Asume que un agente podría leer cualquier cosa en él, y no mantengas credenciales ni datos sensibles allí excepto la credencial de API del modelo que los agentes necesitan.
Mantén cada capa que el tráfico del agente toca parcheada, no solo el kernel: Docker, las imágenes base de los contenedores proxy, y cualquier firewall o dispositivo de red entre el host y la API del modelo. Un proxy o firewall desactualizado en el límite de la sandbox es en sí mismo superficie de ataque.
Mantén el kernel, KVM y el microcódigo de CPU actuales, y deja las mitigaciones de vulnerabilidad de CPU del kernel en sus valores predeterminados.
grep . /sys/devices/system/cpu/vulnerabilities/*no debe mostrar líneasVulnerable.Si el host se comparte con cargas de trabajo que no deben observarse entre sí, también sigue la guía de configuración de host de producción de Firecracker sobre configuraciones de SMT y ejecución especulativa.
Desactiva swap (
sudo swapoff -a, y elimínalo de/etc/fstab) para que la memoria del invitado no se escriba en swap./dev/kvmno necesita ser escribible por todos, y los directorios de instalación y tiempo de ejecución de Kata deben permanecer siendo propiedad de root y no escribibles por otros usuarios.root:kvmcon modo0660es suficiente para/dev/kvm, porque el tiempo de ejecución de Kata se ejecuta como root.
Nunca agregues
--privileged,--device,--cap-add, o redes de host a contenedores de agentes o a servicios objetivo.Bajo Kata esas banderas pasan dispositivos de host y privilegios a la VM.
Mantén agentes en la red interna detrás de los dos proxies.
Firecracker no hace filtrado de paquetes por su cuenta; la red del lado del host y los proxies son el control de salida.
Mantén
enable_debugdesactivado fuera de la solución de problemas; el registro de depuración incluye la salida de la consola del invitado.
Validación de un nuevo host
Después de configurar una máquina nueva, esta secuencia muestra que la sandbox funciona de extremo a extremo. Los pasos 3 y 4 hacen llamadas de modelo reales.
Ejecuta las comprobaciones de aislamiento bajo Verifica el aislamiento tú mismo. Las dos versiones del kernel deben diferir. Nota si el límite de memoria del contenedor limita la VM (ver Dimensionamiento).
Confirma que la CLI del agente se ejecuta bajo el tiempo de ejecución de sandbox, en la imagen que usarás.
Prueba el límite: haz que Claude revise la configuración de la sandbox, luego ejecuta la prueba de escape supervisada, ambas como se describe en Prueba la sandbox antes de confiar en ella.
Ejecuta un pequeño lote de extremo a extremo contra un objetivo que conoces. Ejecuta este paso con el modo de credencial que usarás para compromisos reales, no una clave de API sustituta: el proxy de credencial maneja cada modo de manera diferente (intercambio de tokens para WIF, firma para Bedrock, acuñación de tokens para Vertex), y esta ejecución confirma que la tuya funciona de extremo a extremo. Verifica el registro del proxy de credencial después.
Verifica que nada quedó atrás. Una vez que el lote haya terminado, no debe permanecer ningún contenedor de agente, contenedor auxiliar, proceso de VM o proxy de credencial. El registro del proxy de salida debe mostrar sin líneas de denegación excepto las sondas de los pasos 1 y 3, y el registro del proxy de credencial debe mostrar solo llamadas de modelo.
Notas operativas
Ejecutar agentes bajo Kata con Firecracker difiere de ejecutar contenedores simples de estas maneras.
Los montajes de vinculación son copias; los archivos activos tienen que ser transmitidos
Firecracker no tiene compartición de sistema de archivos de host, así que Kata copia un archivo o directorio montado en vinculación al invitado cuando el contenedor se inicia, y los cambios posteriores en el host no se ven dentro. Eso está bien para entradas que no cambian durante una ejecución, como el origen objetivo, y esas pueden permanecer como montajes de solo lectura. Ningún archivo de credencial se monta o transmite, porque los contenedores de agentes no contienen ninguno (ver El proxy de credencial). Un archivo que cambia durante una ejecución tiene que ser escrito en el contenedor por el orquestador, a través de docker exec, y mantenerse actualizado. Las copias en contenedor son archivos ordinarios que un agente podría editar, así que haz que el orquestador lea los originales en el host, y juzga los hallazgos de una copia que el agente bajo prueba no puede alcanzar.
Cada agente necesita un contenedor complementario para su red
Las interfaces de red de una microVM deben existir cuando la VM arranca; Firecracker no puede agregar una después. Docker, sin embargo, conecta la red de un contenedor solo después de que el tiempo de ejecución ha creado el contenedor. El diseño de referencia funciona alrededor de esto. Primero inicia un pequeño contenedor inactivo que está conectado a la red correcta y ejecuta solo sleep, y luego inicia el agente dentro del espacio de nombres de red de ese contenedor (--network container:<name>). Kata encuentra las interfaces allí al arrancar y las adjunta a la VM. Un complemento sirve exactamente una VM, porque Kata deja los dispositivos de red del lado del host de la VM detrás en él, así que crea y elimina el par juntos y no reutilices un complemento. Uno cuesta un proceso inactivo de aproximadamente 12 MB.
Detener un agente atascado
docker rm -f <agent-container> es suficiente. El orquestador debe detectar el contenedor muerto, marcar la ejecución como fallida, y eliminar el contenedor complementario cuando desglosa la ejecución.
Todo se aborda por IP
El DNS integrado de Docker se ejecuta en el espacio de nombres de red del lado del host y no es accesible desde dentro de un invitado, así que pasa los proxies a los agentes como direcciones IP y asigna a los objetivos en red una IP estática.
docker exec funciona, docker cp no
docker exec en un contenedor de agente se comporta como es habitual; el agente de Kata dentro del invitado ejecuta el comando. docker cp dentro o fuera de un contenedor de agente no funciona, porque los archivos del contenedor están en un disco virtual dentro del invitado. Usa docker exec <container> cat <path> y similares.
Firecracker se ejecuta como root dentro de su jaula
Kata inicia el jailer con uid 0, por lo que el proceso de Firecracker está confinado por su chroot, espacios de nombres, filtro seccomp y cgroup, no por un id de usuario sin privilegios. Los dos archivos que comparte cada VM, el kernel del invitado y la imagen, están protegidos por la bandera inmutable en su lugar (ver Configuración de Kata).
Kata ha descontinuado el runtime del que depende Firecracker
Kata ejecuta Firecracker a través de su runtime Go más antiguo. Kata 4.0 hizo que un runtime Rust más nuevo fuera el predeterminado para sus otros hipervisores y descontinuó el runtime Go. Upstream dice que el runtime Go aún recibe correcciones críticas de errores y correcciones de CVE, y que puede ser eliminado no antes de Kata 5.0. El runtime Rust no enumera a Firecracker entre sus hipervisores, y upstream prueba su integración con Docker principalmente con QEMU. Planifica una migración. Cuando cambies la versión de Kata, repite Validar un nuevo host. Kata también puede usar Cloud Hypervisor en lugar de Firecracker; la implementación de referencia no ha probado ni endurecido esa configuración.
Registros
Los mensajes del runtime de Kata, Firecracker y guest-agent van al diario: journalctl -t kata. Los problemas de containerd y Docker están en journalctl -u containerd y journalctl -u docker.