Volver al blog
LaravelPHPIA

BashBox lleva Bash aislado a los agentes de Laravel

Una forma de dejar que un agente analice archivos y ejecute scripts sin abrir un shell real en el host.

Por Isma4 min de lectura

Dar contexto sin entregar el servidor

Cuando un agente necesita revisar un log, filtrar un JSON o inspeccionar una configuración, darle acceso directo a bash es una decisión difícil de justificar. El problema no es solo que pueda borrar archivos: también puede leer secretos, alcanzar servicios internos o consumir recursos sin control. En un homelab, donde muchas piezas conviven en la misma máquina, el radio de impacto importa más de lo que parece.

BashBox plantea otra vía: interpreta scripts con sintaxis de Bash desde PHP, sin invocar un shell del sistema. Los comandos trabajan sobre un sistema de archivos virtual por defecto y la ejecución puede tener límites de comandos, bucles, salida, memoria de archivos y más controles. Para un agente de Laravel, eso permite ofrecer una herramienta útil sin darle una terminal del host. (github.com)

Un caso práctico para Laravel

Yo lo veo especialmente claro en tareas de diagnóstico acotadas. Una aplicación puede cargar un fragmento de log o una copia de una configuración en el sistema de archivos inicial de BashBox, pedir al agente que haga una consulta concreta y devolver solo la salida resultante. No hace falta crear un contenedor efímero para cada filtro con grep, sort, uniq o jq, siempre que esos comandos estén dentro de los que implementa la librería.

La integración con Laravel no requiere que BashBox conozca el framework. Basta con envolverlo en un servicio propio, construir el entorno con los archivos que el agente puede ver y ejecutar el script generado bajo límites conservadores. El punto importante es que el modelo recibe una capacidad concreta, no una puerta abierta al sistema.

use BashBox\Bash;
use BashBox\BashOptions;
use BashBox\Limits;
 
$bash = new Bash(new BashOptions(
    initialFiles: [
        '/home/user/logs/app.log' => $logContents,
    ],
    limits: new Limits(
        maxCommandCount: 100,
        maxLoopIterations: 500,
        maxOutputSize: 1024 * 1024,
        maxCallDepth: 10,
    ),
));
 
$result = $bash->exec(
    'grep "ERROR" /home/user/logs/app.log | sort | uniq -c | sort -rn'
);
 
$output = $result->stdout;

Este enfoque también encaja cuando el agente debe trabajar con una instantánea, no con el estado vivo de la infraestructura. Por ejemplo, puedo entregarle un docker-compose.yml, una exportación de inventario o logs ya saneados, y pedirle que detecte incoherencias. Si necesita datos nuevos, prefiero que Laravel se los proporcione mediante una acción específica y auditable, en lugar de abrirle red o acceso al disco.

Límites que conviene imponer desde el principio

La librería permite configurar límites al crear Bash mediante BashOptions y Limits. Entre ellos están el número máximo de comandos, las iteraciones por bucle, el tamaño total de salida y la cuota del sistema de archivos. Si se supera una cuota de disco, la escritura falla como lo haría un disco lleno; los demás límites de ejecución producen una excepción específica. (github.com)

Yo empezaría con límites bajos y los ampliaría solo cuando haya una necesidad real. Un agente no necesita procesar cien megabytes de salida para resumir errores recientes, y una respuesta enorme tampoco es buena entrada para el siguiente paso del modelo. Además, limitar desde la herramienta simplifica la observabilidad: es fácil registrar el script, sus archivos de entrada, la salida y el motivo de un fallo.

La letra pequeña

BashBox no ejecuta binarios del host, pero tampoco es una sustitución completa de una instalación real de Bash ni de todas las herramientas GNU. La documentación deja claro que algunos comandos orientados a agentes, como jq, rg o diff, implementan subconjuntos y que las opciones o sintaxis no soportadas fallan de forma explícita. Antes de convertir un script existente en una herramienta para un agente, yo probaría exactamente las expresiones y opciones que quiero admitir. (github.com)

Tampoco conviene confundir aislamiento por defecto con seguridad automática al cambiar la configuración. InMemoryFs no toca el disco, pero ReadWriteFs sí lee y escribe dentro de una raíz configurada, y los comandos personalizados son código PHP que escribimos nosotros. Si habilito red, curl pasa a estar disponible y debo definir prefijos de URL, métodos y protección frente a rangos privados; abrir Internet sin restricciones tiene una opción que el propio proyecto marca como peligrosa. (github.com)

Para automatizaciones de homelab, mi regla sería sencilla: datos de entrada mínimos, sistema de archivos en memoria siempre que sea posible, red desactivada y comandos personalizados muy revisados. BashBox no reemplaza a un contenedor cuando necesito ejecutar herramientas reales, reproducir un entorno Linux o aislar código que no controla la librería. Pero para análisis y transformaciones limitadas que un agente puede expresar con comandos conocidos, reduce bastante la exposición sin añadir una capa de infraestructura por cada ejecución.


Fuente: Laravel News Documentación oficial: BashBox

Newsletter

Lo que aprendo programando con IA, cada dos semanas en tu correo.

Cifras reales, errores incluidos. Sin spam y te das de baja con un clic.

Sin spam y te das de baja con un clic. Uso tu correo solo para enviarte esto y la newsletter. Más en la política de privacidad.