Aislamiento
El runtime puede envolver las invocaciones de herramientas en un sandbox a nivel de sistema operativo que restringe el acceso al sistema de archivos al workspace y elimina el acceso a los secrets del proceso padre. Esto es distinto del sistema de autonomía y de la lista de permitidos de comandos: estas son capas de política que deciden si una herramienta puede ejecutarse; el sandbox es una capa de mecanismo que confina lo que una herramienta en ejecución puede alcanzar si efectivamente se ejecuta.
La configuración del sandbox se encuentra en un perfil de riesgo. Cada agente apunta a un perfil de riesgo mediante agents.<alias>.risk_profile; el sandbox enable/backend del agente se lee de ese perfil.
Proveedores de modelos de CLI (por ejemplo grok_cli): la CLI externa queda fuera del flujo nativo de aprobación de herramientas de ZeroClaw. El aislamiento mediante sandbox del perfil de riesgo anterior no la confina. Por lo tanto, el proveedor ACP grok_cli inyecta --sandbox strict, --permission-mode dontAsk y un conjunto vacío de herramientas integradas de forma predeterminada, y rechaza las solicitudes de permisos de ACP (seleccionando reject_once cuando la CLI lo ofrece; de lo contrario, cancela la solicitud). En cambio, las opciones explícitas de omisión del alias extra_args seleccionan la opción allow_once de la solicitud; esto no deshabilita el sandbox activo del sistema operativo de Grok ni anula sus reglas de denegación. Los demás modos de permiso siguen funcionando con denegación por defecto. Consulta Catálogo → Grok Build CLI.
sandbox_enabled = false (o sandbox_backend = "none") deshabilita el envoltorio adicional de sandbox a nivel del sistema operativo del perfil. En el entorno de ejecución nativo, las herramientas quedan sin un sandbox a nivel del sistema operativo. Con [runtime] kind = "docker", el entorno de ejecución de Docker sigue siendo el límite del contenedor y se informa como docker-runtime; estas opciones impiden que un segundo contenedor de sandbox envuelva el docker run propio del entorno de ejecución. Consulta el Ejemplo mínimo funcional canónico para ver cómo se integra un perfil de riesgo en el resto de la configuración.
Detección automática
sandbox_backend = "auto" selecciona el mejor backend disponible al iniciar:
| Plataforma | Orden preferido |
|---|---|
| Linux | Landlock (kernel 5.13+) → Bubblewrap → Firejail → Docker → ninguno |
| macOS | Seatbelt (sandbox-exec, nativo) → Docker → ninguno |
| Windows | AppContainer (experimental) → Docker → ninguno |
| Cualquiera | Docker (si el daemon es accesible) → ninguno |
Para forzar un backend específico, asigna a sandbox_backend uno de los valores literales enumerados anteriormente.
Lo que el sandbox confina
Acceso a archivos
- Acceso de lectura: restringido al espacio de trabajo,
/usr,/lib,/etc(solo lectura) y las rutas adicionales listadas explícitamente. - Acceso de escritura: restringido al espacio de trabajo y a
/tmp. - Rutas prohibidas: reglas de prefijo de componentes absolutos de
[risk_profiles.<alias>].forbidden_paths. Los prefijos de autorización y denegación en conflicto utilizan la precedencia de la coincidencia más específica, y la denegación prevalece en caso de empate; consulta Reglas de rutas de autonomía.
Red
De forma predeterminada, las herramientas en entorno aislado tienen salida de red completa pero sin escucha entrante. Advertencias por backend:
- Landlock no controla la red, es solo para el sistema de archivos.
- Bubblewrap y Firejail pueden bloquear la red cuando se configuran.
- El modo de red del contenedor Docker sigue
[runtime.docker].networkcuando[runtime].kind = "docker".
Las restricciones de red específicas de cada herramienta (browser, HTTP, web_fetch) se definen en los bloques de configuración propios de esas herramientas ([browser].allowed_domains, [http_request].allowed_domains, [web_fetch].allowed_domains).
Para http_request, los destinos privados/locales permanecen bloqueados de forma predeterminada. Use [http_request].allowed_private_hosts para permitir solo hosts privados/locales específicos como localhost o 10.0.0.1 mientras mantiene [http_request].allowed_domains no vacío; allowed_domains = [] sigue deshabilitando las solicitudes. La configuración existente [http_request].allow_private_hosts = true sigue siendo una opción de compatibilidad más amplia.
Entorno
El sandbox solo deja pasar las variables de entorno indicadas en [risk_profiles.<alias>].shell_env_passthrough. Los secretos heredados no llegan a las herramientas en sandbox a menos que se pasen explícitamente.
Límites de procesos
Los tiempos de espera de tiempo real por herramienta residen en el bloque de configuración propio de la herramienta ([shell_tool].timeout_secs, etc.). Los límites específicos de Docker (memoria, CPU) residen en [runtime.docker] cuando el tipo de runtime del agente está configurado como docker:
Binario de shell
De forma predeterminada, el runtime nativo invoca comandos mediante /bin/sh. Establece [runtime].shell para usar una shell diferente:
[runtime]
shell = "bash" # resuelve mediante PATH, o usa una ruta absoluta
En Unix, los shells compatibles con POSIX se invocan como <shell> -c "<command>". powershell/pwsh seleccionan la sintaxis y la directiva de PowerShell en todos los hosts de escritorio compatibles y se ejecutan como <interpreter> -NoProfile -NonInteractive -Command <command>, de modo que los scripts de perfil no puedan redefinir comandos a espaldas de la directiva y los avisos no puedan bloquear la ejecución. El valor debe ser un nombre de comando simple que se encuentre en PATH (por ejemplo, "bash" o "pwsh") o una ruta absoluta a un ejecutable (por ejemplo, "/bin/bash"); se rechazan las rutas relativas con separadores (por ejemplo, "./sh", "bin/sh"). Se valida cuando se inicia el entorno de ejecución, por lo que un shell vacío, ausente, no ejecutable o con formato incorrecto falla inmediatamente con un error claro en lugar de interrumpir el primer comando. Su valor predeterminado es "sh" si no se establece.
En Windows, el valor selecciona la familia de intérpretes según el nombre de su archivo:
[runtime]
shell = "pwsh" # PowerShell 7+ -> pwsh -NoProfile -NonInteractive -Command <cmd>
# shell = "powershell" # Windows PowerShell 5.x
# shell = "cmd" # o dejar sin definir -> cmd.exe /C "<cmd>" (predeterminado)
powershell y pwsh (como nombres independientes resueltos mediante PATH o como una ruta absoluta, como "C:\\Program Files\\PowerShell\\7\\pwsh.exe") se ejecutan mediante PowerShell; cualquier otro valor (incluidos el valor predeterminado sh y un cmd explícito) se ejecuta mediante cmd.exe /C, de acuerdo con el comportamiento histórico. Solo se rechaza un valor vacío o compuesto únicamente por espacios en blanco; el intérprete se localiza en el momento de iniciar el proceso.
La herramienta de shell, las herramientas de habilidades respaldadas por shell y las tareas de shell de cron/programadas usan esta selección del tiempo de ejecución. El tiempo de ejecución también comunica el dialecto del shell a la política de seguridad, por lo que la política valida el mismo lenguaje que ejecutará el comando.
Al modelo se le comunica la misma selección del entorno de ejecución. La línea ## Runtime del prompt del sistema contiene un campo Shell: que indica el intérprete configurado (bash, zsh, pwsh, powershell, cmd) y, cuando una herramienta registrada acepta un comando escrito por el modelo (shell, cron_add, cron_update, schedule), una sección ## Shell enumera las formas de comando que acepta ese dialecto, de modo que el modelo escribe Get-ChildItem con PowerShell y dir /a con cmd.exe, en lugar de adivinarlo a partir del nombre del sistema operativo. Ambos proceden del mismo adaptador que construye el comando, por lo que el shell indicado no puede diferir del que se ejecuta. Los entornos de ejecución sin acceso al shell (como WASM) omiten ambos. Las recomendaciones de eliminación de la sección de seguridad también siguen el dialecto: solo se sugiere trash donde existe.
La política de PowerShell acepta una gramática acotada: invocaciones de comandos simples, argumentos sin comillas o entre comillas y canalizaciones. Las lecturas de variables simples, como $PSHOME y $PSVersionTable.PSVersion, se limitan a un comando independiente Write-Output/echo, de modo que no puedan ocultar rutas del sistema de archivos a los comandos posteriores. Las expresiones y las formas alternativas de invocación, incluidas las subexpresiones, los paréntesis, los bloques de script, los literales de tipo/las llamadas a métodos estáticos, los operadores de llamada, la redirección, los separadores de instrucciones, las secuencias de escape con acento grave, las variables con ámbito como $env:NAME, las rutas de proveedores de PowerShell, la ejecución directa de scripts y los intérpretes de comandos anidados, se clasifican como de alto riesgo. Los nombres de comandos exclusivos de PowerShell no se añaden a la lista de permitidos predeterminada entre dialectos; añade los cmdlets que necesites a allowed_commands, o habilita "*" con la aprobación correspondiente y la configuración de alto riesgo. Los cmdlets de mutación conocidos siguen los controles de aprobación de riesgo medio/alto; los comandos independientes desconocidos y los cmdlets Verb-Noun son de alto riesgo de forma predeterminada.
Los trabajos de shell de Cron heredan el límite global del entorno de ejecución tanto durante la validación como durante la ejecución. Los trabajos nativos usan el shell nativo configurado, mientras que los trabajos de Docker se ejecutan mediante la imagen, el montaje, la red y la configuración de CPU, memoria y raíz de solo lectura configurados. Una fila de cron almacena el comando, no una copia del entorno de ejecución ni del dialecto. Por lo tanto, después de que una recarga del demonio vuelva a crear el planificador y el registro de herramientas, los trabajos existentes usan la configuración [runtime] recién cargada en su siguiente ejecución. Las ejecuciones programadas de cron se vuelven a validar y nunca se preautorizan.
Solo se aplica al tipo de tiempo de ejecución nativo. Docker usa el shell de su contenedor, y Android (siempre /system/bin/sh) ignora la configuración y no la valida.
Notas por backend
Landlock
La ruta nativa de Linux. Sin configuración, aplicada por el kernel, con una sobrecarga muy baja. Requiere el kernel 5.13 o posterior.
Limitaciones:
- Sin confinamiento de red: Landlock solo controla el acceso al sistema de archivos.
forbidden_pathsse aplica mediante reglas basadas en rutas, no en inodos, por lo que un enlace simbólico ingenioso a veces puede eludirlo (resolvemos los enlaces antes de pasarlos a Landlock para mitigar esto).
Bubblewrap (bwrap)
Sandbox basado en espacios de nombres de usuario de Flatpak. Confina el sistema de archivos y puede bloquear la red. Requiere tener bubblewrap instalado.
Debian/Ubuntu
sudo apt install bubblewrap
Arch
sudo pacman -S bubblewrap
Fedora
sudo dnf install bubblewrap
Firejail
Sandbox basado en SUID. Más antiguo pero ampliamente disponible.
sh
sudo apt install firejail
El perfil predeterminado de Firejail es bastante permisivo; ZeroClaw aplica un perfil personalizado. Pasa argumentos adicionales con firejail_args en el perfil de riesgo.
Docker
Funciona en cualquier lugar donde funcione Docker. El tipo de runtime de Docker ([runtime] kind = "docker") ejecuta cada invocación de shell en un contenedor efímero; consulta el bloque [runtime.docker] anterior para conocer los controles de imagen y recursos.
sh
docker build -t zeroclaw-sandbox:local dev/sandbox/ # compilar la imagen del kit de herramientas integrado
Ventajas: fuerte aislamiento, funciona en cualquier sistema operativo. Desventajas: costo de inicio del contenedor por invocación (100–500 ms). Ideal para implementaciones en producción donde la sobrecarga es aceptable.
Cinturón de seguridad (macOS)
Sandbox nativo de macOS (sandbox-exec). Los perfiles son SBPL: ZeroClaw incluye uno para ejecuciones de herramientas. Funciona en macOS 10.11+.
Limitación: algunas herramientas de CLI (versiones antiguas de git, algunos binarios enlazados con Homebrew) no cooperan con las reglas de acceso a archivos de Seatbelt. Si ve errores de “Operation not permitted” en las llamadas al shell del agente en macOS, la herramienta necesita un acceso más amplio al sistema de archivos: considere cambiar a Docker.
none
Sin sandboxing. Las herramientas se ejecutan con todos los privilegios del usuario del servicio ZeroClaw. Esto es lo que habilita el modo YOLO. Ruidoso, obvio e intencional.
Solución de problemas
- “Sandbox backend unavailable” al iniciar: verifica
zeroclaw service statusy el journal; la detección automática registra qué backends intentó. - Las herramientas funcionan en desarrollo, pero fallan en el servicio: el usuario del servicio a menudo difiere del usuario de la CLI. Verifique que ambos tengan los permisos relacionados con el sandbox que sean necesarios (Landlock: ninguno; Bubblewrap: userns habilitado; Docker: usuario del servicio en el grupo
docker). - Invocaciones lentas de herramientas en el runtime de Docker: la primera invocación descarga la imagen, las siguientes son rápidas. Descargue previamente con
docker pull <image>.
Referencia de código
- Detección:
crates/zeroclaw-runtime/src/security/detect.rs - Backends:
crates/zeroclaw-runtime/src/security/sandbox/(un archivo por backend) - Esquema:
RiskProfileConfigyDockerRuntimeConfigencrates/zeroclaw-config/src/schema.rs