lumo

JavaScript que no toca nada que no le dejes.

lumo es un runtime de JavaScript y TypeScript seguro por defecto. Sin flags, el código no puede leer archivos, abrir red, leer variables de entorno ni lanzar procesos. En Linux lo impone también el kernel.

Instala lumo v0.0.1

$ curl -fsSL https://lumo.gitweave.run/install | bash
Ver el script de instalación

Instala en ~/.lumo/bin sin sudo y verifica el SHA-256 de la descarga. Requiere macOS 14 o posterior con Apple Silicon, o Linux x86_64/arm64 con glibc 2.38 o posterior (Ubuntu 24.04+, Debian 13+, Fedora 39+).

Pide permiso o falla con un mensaje claro

Este programa lee un archivo, una variable de entorno y escribe otro archivo. Concede cada permiso y mira qué cambia en la terminal: el error dice exactamente qué flag falta.

main.js

const config = await Lumo.readTextFile("./config.json");
console.log("config leída");
const token = Lumo.env.get("API_TOKEN");
console.log("token:", token ? "presente" : "ausente");
await Lumo.writeTextFile("./salida.txt", "ok");
console.log("salida escrita");
Concede permisos

Terminal

$ lumo run main.js

error: Uncaught PermissionDenied: Requiere permiso de lectura de "./config.json"; ejecuta de nuevo con --allow-read=./config.json

código de salida: 1

Simulación con los mensajes reales de lumo. En Linux, además, Landlock bloquearía la lectura aunque el runtime tuviera un bug.

Dos capas, por si una falla

En el runtime, en todas las plataformas

Cada operación con efectos fuera del proceso comprueba su permiso antes de actuar. Las rutas se resuelven antes de comparar, así que ni un .. ni un symlink que apunte fuera de lo concedido abren la puerta.

En el kernel, en Linux

Antes de ejecutar una sola línea de JS, lumo se encierra con Landlock (archivos y puertos TCP) y seccomp (syscalls). Lanzar un proceso sin --allow-run termina con el código 126. No hay forma de pedir más permisos después: se declaran al arrancar.

En macOS solo existe la capa del runtime: el sistema no ofrece un equivalente a Landlock que se pueda usar.

Comparado con otros runtimes

CaracterísticalumoDenoBunNode
MotorJavaScriptCoreV8JavaScriptCoreV8
Escrito enZigRustRustC++
Permisos por defectodenegadosdenegadossin modelo de permisosconcedidos
Confinamiento en el kernelLandlock y seccomp (Linux)nonono
Permisos durante la ejecuciónno: se declaran al arrancarsí, con prompts—no
Gestor de paquetesaparte (stil)integradointegradoaparte (npm)

Dónde está lumo hoy

lumo avanza por hitos y no da uno por cerrado hasta que sus tests pasan en macOS y Linux.

  1. M1

    Motor

    JavaScriptCore compilado y enlazado estáticamente; lumo eval.

    hecho
  2. M2

    Event loop

    Timers, microtasks y promesas sobre kqueue, io_uring o epoll.

    hecho
  3. M3

    Permisos

    Flags --allow-*, lumo.json, Landlock y seccomp.

    hecho
  4. M4

    Módulos y TypeScript

    ESM, CommonJS, node_modules y node:path funcionan; falta el borrado de tipos.

    en curso
  5. M5

    Red

    fetch con TLS y un servidor HTTP con Lumo.serve.

    pendiente
  6. M6

    Web APIs

    URL, Encoding, Streams y Fetch validados con web-platform-tests.

    pendiente
  7. M7

    Release 0.1

    Benchmarks contra Node, Bun y Deno y licencias revisadas. Hoy hay builds de vista previa (0.0.x).

    pendiente