Skip to content
GitHub Get Started
Use Cases

Dev Servers

Let users run their own server-style code inside a sandboxed isolate. A guest program can boot a real node:http server, bind a loopback port owned by the kernel, and serve requests, all without touching the host machine.

Secure Exec keeps a guest server running and forwards host requests into it. spawn() starts a long-running guest program and returns a process handle immediately, without waiting for it to exit. fetch(port, { method, path, headers, body }) drives an HTTP request from the host into the guest server listening on that port, through the kernel socket table, and returns the response. The request and response never leave the VM, so this works even when guest network egress is denied.

Spawn a server and drive host requests into it

Section titled “Spawn a server and drive host requests into it”

The guest boots an HTTP server on loopback and stays alive serving requests. The host spawns it, blocks on waitForListener() until the server is accepting connections, drives a request into it, then kills the process and waits for it to exit.

import { NodeRuntime } from "secure-exec";
// A user's "dev server": untrusted, long-running server-style code. It boots a
// real node:http server and keeps serving until it is killed, all inside the
// secure-exec VM with no access to the host machine.
const devServer = `
import http from "node:http";
// Start the user's server, exactly as they wrote it.
const app = http.createServer((req, res) => {
if (req.url === "/health") {
res.writeHead(200, { "content-type": "application/json" });
res.end(JSON.stringify({ ok: true }));
return;
}
res.writeHead(200, { "content-type": "text/plain" });
res.end("hello from the sandboxed dev server");
});
// Listen on loopback inside the VM. The kernel owns this socket; it never
// touches a real host port. The process stays alive serving requests until the
// host kills it.
app.listen(3000, "127.0.0.1", () => {
console.log("server listening on 127.0.0.1:3000");
});
`;
// The guest binds a loopback port, so opt in to networking. NodeRuntime.create()
// denies network by default; permissions merge over that secure default.
const runtime = await NodeRuntime.create({ permissions: { network: "allow" } });
try {
// spawn() starts the server as a long-running guest process and returns a
// handle immediately, without waiting for it to exit.
const server = await runtime.spawn(devServer, {
onStdout: (chunk) => process.stdout.write(new TextDecoder().decode(chunk)),
});
console.log("spawned guest server, pid:", server.pid);
try {
// Block until the guest is actually accepting connections on the port,
// then drive requests into it.
await runtime.waitForListener({ port: 3000 });
// Drive a real host->guest request into the running server.
const health = await runtime.fetch(3000, { path: "/health" });
console.log("health check ->", health.status, JSON.stringify(health.body));
const res = await runtime.fetch(3000, { method: "GET", path: "/" });
console.log("GET / ->", res.status, JSON.stringify(res.body));
console.log(
"RESULT " + JSON.stringify({ status: res.status, body: res.body }),
);
} finally {
// Tear the server down and wait for the guest process to exit.
server.kill();
await server.wait();
console.log("server stopped");
}
} finally {
// Tear down the VM and release the sidecar.
await runtime.dispose();
}

See Full Example

Running it spawns the server, drives host requests into it, and tears it down:

spawned guest server, pid: 1000000
server listening on 127.0.0.1:3000
health check -> 200 "{\"ok\":true}"
GET / -> 200 "hello from the sandboxed dev server"
RESULT {"status":200,"body":"hello from the sandboxed dev server"}
server stopped

The guest owns the server process, the application code, and the loopback socket, while the host stays in control of the lifecycle through the process handle (kill(), wait()) and dispose(). The kernel mediates the socket, so the guest never binds a real host port.

This is useful for platforms that let users write and preview server-side code (live coding environments, serverless playgrounds, educational tools) without giving them access to the host machine.