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.
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).
npx @earendil-works/gondolin bashUseful 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 images (~200MB+) are downloaded on first use from the builtin registry
and cached locally (default: alpine-base:latest).
| macOS | Linux (Debian/Ubuntu) |
|---|---|
brew install qemu node |
sudo apt install qemu-system-arm qemu-utils nodejs npm (x86_64: qemu-system-x86) |
Node.js 22.19 or newer. npm install @earendil-works/gondolin also installs
the platform packages with the Gondolin daemon (gondolind, macOS and Linux on
arm64 and x64) and, on macOS arm64 and Linux x86_64, the krun runner. VMs run
on libkrun where it can (Apple silicon, Linux with /dev/kvm) and on QEMU
otherwise; QEMU's qemu-img is needed either way. See
Installation for the
details, the static CLI without Node.js, and building from a checkout.
- 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)
- host -> guest access (
- Disk checkpoints (snapshots) with resume support
- Custom image builds (Alpine-based build pipeline, optional OCI rootfs source)
- Remote machines: the VM runs under a static Rust daemon (
gondolind) that also works on another machine without Node.js, while policy, hooks and credentials stay local; the same binary is a static CLI - Daemon-side policies: self-contained JavaScript policies (
createDjsHooks(),--hooks-script) that run inside the daemon without a round trip to your process - Configurable DNS behavior (
synthetic,trusted,open), rootfs modes (readonly,memory,cow), and runtime rootfs sizing
- Installation and Quick Start
- Running Commands
- Network Access, HTTP Hooks and Policies and Secrets
- Files and Mounts and Persistence and Snapshots
- Ingress and SSH
- Images and Building Custom Images
- Remote Machines
- CLI Reference, SDK Reference and Environment Variables
- Architecture, Security Design and Limitations
- Upgrading
- 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
There is a Pi + Gondolin extension that runs
pi tools inside a micro-VM and mounts your project at /workspace.
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.tsThis codebase has been built with the support of coding agents.
- Documentation
- Issue Tracker
- License: Apache-2.0