ZOYKUHot Board

earendil-works/gondolinDocumentazione

Experimental Linux microvm setup with a TypeScript Control Plane as Agent Sandbox

Nota sulla lingua:Documentazione tradotta non disponibile. Visualizzazione dell'originale ufficiale in inglese.
npm i gondolin

Gondolin Agent Sandbox

Local Linux micro-VMs with programmable network and filesystem control.

AI agents increasingly run generated code without human review. That code often needs network access and credentials, which creates exfiltration risk.

Gondolin runs that code inside a fast local Linux micro-VM (libkrun where available, QEMU otherwise) while keeping network and filesystem access under host-side policy control. That policy layer can be customized via JavaScript.

Quick Example

import { VM, createHttpHooks } from "@earendil-works/gondolin";

const { httpHooks, env } = createHttpHooks({
  allowedHosts: ["api.github.com"],
  secrets: {
    GITHUB_TOKEN: {
      hosts: ["api.github.com"],
      value: process.env.GITHUB_TOKEN!,
    },
  },
});

const vm = await VM.create({ httpHooks, env });

// String form runs in /bin/sh -lc "..."
const result = await vm.exec(`
  curl -sS -f \
    -H "Accept: application/vnd.github+json" \
    -H "Authorization: Bearer $GITHUB_TOKEN" \
    https://api.github.com/user
`);

console.log("exitCode:", result.exitCode);
console.log("stdout:\n", result.stdout);
console.log("stderr:\n", result.stderr);

await vm.close();

The guest only sees a placeholder token. The real secret is injected by the host only for allowed destinations (including Authorization: Basic ... flows).

CLI Quick Start

npx @earendil-works/gondolin bash

Useful session commands:

# List running sessions
npx @earendil-works/gondolin list

# Attach to an existing session
npx @earendil-works/gondolin attach <session-id>

# Snapshot a running session (stops it)
npx @earendil-works/gondolin snapshot <session-id>

# Resume from snapshot id/path
npx @earendil-works/gondolin bash --resume <snapshot-id-or-path>

Guest assets (kernel/initramfs/rootfs plus optional krun boot artifacts, ~200MB+) are resolved automatically on first use via builtin-image-registry.json and cached locally. When no image is specified, Gondolin uses GONDOLIN_DEFAULT_IMAGE (default: alpine-base:latest).

Requirements (QEMU is the fallback backend, and its qemu-img creates the root disk overlays on both backends):

macOS Linux (Debian/Ubuntu)
brew install qemu node sudo apt install qemu-system-arm nodejs npm (x86_64: qemu-system-x86)

Node.js 22.19 or newer is required for the SDK and the npm CLI.

The VM is run by the native engine: gondolind, a static Rust daemon shipped with the optional platform packages (@earendil-works/gondolin-native-*, macOS and Linux on arm64 and x64; without one, set GONDOLIN_NATIVE_BIN to a binary). The daemon can run on another machine (--native-command "ssh host gondolind" --remote): that machine only needs QEMU (or the krun runner, selected explicitly for remote daemons) and the binary, no Node.js; policy, hooks, credentials and file providers stay with your local Node.js process. The same binary is also a static gondolin CLI without Node.js.

The native engine serves guest file access over virtio-fs on krun and on a QEMU with vhost-user. Homebrew's QEMU lacks vhost-user, so QEMU on macOS uses the slower sandboxfs transport (see QEMU).

VM backend

The krun backend (libkrun) is the default wherever it can run: macOS on Apple silicon and Linux arm64/x86_64 with read/write access to /dev/kvm, a krun runner installed, and an image with krun boot assets (published images and gondolin build output have them). Everywhere else Gondolin uses QEMU, as it also does when a qemu-only option (sandbox.qemuPath, machineType, accel, cpu, qemuIdlePauseMs) is set. --vmm qemu|krun, sandbox.vmm or GONDOLIN_VMM=qemu|krun pins a backend; see VM Backends.

Published installs of @earendil-works/gondolin include the runner as an optional platform package on macOS arm64 and Linux x86_64. Elsewhere (Linux arm64) or from a checkout, build it with:

make krun-runner

This stages libkrun under .cache/ (no global install) and builds the local runner helper at host/krun-runner/zig-out/bin/gondolin-krun-runner. On macOS, the build ad-hoc signs the runner with the com.apple.security.hypervisor entitlement so Hypervisor.framework access is allowed. When present, Gondolin auto-detects this runner.

Linux prerequisites for make krun-runner (Ubuntu/Debian):

sudo apt install \
  build-essential curl git make pkg-config clang lld xz-utils \
  libclang-dev llvm-dev libcap-ng-dev

# libkrun requires a modern Rust toolchain (edition2024)
curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal
. "$HOME/.cargo/env"

# install Zig 0.17.0 for your Linux architecture

When vmm=krun is selected, Gondolin requires krun boot assets from the selected image manifest (assets.krunKernel and optional assets.krunInitrd). For custom kernels/initrds, provide an explicit sandbox.imagePath asset object and select vmm: "krun" explicitly (explicit asset paths default to QEMU).

Linux and macOS are supported. ARM64 is the most tested runtime path today. Linux x86_64 make krun-runner is covered by CI smoke builds.

Feature Highlights

  • Local disposable micro-VMs for agent turns/tasks
  • Programmable HTTP/TLS egress policy (allowlists + request/response hooks)
  • Secret injection without guest exposure via placeholders
  • Programmable VFS mounts that allow you to write custom file system behavior in JavaScript.
  • Ingress gateway to expose guest HTTP services on host (--listen, vm.enableIngress())
  • Attaching allows you to attach a shell to an already running VM
  • SSH support
    • host -> guest access (vm.enableSsh())
    • optional guest -> upstream allowlisted SSH egress (proxied, exec-oriented)
  • Disk checkpoints (snapshots) with resume support
  • Custom image builds (Alpine-based build pipeline, optional OCI rootfs source)
  • Native engine (default): a static Rust daemon (gondolind) runs the VM, also on remote machines without Node.js; the same binary is a static CLI
  • Tier-2 hooks: self-contained JavaScript policies (createDjsHooks(), --hooks-script) that run inside the daemon
  • Configurable DNS behavior (synthetic, trusted, open), rootfs modes (readonly, memory, cow), and runtime rootfs sizing

Documentation

Repository Guides

  • Host package: installation, CLI usage, and SDK examples
  • Guest sandbox: Zig build and image/initramfs pipeline
  • images/: canonical image release build configs (used by image-release workflow)
  • Examples: end-to-end integration examples

Pi Extension

There is a Pi + Gondolin extension that runs pi tools inside a micro-VM and mounts your project at /workspace.

Browser Use

There is a Browser Use example that runs Chromium inside a micro-VM and drives it from a Browser Use agent on the host through the ingress gateway. Only the guest-local Chrome DevTools endpoint is exposed:

node host/bin/gondolin.ts build --config host/examples/chromium.json --tag browser-use:latest
OPENAI_API_KEY=... node host/examples/browser-use.ts

AI Use Disclaimer

This codebase has been built with the support of coding agents.

Mirror archiviato dal repository ufficiale GitHub · Visita su GitHub
Data snapshot: 2026-11-08