«Ejecútalo en una sandbox» suena a una sola instrucción. En la práctica hay cuatro fronteras habituales a las que la gente se refiere con eso, y detienen cosas muy distintas. Elegir la equivocada te deja expuesto o hace que cada ejecución sea más lenta y cara de lo necesario.
Esta comparación da por hecho que el código es realmente no fiable: escrito por un modelo de lenguaje, enviado por un usuario o llegado en un pull request de alguien a quien no conoces. El código que escribiste tú tiene otras necesidades.
Qué puede salir mal
Antes de comparar fronteras, conviene nombrar para qué sirven. El código no fiable puede:
- Leer lo que no debe: variables de entorno, claves SSH, archivos de tu directorio personal, endpoints de metadatos de la nube.
- Agotar recursos: entrar en un bucle infinito, hacer fork hasta bloquear la máquina, llenar el disco.
- Abusar de la red: escanear otros hosts, enviar spam, minar criptomonedas, llamar a tus servicios internos.
- Persistir: instalar una tarea cron o un servicio que sobreviva a la tarea.
- Escapar: usar un fallo de la capa inferior para ejecutar código en el propio host.
Cada nivel de los siguientes cubre parte de esto, no todo.
Nivel 1: un proceso
La sandbox más sencilla es un proceso hijo: subprocess.run con un tiempo límite, quizá con un usuario propio, límites de recursos y un filtro seccomp si eres minucioso.
Detiene: la ejecución sin fin (el tiempo límite), parte del agotamiento de recursos (límites), algunas llamadas al sistema peligrosas (seccomp). No detiene: la lectura de todo lo que pueda leer ese usuario, el acceso a la red, la persistencia a través de cualquier cosa en la que el usuario pueda escribir y cualquier fallo del kernel. Fallo típico: el código lee un archivo que habías olvidado que era legible, o un intérprete «restringido» resulta tener una puerta trasera. La historia está llena de sandboxes dentro del lenguaje que no aguantaron.
El arranque es prácticamente inmediato. Sirve para tu propio código; no es una frontera para el de otros.
Nivel 2: un contenedor
Los namespaces dan al código su propia vista de archivos, procesos y red; los cgroups limitan CPU y memoria; las capabilities retiradas y seccomp reducen lo que puede pedirle al kernel.
Detiene: la lectura de los archivos del host (salvo que estén montados), ver otros procesos, el uso ilimitado de recursos y buena parte del problema de persistencia si el contenedor se desecha. No detiene: un fallo en el kernel compartido del host. Todos los contenedores de la máquina hablan con el mismo kernel, así que una vulnerabilidad del kernel alcanzable es una salida. Fallo típico: la configuración más que exploits exóticos. Un contenedor privilegiado, el socket del runtime de contenedores montado dentro, la red del host activada «solo para depurar». Cada una elimina la frontera sin hacer ruido.
El arranque se mide en milisegundos. Existen variantes reforzadas, entre ellas kernels en espacio de usuario que interceptan las llamadas al sistema antes de que lleguen al host, a costa de velocidad y compatibilidad. Para código de gente de confianza, un contenedor bien configurado es una opción sensata por defecto.
Nivel 3: una microVM
Una microVM ejecuta su propio kernel bajo un hipervisor, como una VM completa, pero sin casi nada de hardware emulado. El ejemplo más conocido es Firecracker.
Detiene: todo lo que detiene un contenedor, más el problema del kernel compartido. Para alcanzar el host, el código tiene que romper el hipervisor o uno de un puñado de dispositivos virtuales, una superficie mucho menor que la interfaz de llamadas al sistema de un kernel. No detiene: el mal uso de lo que le entregues. El tráfico saliente abierto sigue pudiendo abusarse; los secretos inyectados pueden seguir filtrándose. Fallo típico: la política, no el aislamiento. Alguien pasa un token de producción «para que funcionen los tests» o deja el tráfico saliente sin restricciones donde no hace falta.
El arranque va de una fracción de segundo a un segundo aproximadamente, con unos pocos megabytes de sobrecarga. Es lo bastante rápido para crear una por tarea y eliminarla después, lo que además resuelve la persistencia: no queda nada a lo que volver.
Nivel 4: una máquina virtual completa
Una VM normal, o un VPS, tiene el mismo tipo de frontera que una microVM: virtualización por hardware y un hipervisor. La diferencia está en todo lo demás: un modelo de dispositivos completo, un sistema operativo entero, una IP pública si la quieres y un ciclo de vida de días o meses.
Detiene: las mismas clases de problemas que una microVM, con una superficie de ataque algo mayor porque se emula más hardware. No detiene: el abuso de su propia identidad de red. Una VM con IP pública que ejecuta código abusivo hace que su IP acabe en listas de bloqueo, lo que importa si esa misma IP envía tu correo. (Si ya ha pasado, consulta qué hacer cuando tu IP está en una lista de bloqueo.) Fallo típico: vive demasiado. Una VM creada para un experimento acumula credenciales y estado, y poco a poco se convierte en la máquina de confianza que debía proteger.
El arranque tarda de decenas de segundos a minutos, y la facturación suele ser mensual. Es la forma adecuada para un servicio duradero que necesita puertos entrantes, y la equivocada para ejecutar código durante 20 segundos.
La comparación
| Proceso | Contenedor | MicroVM | VM completa | |
|---|---|---|---|---|
| Kernel propio | no | no | sí | sí |
| Frontera principal | permisos de usuario | namespaces + kernel compartido | hipervisor, modelo de dispositivos diminuto | hipervisor, modelo de dispositivos completo |
| Arranque | ~0 | ms | ~0.1–1 s | 10 s – minutos |
| Sobrecarga | ninguna | pequeña | unos pocos MiB | decenas–cientos de MiB |
| Desechar por tarea | fácil | fácil | fácil | lento, caro |
| Puertos entrantes / IP pública | los del host | los del host | normalmente ninguno | sí |
Cómo elegir
- Código escrito por ti o tu equipo: basta con un proceso o un contenedor.
- CI para tus propias ramas: un contenedor en tu runner.
- Código de agentes, envíos de usuarios, pull requests externos: una microVM por tarea, eliminada después.
- Un servicio no fiable que debe aceptar conexiones o funcionar durante semanas: una VM aparte con su propia IP, lejos de todo lo que guarde tus credenciales o envíe tu correo.
Elijas lo que elijas, se aplican dos reglas encima: no metas dentro nada que no le darías al autor del código, y decide deliberadamente qué puede hacer la red.
Dónde encajan nuestros productos
Para el nivel 3 ofrecemos sandboxes de código: microVM de Firecracker que arrancan en un segundo aproximadamente, con internet saliente, sin puertos entrantes y facturación por segundo. Están pensadas precisamente para el tercer punto de arriba; la página de salvaguardas de MCP explica cómo limitar lo que un agente puede hacer con ellas. Para el nivel 4, un VPS como la tarifa AI agent te da una máquina entera al mes. Los ejemplos desarrollados en sandbox para agentes de IA muestran el patrón de microVM de principio a fin, y lo que los agentes de IA necesitan de verdad de la infraestructura trata el aislamiento como uno de varios requisitos.
Comentarios
Aún no hay comentarios. Sé el primero.