Cambiar tema

Guía de Agent Sandbox: solución completa para ejecutar código de IA con seguridad

Easton editorial illustration: one shielded sandbox containing an agent code cube

En primavera de 2025, investigadores de seguridad hicieron algo directo: probaron los 16 agentes de IA públicos del batch Spring de Y Combinator. Resultado: 7 fueron comprometidos. Algunos filtraron datos de usuarios, otros permitieron ejecución remota de código y uno borró la base de datos entera.

Ese es el precio de dejar que un agente de IA ejecute código. Le das libertad y te deja una trampa.

Todos usamos IA para escribir código, ejecutar scripts y procesar datos. Pero ¿has pensado si te atreves a correr en el servidor código generado por un gran modelo? Si hace un rm -rf / o envía en secreto tus claves de AWS a un servidor externo, no tendrás dónde quejarte.

Ahí entra Agent Sandbox.

¿En qué se diferencia un agente de IA de una app tradicional? No en que converse o entienda instrucciones, sino en que puede escribir y ejecutar código por sí mismo.

Imagina: pides a un agente de análisis que procese 1 GB de datos de ventas. Escribe Python para leer, analizar y generar gráficos. El código lo generó el modelo; tú no lo revisaste. Y se ejecuta.

Hay varios riesgos graves:

Ejecución arbitraria de código. El modelo no entiende límites de seguridad. os.system(), subprocess.run() los usa cuando hace falta, sin pensar en consecuencias. Un prompt bien diseñado puede forzar comandos del sistema.

Ataque de agotamiento de recursos. El código del agente no tiene conciencia de recursos. Un bucle infinito satura la CPU; una recursión sin fin revienta la memoria. El servidor cae.

Escalada en el sistema de archivos. Sin restringir rutas, puede leer todo el disco y escribir donde quiera. Configuración, claves, datos de usuarios: todo a su alcance.

Fuga de datos por red. Una petición HTTP oculta envía datos sensibles al servidor del atacante y puede pasar desapercibida.

OWASP publicó en 2025 el Top 10 de amenazas de seguridad para agentes de IA. La número uno es «manipulación de la interacción con herramientas del agente»: el atacante, con prompt injection u otros medios, desvía cómo el agente invoca herramientas.

Ya hay casos reales:

  • Vulnerabilidad RCE en Langflow: ejecución remota de código descubierta por Horizon3; entrada maliciosa ejecuta código arbitrario en el servidor.
  • Ejecución automática en Cursor: investigadores encontraron que Cursor ejecuta ciertos comandos MCP; un prompt malicioso puede dispararlos.
  • Borrado de base de datos en Replit: código generado por IA eliminó la base de datos completa.

El sandbox no es opcional. Es infraestructura del agente de IA, como no exponer un servidor a internet sin firewall: no deberías ejecutar código de IA sin sandbox.

El valor del sandbox se resume en tres puntos: aislamiento (encerrar código riesgoso), límites (tope en CPU, memoria, red y archivos) y auditoría (registrar qué hizo para investigar incidentes).

Comparativa de soluciones sandbox

Si necesitas sandbox, ¿qué usar? Hay tres rutas principales: contenedores (Docker), gVisor y microVM Firecracker.

Una tabla comparativa para orientarte:

EnfoqueAislamientoArranqueRecursosEscenario
Contenedor Docker★★☆☆☆★★★★★★★★★★Dev/test, código de bajo riesgo
gVisor★★★★☆★★★★☆★★★☆☆Producción, riesgo medio
Firecracker★★★★★★★★★☆★★★☆☆Alta seguridad, producción

Contenedor Docker: rápido pero insuficiente

Docker es lo más común: arranque rápido, poco consumo, ecosistema maduro. Pero contenedor y host comparten kernel.

Los procesos del contenedor están aislados por namespace, pero si alguien explota el kernel, cruza el límite y obtiene root en el host.

En 2024 se publicaron varias vulnerabilidades de escape de contenedor. Para código no confiable generado por IA, Docker no basta.

gVisor: un «kernel falso» en espacio de usuario

gVisor es un proyecto open source de Google. La idea: no usar el kernel del host directamente, sino un «kernel falso» (Sentry) en espacio de usuario.

Cuando el programa del contenedor hace una llamada al sistema, gVisor la intercepta y Sentry la procesa. Solo operaciones seguras; las peligrosas se rechazan. Aunque el código intente dañar, no toca el kernel real.

Ventaja: buena compatibilidad; la mayoría de imágenes Docker funcionan. Inconveniente: sobrecarga ~10-20% y algunas llamadas especiales pueden no estar soportadas.

GKE soporta gVisor de forma nativa: una línea runtimeClassName: gvisor en el Pod.

Firecracker: aislamiento real a nivel de hardware

Firecracker es microVM open source de AWS. Cada sandbox es una VM pequeña con kernel propio.

¿Qué implica? Aunque el atacante tenga root en el sandbox y explote el kernel, solo afecta esa VM, no el host.

Arranque en 100-800 ms; mucho menos overhead que VMs tradicionales (mínimo ~128 MB de RAM por VM).

E2B, AWS Bedrock AgentCore y otros servicios profesionales de sandbox para IA usan Firecracker por debajo.

Marco de decisión

Árbol simple:

  1. ¿Solo desarrollo local? Docker basta: rápido y práctico.
  2. ¿Producción?
    • Seguridad media y rendimiento → gVisor
    • Alta seguridad y compliance → Firecracker
  3. ¿Sin operar infraestructura? Servicio gestionado (E2B, Bedrock AgentCore)

Práctica: sandbox local de desarrollo

Pasemos a montar uno: FastAPI + Jupyter Kernel + contenedor gVisor.

¿Por qué esta combinación?

  • FastAPI ofrece HTTP limpio; el agente envía código por REST
  • Jupyter Kernel da Python interactivo con variables persistentes
  • gVisor aísla y evita que código malicioso afecte al host

Paso 1: servicio FastAPI

Crea main.py:

# main.py
import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException
from jupyter_client.manager import AsyncKernelManager
from pydantic import BaseModel

app = FastAPI()

class CodeRequest(BaseModel):
    code: str

class ExecutionResult(BaseModel):
    output: str

@asynccontextmanager
async def kernel_client():
    """Gestiona el ciclo de vida del Jupyter Kernel"""
    km = AsyncKernelManager(kernel_name="python3")
    await km.start_kernel()
    kc = km.client()
    kc.start_channels()
    await kc.wait_for_ready()
    try:
        yield kc
    finally:
        kc.stop_channels()
        await km.shutdown_kernel()

async def execute_code(code: str, timeout: int = 30) -> str:
    """Ejecuta código y devuelve el resultado"""
    async with kernel_client() as kc:
        msg_id = kc.execute(code)
        try:
            while True:
                reply = await asyncio.wait_for(
                    kc.get_iopub_msg(),
                    timeout=timeout
                )
                if reply["parent_header"]["msg_id"] != msg_id:
                    continue
                msg_type = reply["msg_type"]
                if msg_type == "stream":
                    return reply["content"]["text"]
                elif msg_type == "error":
                    return f"Error: {reply['content']['evalue']}"
                elif msg_type == "status" and reply["content"]["execution_state"] == "idle":
                    break
        except asyncio.TimeoutError:
            return "Error: Execution timed out"
    return ""

@app.post("/execute", response_model=ExecutionResult)
async def execute(request: CodeRequest):
    """API de ejecución de código"""
    try:
        output = await execute_code(request.code)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
    return ExecutionResult(output=output)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

La lógica central: por cada petición, arranca un Jupyter Kernel independiente, ejecuta, devuelve resultado y destruye el kernel.

Paso 2: Dockerfile

FROM jupyter/base-notebook:latest

WORKDIR /app

COPY main.py /app/main.py
COPY requirements.txt /app/requirements.txt

RUN pip install --no-cache-dir -r requirements.txt

# Usuario no root (buena práctica de seguridad)
USER jovyan

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Fíjate en USER jovyan: ejecutar sin root limita el daño si hay escape.

Paso 3: despliegue en GKE (con gVisor)

En GKE, añade una línea al Pod:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: agent-sandbox
spec:
  template:
    spec:
      runtimeClassName: gvisor  # Clave: habilitar gVisor
      containers:
      - name: sandbox
        image: your-registry/agent-sandbox:latest
        ports:
        - containerPort: 8000
        resources:
          limits:
            memory: "512Mi"
            cpu: "500m"

Tu entorno de ejecución ya corre dentro del sandbox gVisor.

Paso 4: restricciones de seguridad

La configuración anterior no basta en producción. Añade al menos:

# Política de red: solo APIs necesarias
# Sistema de archivos de solo lectura
securityContext:
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false

# Timeout de ejecución
# Ya definido en FastAPI con el parámetro timeout

Avanzado: despliegue en clúster Kubernetes

Si el agente escala, un solo contenedor no alcanza. Entra el controlador Agent Sandbox de Kubernetes.

Google open sourceó en 2025 Agent Sandbox con API declarativa de gestión.

Conceptos del CRD Sandbox

Recursos personalizados:

  • Sandbox: instancia con identidad estable, almacenamiento persistente y ciclo de vida
  • SandboxTemplate: plantilla con configuración estándar
  • SandboxClaim: solicitud bajo demanda de instancias

Ejemplo simple:

apiVersion: sandbox.k8s.io/v1alpha1
kind: Sandbox
metadata:
  name: my-agent-sandbox
spec:
  template:
    spec:
      runtimeClassName: gvisor
      containers:
      - name: executor
        image: python:3.11-slim
        command: ["sleep", "infinity"]
      # Almacenamiento persistente
      volumes:
      - name: workspace
        emptyDir: {}
      # Límites de recursos
      resources:
        limits:
          memory: "1Gi"
          cpu: "1"

Gestión del ciclo de vida

Agent Sandbox permite pausar y reanudar:

# Pausar sandbox (libera CPU y la mayor parte de memoria)
kubectl patch sandbox my-agent-sandbox --type=merge -p '{"spec":{"paused":true}}'

# Reanudar sandbox
kubectl patch sandbox my-agent-sandbox --type=merge -p '{"spec":{"paused":false}}'

Útil para agentes con ejecución intermitente: pausado casi sin recursos; reanudación en segundos.

Pool de precalentamiento

Para reducir latencia de arranque, Agent Sandbox soporta pools: sandboxes en pausa listos para activar.

Eso baja el «cold start» de segundos a milisegundos.

Servicios gestionados

Si no quieres operar infraestructura, los servicios gestionados ayudan. Opciones principales:

E2B: open source + cloud

E2B es sandbox de código para agentes de IA. Dos modalidades:

  • E2B Cloud: servicio gestionado, pago por uso
  • E2B on AWS: despliega la versión open source en tu cuenta AWS

Debajo usa Firecracker. SDK conciso:

from e2b import Sandbox

# Crear sandbox
sandbox = Sandbox()

# Ejecutar código
result = sandbox.run_code("print('Hello, World!')")

# Cerrar sandbox
sandbox.close()

E2B on AWS encaja en empresas con requisitos de soberanía de datos: todo en tu cuenta.

AWS Bedrock AgentCore

AWS lanzó en 2025 Bedrock AgentCore para ejecución de código y operación de navegador en agentes de IA.

Code Interpreter ofrece runtimes Python/JavaScript/TypeScript en microVM independiente por sesión, hasta 5 GB por archivo.

Browser Tool permite abrir páginas, rellenar formularios y hacer clic. Ideal para scraping y SaaS.

Facturación por vCPU y memoria usados, no por tiempo de instancia encendida: al terminar la ejecución, se liberan recursos.

Recomendaciones de selección

EscenarioRecomendación
Validación rápida, apps pequeñasE2B Cloud
Empresa, datos localesE2B on AWS o Bedrock AgentCore
Ecosistema AWS profundoBedrock AgentCore
Automatización de navegadorBedrock AgentCore Browser Tool
Control total y capacidad de opsKubernetes propio + Agent Sandbox

Conclusión

En resumen: la seguridad no es opcional; es infraestructura del agente de IA.

En selección técnica:

  • Equipos pequeños y validación rápida: Docker o gVisor
  • Apps empresariales y alta seguridad: Firecracker o servicio gestionado
  • Si ya usas Kubernetes: controlador Agent Sandbox

Sea cual sea la opción, empieza en local. Un FastAPI mínimo con Docker, luego refuerzo y producción.

Recuerda: cuanto antes añadas el sandbox, mejor. Esperar a un incidente sale mucho más caro.

Construir entorno sandbox para AI Agent

Montar un entorno seguro de ejecución de código de IA desde cero

⏱️ Estimated time: 60 min

  1. 1

    Step 1: Crear servicio FastAPI

    Escribe main.py con endpoint de ejecución:
    • AsyncKernelManager para Jupyter Kernel • Timeout de ejecución (30 s por defecto) • Devuelve resultado o error
  2. 2

    Step 2: Escribir Dockerfile

    Basado en jupyter/base-notebook:
    • Instalar FastAPI y uvicorn • Usuario no root (jovyan) • Exponer puerto 8000
  3. 3

    Step 3: Desplegar en Kubernetes

    Pod con gVisor:
    • runtimeClassName: gvisor • Límites de CPU/memoria • Contexto de seguridad (filesystem solo lectura)
  4. 4

    Step 4: Verificar aislamiento

    Prueba límites:
    • Acceso al host (debe fallar) • Código intensivo (debe limitarse) • Aislamiento de red

FAQ

¿Diferencia entre Docker y gVisor?
Docker comparte kernel con el host; una vulnerabilidad puede permitir escape. gVisor implementa un kernel falso (Sentry) en espacio de usuario, intercepta syscalls y solo permite operaciones seguras.
¿Cuándo usar Firecracker en lugar de gVisor?
Cuando la seguridad es crítica:
• Aislamiento hardware (finanzas, salud) • Cumplimiento estricto • Código de terceros no confiable
gVisor tiene ~10-20% de overhead; sirve para la mayoría de producción.
¿E2B o AWS Bedrock AgentCore?
E2B para validación rápida y control open source: • Apps pequeñas: E2B Cloud • Datos locales: E2B on AWS
Bedrock AgentCore si ya usas AWS: • Integración más simple • Automatización de navegador: Browser Tool
¿El sandbox afecta el rendimiento?
Sí: Docker casi sin pérdida, gVisor ~10-20%, Firecracker ~15-30%. Para análisis de datos y scripts de agents suele ser aceptable.
¿Sandbox rápido en local?
Lo más simple: contenedor Docker con gVisor. En GKE añade runtimeClassName: gvisor. En local puro, Docker con límites de recursos y permisos basta.

9 min de lectura · Publicado el: 23 mar 2026 · Actualizado el: 21 ago 2026

Comentarios

Inicia sesión con GitHub para dejar un comentario

Easton BlogEaston Blog