Ejecución de código en entorno aislado

El crate adk-sandbox proporciona ejecución de código aislada para agentes ADK, con dos niveles de aislamiento:

  1. Aislamiento de procesos — procesos secundarios con aislamiento del entorno y aplicación de tiempos de espera
  2. Perfiles de sandbox a nivel del sistema operativo — restricciones a nivel del kernel sobre el sistema de archivos, la red y la creación de procesos

Motores

BackendNivel de aislamientoLenguajesIndicador de funcionalidad
ProcessBackendEntorno + tiempo de esperaRust, Python, JS, TS, Comandoprocess (predeterminado)
ProcessBackend + sandboxNivel del kernelIgual que arribaprocess + sandbox-native
WasmBackendCompleto (memoria, sistema de archivos, red)solo WASMwasm

¿Qué aislamiento estás obteniendo?

ProcessBackend::isolation() lo informa, por lo que esto no es algo que deba inferirse del nombre del crate:

ResultadoSignificado
IsolationClass::SubprocessOnlyUn proceso hijo con el entorno borrado, un tiempo de espera y su propio grupo de procesos. El sistema operativo no aplica ninguna restricción adicional: el código puede leer el sistema de archivos del host y acceder a la red. Esto es lo que proporciona ProcessBackend::default().
IsolationClass::OsEnforcedSe adjuntan un aplicador y una política, por lo que el sistema operativo restringe el proceso hijo.

Dos aspectos del backend de procesos que conviene conocer:

  • Los programas se resuelven antes de borrar el entorno. Un python3, node o rustc sin ruta se busca en el PATH de quien realiza la llamada y se pasa al proceso hijo como una ruta absoluta. Esto significa que el proceso hijo no necesita su propio PATH para iniciarse; anteriormente, quien realizaba la llamada tenía que incluir PATH en ExecRequest::env, lo que también permitía al código ejecutado generar cualquier otra cosa desde allí.
  • La compilación pasa por el mismo límite que la ejecución. El código fuente de Rust solía compilarse mediante un comando creado fuera de la ruta compartida, por lo que la compilación no tenía un envoltorio de cumplimiento, ni tiempo de espera, ni grupo de procesos. Esto es importante porque la compilación no es inerte: include_str! lee archivos y las macros procedurales ejecutan código arbitrario antes de que exista el binario generado. La fase de compilación recibe una lista de herramientas permitidas específica de la plataforma; en Windows, esto incluye las rutas de MSVC y Windows SDK, detectadas a partir de la cadena de herramientas instalada cuando quien realiza la llamada no se encuentra ya en un shell de Developer. La compilación utiliza el enlazador rust-lld de la cadena de herramientas de Rust, por lo que no se puede seleccionar un link.exe no relacionado que aparezca antes en PATH. Un mecanismo de cumplimiento del sistema operativo es lo que restringe esa fase.

Prioridad del entorno

SandboxPolicy::env proporciona valores predeterminados para cada ejecución y ExecRequest::env los anula por llamada. Las variables de la política se ignoraban por completo anteriormente.

Perfiles de aislamiento del sistema operativo

El cumplimiento del aislamiento a nivel del sistema operativo restringe los procesos hijos a nivel del kernel. Esto va más allá del aislamiento del entorno: el propio sistema operativo bloquea el acceso no autorizado al sistema de archivos, las conexiones de red y la creación de procesos.

Compatibilidad con plataformas

PlataformaAplicadorCómo funciona
macOSSeatbelt (sandbox-exec)Reglas a nivel de llamadas al sistema: «permitir de forma predeterminada, denegar lo peligroso» — deniega escrituras, red y bifurcaciones; las lecturas no están restringidas
Linuxbubblewrap (bwrap)Aislamiento del espacio de nombres del sistema de archivos (montajes en lista blanca)
WindowsAppContainerNo implementado — el enforcer informa que no está disponible

Inicio rápido

use adk_sandbox::{
    ProcessBackend, ProcessConfig, SandboxBackend,
    SandboxPolicyBuilder, get_enforcer,
};

// 1. Define what the sandboxed process can do
let policy = SandboxPolicyBuilder::new()
    .allow_read("/usr")           // Read system libraries
    .allow_read_write("/tmp/work") // Write to work directory
    .allow_process_spawn()         // Python needs to exec
    // Network is denied by default
    .env("PATH", "/usr/bin:/usr/local/bin")
    .build();

// 2. Get the platform-appropriate enforcer
let enforcer = get_enforcer()?;

// 3. Create a sandboxed backend
let backend = ProcessBackend::with_sandbox(
    ProcessConfig::default(),
    enforcer,
    policy,
);

// 4. Execute code — network is blocked, writes restricted
let result = backend.execute(request).await?;

Indicadores de funciones

[dependencies]
# Auto-detect platform enforcer
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-native"] }

# Or pick a specific platform
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-macos"] }
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-linux"] }

SandboxPolicy

La política define lo que un proceso aislado puede hacer:

CampoPredeterminadoDescripción
allowed_paths[] (denegar todo)Rutas del sistema de archivos con acceso de solo lectura o de lectura y escritura
allow_networkfalseSi se permite el acceso a la red
allow_process_spawnfalseSi se permite la creación de procesos secundarios
env{}Variables de entorno para el proceso aislado

Diferencias entre plataformas

macOS (Seatbelt): Utiliza «permitir de forma predeterminada, denegar lo peligroso»: comienza con acceso total y luego bloquea la red, las escrituras de archivos y la creación de procesos. Un enfoque de lista blanca pura no funciona porque Python necesita decenas de categorías de llamadas al sistema específicas de macOS durante el inicio.

Linux (bubblewrap): Utiliza una lista blanca basada en espacios de nombres: de forma predeterminada no existe nada; solo se monta lo necesario. Instala con apt install bubblewrap o dnf install bubblewrap.

Windows (AppContainer): No está implementado. El diseño se basa en ACL con tokens: un SID restringido sin acceso de forma predeterminada y, posteriormente, ACL otorgadas para rutas específicas; pero faltan la creación de contenedores, las ACL, las capacidades y la limpieza de objetos de trabajo, por lo que probe() devuelve EnforcerUnavailable. Ejecuta sin un aplicador de restricciones en Windows, o utiliza macOS o Linux, donde la aplicación de restricciones es real.

Ejemplo

Consulta examples/sandbox_agent/ para ver un ejemplo completo basado en LLM-agent que ejecuta código Python en un entorno aislado, con el acceso a la red bloqueado por el kernel del sistema operativo.

Ejecución de código en entorno aislado - Documentación ADK-Rust | ADK-Rust