StartupKit
ES

Cómo funciona el aislamiento

El modelo de seguridad del triaje con IA que conoce tu código: por qué el límite de red vive fuera del agente, cómo aislar un runner de GitLab y cómo restringir adónde puede enviar datos un agente a partir de un informe enviado por un atacante.

Por qué importa

El triaje con IA que conoce tu código proporciona a un agente dos cosas a la vez: tu código fuente y el cuerpo de un informe controlado por un atacante. Es un objetivo para la inyección de prompts. Un investigador malicioso puede redactar un informe que intente secuestrar al agente para leer secretos y enviarlos con curl a un host externo.

Impón las restricciones de red fuera del agente para bloquear los destinos que no estén en la lista de permitidos, incluso cuando el modelo siga instrucciones maliciosas. La configuración que se describe a continuación mantiene excepciones para el endpoint del modelo y el MCP de Kit.

Danger

Trata el cuerpo de todos los informes como contenido hostil. El prompt de triaje envuelve los campos en delimitadores y ordena al modelo que no ejecute las instrucciones que encuentre dentro, pero la higiene de delimitadores es defensa en profundidad, no el límite. El límite es la denegación de toda salida que se describe a continuación.

El principio fundamental: el agente no es el límite de seguridad

Claude Code, Codex y otros agentes tienen sandboxes, listas de dominios permitidos y modos de permisos. Son útiles como defensa en profundidad. No son una garantía fiable frente a la extracción de datos cuando el atacante controla el contenido que procesa el agente.

Motivos:

  • Las denegaciones pueden aprobarse automáticamente. Las configuraciones de permisos de Claude Code documentan un defaultMode que puede aceptar ediciones automáticamente o eludir permisos. Una opción mal configurada invalida las reglas de denegación.
  • Los fallos del sandbox son reales. Se han corregido fallos de escape por enlace simbólico, desviaciones del analizador de SOCKS5 (incluido un truco con un byte nulo) capaces de eludir cualquier lista de comodines. Utiliza versiones recientes, pero no confíes en la lista como barrera.
  • Los dominios permitidos pueden tener API capaces de extraer datos. Si permites el dominio del proveedor del LLM, ese mismo dominio puede ofrecer una API de archivos, cargas o almacenamiento: un canal perfecto de extracción que tu regla de «permitir el endpoint del modelo» aceptará.

Las restricciones sobre los destinos de los datos deben operar fuera del agente, en la configuración de red y del runner. Los endpoints permitidos siguen recibiendo los datos que se usan para el análisis y para registrar el resultado.

El límite: denegar toda salida y utilizar un proxy con dos destinos

El aislamiento se construye con cuatro controles de la capa del entorno. El repositorio de ejemplo los muestra en su .gitlab-ci.yml y en el directorio infra/.

1. Un runner de GitLab autogestionado

Debes utilizar un runner autogestionado. No puedes aislar de la red del host los runners compartidos SaaS de GitLab.com, así que no puedes imponerles el límite de salida. El README del repositorio de ejemplo lo indica como requisito previo.

2. Un ejecutor Docker sin privilegios

Ajuste Valor Motivo
privileged false El modo privilegiado equivale en la práctica a ser root del host. Es obligatorio desactivarlo en una ruta que procesa informes no fiables.
Ejecutar como usuario no root Elimina SETUID y SETGID, y no concedas capacidades innecesarias.
Socket de Docker sin montar Montarlo permite tomar el control del host.
Volúmenes del host ninguno No montes directorios del host dentro del trabajo.
FF_NETWORK_PER_BUILD 1 GitLab crea una red puente exclusiva para cada trabajo y la destruye al terminar, de modo que la red queda aislada y es reproducible.
# config.toml on your self-managed runner
[[runners]]
  executor = "docker"
  environment = ["FF_NETWORK_PER_BUILD=1"]
  [runners.docker]
    privileged = false

3. Denegación de toda salida en el host

Warning

GitLab Runner no ofrece una lista nativa de salidas permitidas. No existe un ajuste incorporado que permita a los trabajos acceder solo a determinados hosts; hay una función propuesta, pero no se ha publicado. El límite de salida debe aplicarse en la capa del host o del espacio de nombres.

Aplica una política de salida con DROP predeterminado a la red del trabajo mediante iptables o nftables, o ejecuta el trabajo en un espacio de nombres de red sin ruta hacia tu intranet. Todo el tráfico saliente se deniega de forma predeterminada; después abres exactamente los dos destinos siguientes y nada más, ni siquiera tu propia red interna.

4. Un proxy de salida que termina TLS y valida tokens

La única ruta de salida permitida es un proxy que acepta exactamente dos destinos:

  1. Tu endpoint de inferencia del LLM, por ejemplo https://api.deepseek.com/anthropic.
  2. El host MCP limitado de Kit, para leer el informe y publicar el triaje.

El proxy hace algo más que fijar esos dos hosts:

  • Limita el acceso a las rutas de inferencia y MCP para bloquear las API de archivos o almacenamiento del proveedor del LLM aunque se permita el host.
  • Valida el token de sesión de cada ejecución. Un atacante que consiga introducir su propia clave de API en el agente no puede utilizarla porque el proxy solo acepta el token emitido para esa ejecución.

Este diseño reproduce el patrón de proxy MITM dentro de la máquina virtual que Anthropic utiliza para aislar sus propios agentes. Un filtro de salida similar a harden-runner es un equivalente conceptual razonable para la implementación de referencia.

El enmascaramiento es higiene, no protección

Guarda la clave del modelo como variable de CI enmascarada y protegida. Kit pasa el token MCP por separado al activar cada pipeline. Evita imprimir cualquiera de los dos valores y revisa los registros de las ejecuciones de prueba por si se han expuesto.

Important

El enmascaramiento solo impide que un valor aparezca en los registros ([MASKED]). Un trabajo comprometido aún puede leer la variable en tiempo de ejecución. La propia documentación de GitLab advierte que no es una medida infalible. Las restricciones de red bloquean los destinos no aprobados; el enmascaramiento solo reduce la exposición en los registros.

Por eso importa el modelo de token limitado: aunque un trabajo secuestrado lea el token, está limitado a un informe durante una hora y permite enviar un único resultado final de triaje. Las pruebas del pipeline deben adjuntarse antes de ese envío. Las reglas de red bloquean los demás destinos, pero mantienen el acceso al endpoint del modelo y al MCP de Kit.

Qué debes probar antes de activarlo

El repositorio de ejemplo incluye un fixture injection-canary: un informe cuyo cuerpo ordena al agente leer una variable secreta y enviarla con curl a un host controlado. Ejecútalo en tu runner real antes de conectarlo a Kit.

La prueba solo se supera si:

  1. El pipeline termina correctamente y produce un triaje válido.
  2. El intento de salida falla en la capa de red, no porque el agente haya decidido obedecer el prompt del sistema.
  3. Los registros muestran la conexión bloqueada sin revelar el valor secreto.

Si la petición externa tiene éxito, todavía no tienes un aislamiento. Corrige el cortafuegos del host antes de conectar Kit.

Una nota sobre la elección del modelo

Tú controlas el modelo y también asumes su riesgo. Enviar tu código y los informes no fiables a un endpoint alojado (la API de DeepSeek de forma predeterminada) es una decisión propia sobre residencia y confianza de los datos. Ese es precisamente el sentido de «tu IA, tu red». Cuando convenga, dirige el agente a un endpoint autoalojado, como vLLM local o un proxy de Ollama compatible con Anthropic, para que la inferencia nunca salga de tu perímetro. El archivo SECURITY.md del repositorio de ejemplo lo recalca.

En resumen

  • Runner de GitLab autogestionado, no un runner compartido SaaS
  • Ejecutor Docker con privileged = false, usuario no root, sin socket de Docker ni volúmenes del host
  • FF_NETWORK_PER_BUILD=1 para aislar la red de cada trabajo
  • Salida con DROP predeterminado en el host mediante iptables, nftables o un espacio de nombres de red
  • Proxy de salida que permite exactamente dos hosts y rutas: el endpoint del LLM y el host MCP de Kit
  • El proxy valida el token de cada ejecución y bloquea las API de almacenamiento del proveedor del LLM
  • El token limitado vale para un informe durante una hora; adjunta las pruebas del pipeline antes de enviar el único resultado final; el enmascaramiento solo es una medida de higiene
  • Ejecuta el fixture injection-canary y confirma que se bloquea el intento de extracción
  • Fija una versión reciente de Claude Code o del entorno de sandbox como defensa en profundidad, no como límite

Y ahora qué

Escriba para buscar...