🛡️ sandbox-labs GitHub ↗

🧠 Qué es un sandbox#

Empieza aquí. Sin este documento, el resto del repositorio no se entiende.

El problema de partida#

Cuando ejecutas un programa en tu equipo, ese programa corre como tú. Tiene exactamente tus permisos: puede leer cualquier archivo que tú puedas leer, conectarse a donde quiera y ver todo lo que tienes abierto.

No hay término medio. O lo ejecutas con todo tu poder, o no lo ejecutas.

Y ejecutas código ajeno constantemente sin pensarlo:

flowchart LR
  P["📦 Programa ajeno"] --> H["🖥️ Tu equipo"]
  H --> A["📁 Tus archivos"]
  H --> B["🌐 Internet"]
  H --> C["🔑 ~/.ssh · ~/.aws"]
  H --> D["⚙️ Tus procesos"]
  H --> E["✉️ Tus tokens"]

La definición#

Un sandbox es un entorno que le entrega a un programa una porción declarada del sistema —unas carpetas, quizá algo de red, un techo de memoria y de CPU— para que haga trabajo real dentro de ella, y donde el resto del sistema no existe.

Las dos mitades importan, y la primera se olvida siempre:

da al programa lo que necesita para hacer su tarea de verdad —leer esta carpeta, escribir en esta otra, hablar con este servidor— y con eso funciona igual que fuera. Un sandbox donde no se puede hacer nada no sirve para nada.

Lo importante es cómo se hace cumplir la segunda mitad. No es un aviso de permisos que el programa pueda esquivar ni una promesa de buena conducta: si pide

intenta conectarse, no hay red que usar — no una red bloqueada: no hay pila de red.

flowchart LR
  subgraph J["🔒 El sandbox: la porción concedida"]
    P["📦 El mismo programa"]
    P --> W["📁 Su carpeta de trabajo"]
    P --> N["🌐 Los destinos permitidos"]
    P --> R["📊 Su memoria y su CPU"]
  end
  P -.->|no existe| B["🗄️ El resto del disco"]
  P -.->|no existe| C["🔑 Tus claves"]
  P -.->|no existe| D["⚙️ Tus procesos"]

Por eso la pregunta útil no es «¿está aislado?», que se responde sí o no y no sirve de nada. Es «¿qué porción del sistema le he dado, y qué hace con ella?»

La analogía#

Contratas a un cerrajero.

hay teléfono, y cuando se va compruebas qué tocó.


Qué se controla#

ControlQué decidesSin él
FilesystemQué ve: una carpeta de entrada y otra de salidaLee tus claves y escribe donde tú escribas
RedSi tiene internet, unos destinos concretos, o ningunoExfiltra lo que encuentre y descarga su segunda etapa
ProcesosSi ve tus otros programas o solo el suyoInspecciona y señaliza procesos ajenos
RecursosCuánta memoria, cuánto tiempo, cuántos procesosUna carga descontrolada tumba el equipo
PrivilegiosQué capabilities conservaPuede montar, trazar procesos o tocar la red del host
EntornoQué variables heredaUn token heredado convierte la ejecución en una filtración

Dónde se declara todo eso#

En un archivo de política, separado del código. Ni el programa negocia sus permisos, ni quien lo escribió decide sus límites.

{
  "filesystem": { "root": "ephemeral", "writable": ["/workspace/output"] },
  "network":    { "mode": "none" },
  "resources":  { "memoryMb": 512, "processes": 32 },
  "process":    { "capabilities": [], "allowedEnvironment": [] }
}

Léelo como una lista de decisiones tuyas. Lo que no aparece ahí no se monta, y lo que no se monta dentro no existe.

flowchart LR
  A["📄 política.json<br/>lo que se permite"] --> C["⚙️ sandboxctl"]
  B["📦 caso<br/>qué política usa"] --> C
  C --> D["🔒 controles del kernel<br/>namespaces · caps · límites"]
  D --> E["🟢 sandbox vivo<br/>y haces tareas dentro"]

Referencia campo a campo en POLICY_REFERENCE.md.


Cinco sandboxes que ya usas#

No es una técnica de laboratorio: la usas a diario sin llamarla así.

DóndeQué código ajeno ejecutaCon qué aísla
El navegadorEl JavaScript de cada web que abresnamespaces + seccomp · AppContainer
El móvilCada app instaladaUn UID por app + SELinux
ServerlessCódigo de miles de clientes en la misma máquinaFirecracker, una microVM por invocación
Los runners de CIEl código de cualquier pull requestVM efímera por job
Los intérpretes de IACódigo recién generado que nadie ha leídogVisor o microVM, sin red

Escaparse del sandbox de un navegador se paga por encima de los 200.000 dólares en las competiciones de seguridad. Si fuera fácil, no valdría tanto.


En qué se parece a una API o a un MCP, y en qué no#

Es la comparación más útil que se puede hacer, porque los tres controlan qué parte del sistema alcanza un programa. Pero el mecanismo es distinto, y esa diferencia decide cuál sirve en cada caso.

El malentendido más común, primero#

«Un sandbox recibe instrucciones como GET y POST, entonces es una API.»

No, y aclarar esto ordena todo lo demás. GET y POST son verbos de HTTP: el vocabulario con el que se habla con una API por la red. Un programa dentro de un sandbox no habla HTTP con el sandbox. Lo que hace son llamadas al sistemaopen, read, write, connect, execve—, que son las instrucciones que cualquier programa le da al sistema operativo, esté o no enjaulado.

Y el sandbox no las recibe: no hay nadie escuchando. Lo que hay es un kernel que, para ese proceso, responde que el fichero no está y que no hay red.

La imagen que lo resuelve: con una API tú estás fuera y pides. Con un sandbox tú estás dentro y el suelo decide.

La tabla#

Qué esDónde estás túSu vocabularioQuién decideSi el programa NO colabora
APIUn catálogo de operaciones que un servicio ofrece. Pides una y te respondeFuera, llamando a la puertaGET, POST, DELETE… o funciones de una bibliotecaEl servicio que la publicaNada la detiene: el programa conserva todo lo demás del sistema. La API solo acota lo que le pide a ese servicio
MCPUn protocolo que le declara a un modelo de IA qué herramientas tieneFuera, pidiendo herramientastools/list, tools/callEl servidor de herramientasIgual: el modelo no usa otras herramientas, pero el proceso que lo ejecuta mantiene sus permisos intactos
SandboxUn entorno de ejecución con una porción declarada del sistema dentroDentro. Es el suelo que pisasopen, read, connect, execve… (llamadas al sistema)El kernelPuede intentar lo que quiera y el kernel se lo niega. No depende de su buena voluntad

La diferencia que decide cuál usar#

Una API y un MCP son fronteras con las que el programa colabora. Funcionan porque el programa decide pedir las cosas por ahí.

Un sandbox funciona sobre un programa que no colabora: uno que llama directamente a open("/home/tú/.ssh/id_rsa") sin pasar por ninguna API. No hay nada que le impida hacer esa llamada; lo que hay es un kernel que responde que ese fichero no existe.

De ahí la regla práctica:

Si puedes confiar en que el código use solo tu API, no necesitas un sandbox. Si no puedes confiar en eso —porque el código es ajeno, generado o simplemente desconocido—, la API no te protege de nada.

Y se combinan, que es lo habitual#

No compiten, y hay un detalle que explica por qué se confunden tanto: un sandbox casi siempre se maneja con una API. En este repositorio, sandboxctl y el panel en 127.0.0.1:9093 levantan jaulas, las apagan y consultan su estado. Esa API gobierna el sandbox desde fuera; no es el sandbox, igual que el mando de una grúa no es la grúa.

Un agente de IA real usa los tres a la vez:

flowchart LR
  M["🤖 Modelo"] -->|"herramientas declaradas"| MCP["🔌 Servidor MCP"]
  MCP -->|"operaciones expuestas"| API["🌐 API del servicio"]
  MCP --> S
  subgraph S["🔒 Sandbox"]
    T["⚙️ La herramienta que ejecuta código"]
  end
  S -.->|no existe| H["🔑 El resto de tu equipo"]

El MCP decide qué herramientas hay. La API decide qué operaciones ofrece cada servicio. El sandbox decide qué puede tocar del sistema la herramienta que de verdad ejecuta algo — y es el único de los tres que sigue en pie si la herramienta hace algo que nadie previó. Eso es exactamente el caso 08.


Lo que un sandbox NO es#

programa puede hacer, conocido o no.

contiene muy bien a un script descuidado y mucho peor a alguien con un exploit de kernel en la mano.

necesidad de tener criterio.

Por eso este repositorio no te dice «esto es seguro». Te dice, con evidencia medida en tu host, qué controles quedaron efectivos y cuáles no.

Siguiente paso#