### Verify Secure Exec Quickstart Examples Source: https://github.com/rivet-dev/secure-exec/blob/main/examples/quickstart/README.md Run these commands to verify the types and documentation of the Secure Exec quickstart examples. ```bash pnpm --filter @secure-exec/example-quickstart check-types ``` ```bash pnpm --filter @secure-exec/example-quickstart verify-docs ``` -------------------------------- ### Install Dependencies and Run Test Source: https://github.com/rivet-dev/secure-exec/blob/main/examples/virtual-file-system-s3/README.md After setting up MinIO, install the project dependencies and run the test suite to execute the S3 filesystem example. ```bash pnpm install pnpm test ``` -------------------------------- ### Secure Exec with Server Boilerplate Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/research/comparison/cloudflare-dynamic-workers.md This example shows how a user might manually wire up server boilerplate when using Secure Exec, including defining a Hono app and starting a server. ```javascript // User has to wire up server boilerplate const code = ` const { serve } = require('@hono/node-server'); const { Hono } = require('hono'); const app = new Hono(); app.get('/', (c) => c.text('hello')); serve({ fetch: app.fetch, port: 3000 }); `; await process.exec(code); ``` -------------------------------- ### Install secure-exec Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/sdk-overview.mdx Install the package using your preferred package manager. ```bash npm install secure-exec ``` ```bash bun add secure-exec ``` ```bash pnpm add secure-exec ``` ```bash yarn add secure-exec ``` -------------------------------- ### Install secure-exec Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/quickstart.mdx Install the package using your preferred package manager. ```bash npm install secure-exec ``` ```bash pnpm add secure-exec ``` ```bash bun add secure-exec ``` ```bash yarn add secure-exec ``` -------------------------------- ### Add a codemode example Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/todo.md Provide a focused example that demonstrates secure-exec usage in a realistic tool flow. Files are located in the examples/ directory. -------------------------------- ### Secure-Exec Consumer API - Minimal Usage (WasmVM only) Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/arch/kernel-integration.md Illustrates the minimal setup for secure-exec using only the WasmVM runtime. This example shows kernel creation and mounting the WasmVM runtime to execute a simple command. ```typescript import { createKernel, createWasmVmRuntime } from 'secure-exec'; const kernel = createKernel({ filesystem: createInMemoryFileSystem() }); kernel.mount(createWasmVmRuntime()); const result = await kernel.exec('echo hello'); ``` -------------------------------- ### Reproduce Benchmarks Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/benchmarks.mdx Commands to clone the repository, install dependencies, and execute performance benchmarks. ```bash # Clone and install git clone https://github.com/rivet-dev/secure-exec cd secure-exec && pnpm install # Run both benchmarks (saves timestamped results to benchmarks/results/) cd packages/secure-exec ./benchmarks/run-benchmarks.sh # Or run individually npx tsx benchmarks/coldstart.bench.ts # cold + warm start node --expose-gc --import tsx/esm benchmarks/memory.bench.ts # memory ``` -------------------------------- ### Start MinIO with Docker Compose Source: https://github.com/rivet-dev/secure-exec/blob/main/examples/virtual-file-system-s3/README.md Use this command to quickly start a local MinIO instance using Docker Compose for testing. ```bash docker compose up -d ``` -------------------------------- ### Runnable Filesystem Example Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/features/filesystem.mdx Demonstrates how to use an in-memory filesystem with secure-exec to execute code that interacts with the filesystem. ```APIDOC ## Runnable Filesystem Example ### Description This example shows how to set up and use an in-memory filesystem with `secure-exec`. It executes code within a sandbox that creates a directory and writes a file to this in-memory filesystem. The example then verifies the content written to the file. ### Method N/A (This is a client-side code example) ### Endpoint N/A ### Request Example ```typescript import { NodeRuntime, allowAllFs, createInMemoryFileSystem, createNodeDriver, createNodeRuntimeDriverFactory, } from "../..\/packages\/secure-exec\/src\/index.ts"; const filesystem = createInMemoryFileSystem(); const runtime = new NodeRuntime({ systemDriver: createNodeDriver({ filesystem, permissions: { ...allowAllFs }, }), runtimeDriverFactory: createNodeRuntimeDriverFactory(), }); try { const result = await runtime.exec(` import fs from "node:fs"; fs.mkdirSync("/workspace", { recursive: true }); fs.writeFileSync("/workspace/hello.txt", "hello from the sandbox"); `, { filePath: "/entry.mjs" }); if (result.code !== 0) { throw new Error(`Unexpected execution result: ${JSON.stringify(result)}`); } const message = await filesystem.readTextFile("/workspace/hello.txt"); console.log( JSON.stringify({ ok: message === "hello from the sandbox", message, summary: "sandbox wrote to the in-memory filesystem", }), ); } finally { runtime.dispose(); } ``` ### Response Example ```json { "ok": true, "message": "hello from the sandbox", "summary": "sandbox wrote to the in-memory filesystem" } ``` ``` -------------------------------- ### Consumer API - Minimal Usage (WasmVM only) Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/arch/kernel-integration.md A minimal example demonstrating the initialization of the kernel with only the WasmVM runtime. ```APIDOC ## Consumer API - Minimal Usage (WasmVM only) ### Description This example shows the most basic setup, initializing the kernel with only the WasmVM runtime and executing a simple command. ### Initialization and Execution ```typescript import { createKernel, createWasmVmRuntime } from 'secure-exec'; const kernel = createKernel({ filesystem: createInMemoryFileSystem() }); kernel.mount(createWasmVmRuntime()); const result = await kernel.exec('echo hello'); ``` ``` -------------------------------- ### Secure Exec with Exported Fetch Handler Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/research/comparison/cloudflare-dynamic-workers.md This example demonstrates how a user can export a fetch handler directly from their code, which the host can then invoke, simplifying server setup within Secure Exec. ```javascript // User code is just the handler const code = ` const { Hono } = require('hono'); const app = new Hono(); app.get('/', (c) => c.text('hello')); module.exports = { fetch: app.fetch }; `; const worker = await process.run(code); // Host calls the exported fetch directly const response = await worker.exports.fetch(request); ``` -------------------------------- ### Install Secure Exec Source: https://github.com/rivet-dev/secure-exec/blob/main/README.md Command to install the library via npm. ```bash npm install secure-exec ``` -------------------------------- ### Verify feature examples Source: https://github.com/rivet-dev/secure-exec/blob/main/examples/features/README.md Use these commands to validate types and execute tests for the feature examples package. ```bash pnpm --filter @secure-exec/example-features check-types pnpm --filter @secure-exec/example-features test ``` -------------------------------- ### Run Hono Sandbox Example Source: https://github.com/rivet-dev/secure-exec/blob/main/examples/hono/README.md Execute the Hono sandbox example using pnpm. This command initiates the loader, which in turn sets up and interacts with the sandboxed runner. ```bash pnpm -C examples/hono/loader dev ``` -------------------------------- ### Initialize NodeRuntime Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/architecture.mdx Demonstrates the basic setup of a NodeRuntime instance with a system driver. ```ts import { NodeRuntime, createNodeDriver } from "secure-exec"; const runtime = new NodeRuntime({ systemDriver: createNodeDriver(), }); await runtime.exec("console.log('hello')"); await runtime.run("export default 42"); runtime.dispose(); ``` -------------------------------- ### Install kernel dependencies Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/kernel/quickstart.mdx Install the core kernel and required runtime drivers via pnpm. ```bash pnpm add @secure-exec/kernel @secure-exec/runtime-wasmvm @secure-exec/runtime-node ``` -------------------------------- ### Setup WebAssembly Execution Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/wasm/webapi/esm-integration/execute-start.tentative.html Configure the WebAssembly execution environment to allow uncaught exceptions. This setup is necessary before loading and testing modules. ```javascript setup({allow_uncaught_exception: true}); ``` -------------------------------- ### Pi Cross-Surface Parity Test Setup Source: https://github.com/rivet-dev/secure-exec/blob/main/scripts/ralph/progress.txt Illustrates the setup for a cross-surface parity test, ensuring consistent outcomes across SDK, PTY, and headless surfaces using the same mock LLM server and tool calls. ```typescript import { createSandbox } from '@e2b/sdk'; import { createKernel, createNodeRuntime, createNodeHostNetworkAdapter } from '@e2b/kernel'; import { spawn } from 'child_process'; // SDK Surface const sdkSandbox = await createSandbox({ /* ... */ }); await sdkSandbox.exec('read file.txt'); await sdkSandbox.exec('pwd'); await sdkSandbox.exec('write file.txt'); const sdkResult = await sdkSandbox.exec('echo "final"'); // PTY Surface const ptyKernel = createKernel({ hostNetworkAdapter: createNodeHostNetworkAdapter() }); const ptyRuntime = createNodeRuntime({ kernel: ptyKernel, permissions: { allowAllFs: true, allowAllNetwork: true, allowAllChildProcess: true, allowAllEnv: true } }); const ptyShell = await ptyRuntime.openShell({ cwd: sdkSandbox.workDir }); await ptyShell.exec('read file.txt'); await ptyShell.exec('pwd'); await ptyShell.exec('write file.txt'); const ptyResult = await ptyShell.exec('echo "final"'); // Headless Surface // Assumes a mock LLM server is running and fetch-intercept is preloaded const headlessProcess = spawn('node', ['path/to/headless/script.js'], { stdio: 'pipe' }); // ... interact with headless process and verify output // Assertions for exit code, file content, and final text across all surfaces ``` -------------------------------- ### Execute Codemod Example Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/spec-hardening.md Command to run the codemod example workflow within the secure-exec environment. ```bash pnpm --filter codemod-example start ``` -------------------------------- ### Setup back button navigation Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/resource-timing/resources/embed-navigate-back.html Initializes the navigation environment for an embedded HTML file. ```javascript setup_back_navigation("embed-navigate-back.html"); target.src = pre_navigate_url; ``` -------------------------------- ### Setup iframe back navigation Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/resource-timing/resources/iframe-navigate-back.html Initializes the navigation environment for iframe back button testing. ```javascript setup_back_navigation("iframe-navigate-back.html"); target.src = pre_navigate_url; ``` -------------------------------- ### Project Directory Structure Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/common/security-features/README.md Example of a nested project directory structure showing parent and child project components. ```text project-directory/ (e.g. referrer-policy/) ├── spec.src.json - Parent project's spec JSON ├── generic/ │ └── test-case.sub.js - Parent project's test helper ├── gen/ - parent project's generated tests └── sub-project-directory/ (e.g. 4K) ├── spec.src.json - Child project's spec JSON ├── generic/ │ └── test-case.sub.js - Child project's test helper └── gen/ - child project's generated tests ``` -------------------------------- ### Setup back navigation for object elements Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/resource-timing/resources/object-navigate-back.html Initializes the navigation environment for an object element using a specific HTML file. ```javascript setup_back_navigation("object-navigate-back.html"); ``` -------------------------------- ### Execute synchronous XMLHttpRequest request Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/resource-timing/resources/fake_responses_https.sub.html Performs a synchronous GET request to a dynamically constructed URL. This function is intended to be called after the parent iframe setup is complete. ```javascript function request() { var client = new XMLHttpRequest, baseurl = "https://{{hosts[alt][]}}:{{ports[https][0]}}{{location[pathname]}}", url = new URL("fake_responses.py", baseurl).href; client.open("GET", url, false) client.send(null) client.open("GET", url, false) client.send(null) } if(window.parent.setup_iframe) { window.parent.setup_iframe(); request(); } ``` -------------------------------- ### Serialize Blob URL Origin in Multi-Global Setup Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/FileAPI/url/multi-global-origin-serialization.sub.html This example demonstrates how to serialize a blob URL's origin in a multi-global context. It asserts that the origin correctly reflects the 'www1' subdomain as configured. ```javascript "use strict"; setup({ single_test: true }); document.domain = "{{host}}"; window.onload = () => { const url = frames[0].createBlobURL(); const desired = "blob:{{location[scheme]}}://www1"; assert_equals(url.substring(0, desired.length), desired, "Origin should contain www1, from the current settings object"); done(); }; ``` -------------------------------- ### Snapshot Creation Flow - Initial Setup Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/specs/v8-context-snapshot.md This outlines the steps involved in creating a snapshot, including isolate and context creation, registration of bridge functions, injection of default globals, and running the bridge IIFE. ```plaintext 1. Create snapshot_creator isolate with ExternalReferences 2. Create context 3. Register STUB bridge functions on global - Same names (_fsReadFile, _log, etc.) - Same callbacks (sync_bridge_callback, async_bridge_callback) - External data points to a static no-op BridgeCallContext - These stubs exist so the bridge IIFE can reference them at setup time 4. Inject default config globals: - __runtimeBridgeSetupConfig = { initialCwd: "/", ... } - __runtimeCustomGlobalPolicy = { hardenedGlobals: [...], mutableGlobals: [...] } - _maxTimers = DEFAULT_MAX_TIMERS - _maxHandles = DEFAULT_MAX_HANDLES - _processConfig = { cwd: "/", env: {}, ... } - _osConfig = { homedir: "/root", ... } 5. Run the STATIC bridge IIFE - ivm-compat shim - globalExposureHelpers - bridgeInitialGlobals (with deferred config) - consoleSetup - setupFsFacade (with getter delegation) - bridge bundle IIFE - bridge attach - applyTimingMitigationOff (default — freeze applied post-restore) - requireSetup - initCommonjsModuleGlobals - applyCustomGlobalPolicy 6. set_default_context(context) 7. create_blob(FunctionCodeHandling::Keep) ``` -------------------------------- ### Compare Session Initialization Flows Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/specs/v8-startup-snapshot.md Visualizes the transition from standard per-session initialization to the optimized snapshot-based restoration flow. ```text Per session (current): create_isolate() → create_context() → disable_wasm() → register_bridge_fns() → run_bridge_iife() → inject_globals() → run_user_code() Per session (with snapshot): restore_from_snapshot() → create_context() → disable_wasm() → register_bridge_fns() → run_bridge_iife(code-cached) → inject_globals() → run_user_code() ``` -------------------------------- ### Full Node.js CLI Example with Secure Exec Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/kernel/interactive-shell.mdx A complete Node.js CLI application demonstrating the setup and usage of Secure Exec. It mounts Wasm and Node.js runtimes, connects to an interactive terminal, and handles kernel disposal. ```typescript import { createKernel } from "@secure-exec/kernel"; import { createInMemoryFileSystem } from "@secure-exec/os-browser"; import { createWasmVmRuntime } from "@secure-exec/runtime-wasmvm"; import { createNodeRuntime } from "@secure-exec/runtime-node"; const vfs = createInMemoryFileSystem(); const kernel = createKernel({ filesystem: vfs }); await kernel.mount(createWasmVmRuntime({ commandDirs: ["./wasmvm/target/wasm32-wasip1/release/commands"], })); await kernel.mount(createNodeRuntime()); // Drop into an interactive shell — ^D or `exit` to quit const exitCode = await kernel.connectTerminal(); await kernel.dispose(); process.exit(exitCode); ``` -------------------------------- ### Initialize and execute with Secure Exec kernel Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/kernel/quickstart.mdx Demonstrates setting up the kernel with an in-memory filesystem, mounting runtimes, and executing shell and Node.js commands. ```ts import { createKernel } from "@secure-exec/kernel"; import { createInMemoryFileSystem } from "@secure-exec/os-browser"; import { createWasmVmRuntime } from "@secure-exec/runtime-wasmvm"; import { createNodeRuntime } from "@secure-exec/runtime-node"; const vfs = createInMemoryFileSystem(); const kernel = createKernel({ filesystem: vfs }); await kernel.mount(createWasmVmRuntime({ commandDirs: ["./wasmvm/target/wasm32-wasip1/release/commands"], })); await kernel.mount(createNodeRuntime()); // Shell commands const echo = await kernel.exec("echo hello | tr a-z A-Z"); console.log(echo.stdout); // "HELLO\n" // Node code that calls shell commands const node = await kernel.exec(`node -e " const { execSync } = require('child_process'); console.log(execSync('echo hi from shell', { encoding: 'utf-8' }).trim()); "`); console.log(node.stdout); // "hi from shell\n" // Shared VFS await kernel.writeFile("/tmp/msg.txt", "cross-runtime"); const cat = await kernel.exec("cat /tmp/msg.txt"); console.log(cat.stdout); // "cross-runtime" await kernel.dispose(); ``` -------------------------------- ### Spawn a process directly Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/kernel/api-reference.mdx Use `kernel.spawn()` to start a process directly and get a `ManagedProcess` handle. This handle allows for streaming I/O and waiting for process completion. Options include stdout/stderr callbacks, environment variables, and working directory. ```typescript const proc = kernel.spawn("node", ["-e", "console.log('hi')"], { onStdout: (data) => process.stdout.write(data), onStderr: (data) => process.stderr.write(data), env: { NODE_ENV: "production" }, }); console.log(proc.pid); // e.g. 42 const exitCode = await proc.wait(); ``` -------------------------------- ### Run TypeScript code with module loading Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/features/module-loading.mdx This example demonstrates running TypeScript code within a sandbox, importing the host's installed TypeScript package. Ensure the runtime is configured with appropriate file system permissions and module access. ```typescript import path from "node:path"; import { fileURLToPath } from "node:url"; import { NodeRuntime, allowAllFs, createNodeDriver, createNodeRuntimeDriverFactory, } from "../../../packages/secure-exec/src/index.ts"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../.."); const runtime = new NodeRuntime({ systemDriver: createNodeDriver({ moduleAccess: { cwd: repoRoot }, permissions: { ...allowAllFs }, }), runtimeDriverFactory: createNodeRuntimeDriverFactory(), }); try { const result = await runtime.run<{ version: string }>( ` import typescript from "/root/node_modules/typescript/lib/typescript.js"; export const version = typescript.version; `, "/app/example.mjs", ); if (result.code !== 0 || typeof result.exports?.version !== "string") { throw new Error(`Unexpected runtime result: ${JSON.stringify(result)}`); } console.log( JSON.stringify({ ok: true, version: result.exports.version, summary: "sandbox resolved the host typescript package from the overlay", }), ); } finally { runtime.dispose(); } ``` -------------------------------- ### Configure Filesystem Permissions in NodeRuntime Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/features/permissions.mdx This example demonstrates how to configure filesystem permissions for a NodeRuntime. It allows access to paths starting with '/workspace' while denying access to '/secret.txt'. The sandboxed code attempts to write to '/workspace' and read from '/secret.txt' to verify the permissions. ```typescript import { NodeRuntime, createInMemoryFileSystem, createNodeDriver, createNodeRuntimeDriverFactory, } from "../../../packages/secure-exec/src/index.ts"; const filesystem = createInMemoryFileSystem(); await filesystem.writeFile("/secret.txt", "top secret"); const runtime = new NodeRuntime({ systemDriver: createNodeDriver({ filesystem, permissions: { fs: (request) => ({ allow: request.path.startsWith("/workspace") }), }, }), runtimeDriverFactory: createNodeRuntimeDriverFactory(), }); const result = await runtime.run<{ message: string; blocked: boolean; }>( ` import fs from "node:fs"; fs.mkdirSync("/workspace", { recursive: true }); fs.writeFileSync("/workspace/message.txt", "hello from permissions"); let blocked = false; try { fs.readFileSync("/secret.txt", "utf8"); } catch (error) { blocked = error && error.code === "EACCES"; } export const message = fs.readFileSync("/workspace/message.txt", "utf8"); export { blocked }; `, "/entry.mjs", ); console.log( JSON.stringify({ ok: result.code === 0 && result.exports?.message === "hello from permissions" && result.exports?.blocked === true, message: result.exports?.message, blocked: result.exports?.blocked, summary: "filesystem access was allowed for /workspace and denied for /secret.txt", }) ); ``` -------------------------------- ### Run a Hono Dev Server in an Isolate Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/use-cases/dev-servers.mdx Starts a user-provided Hono server within a sandboxed isolate, waits for its health endpoint, proxies requests, and terminates the runtime. Requires setup of NodeRuntime with appropriate network permissions and resource limits. ```typescript import { createServer } from "node:net"; import { NodeRuntime, allowAllNetwork, createNodeDriver, createNodeRuntimeDriverFactory, } from "secure-exec"; const host = "127.0.0.1"; const port = await findOpenPort(); const logs: string[] = []; const runtime = new NodeRuntime({ systemDriver: createNodeDriver({ useDefaultNetwork: true, permissions: { ...allowAllNetwork }, }), runtimeDriverFactory: createNodeRuntimeDriverFactory(), memoryLimit: 128, cpuTimeLimitMs: 60_000, }); const execPromise = runtime.exec(` import { Hono } from "hono"; import { serve } from "@hono/node-server"; const app = new Hono(); app.get("/", (c) => c.text("hello from sandboxed hono")); app.get("/health", (c) => c.json({ ok: true })); serve({ fetch: app.fetch, port: ${port}, hostname: "${host}", }); console.log("server:listening:${port}"); await new Promise(() => {}); `, { filePath: "/app/server.mjs", onStdio: (event) => logs.push(`[${event.channel}] ${event.message}`), }); try { await waitForServer(runtime, `http://${host}:${port}/health`); const response = await runtime.network.fetch(`http://${host}:${port}/`, { method: "GET", }); console.log(response.status); // 200 console.log(response.body); // "hello from sandboxed hono" } finally { await runtime.terminate(); await execPromise.catch(() => undefined); } async function findOpenPort(): Promise { return new Promise((resolve, reject) => { const server = createServer(); server.once("error", reject); server.listen(0, host, () => { const address = server.address(); if (!address || typeof address !== "object") { reject(new Error("Failed to allocate a port")); server.close(); return; } const allocatedPort = address.port; server.close((error) => { if (error) { reject(error); return; } resolve(allocatedPort); }); }); }); } async function waitForServer(runtime: NodeRuntime, url: string): Promise { for (let attempt = 0; attempt < 50; attempt += 1) { try { const response = await runtime.network.fetch(url, { method: "GET" }); if (response.status === 200) { return; } } catch { // Retry until the server is ready. } await new Promise((resolve) => setTimeout(resolve, 100)); } throw new Error(`Timed out waiting for ${url}`); } ``` -------------------------------- ### Setup Host Functions and Test Window Opening Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/wasm/jsapi/functions/entry.html Sets up host functions and tests the indirect opening of a window. It verifies that the opened window's location matches the expected URL and ensures cleanup by closing the window. ```javascript setup({ explicit_done: true }); const relativeURL = "resources/window-to-open.html"; const expectedURL = (new URL(relativeURL, location.href)).href; const incumbentWindow = frames[0]; window.onload = () => { async_test(t => { const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); w.onload = t.step_func_done(() => { t.add_cleanup(() => w.close()); assert_equals(w.location.href, expectedURL); }); }, "Sanity check: this all works as expected synchronously"); async_test(t => { // No t.step_func because that could change the realms call_later(() => { const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); w.onload = t.step_func_done(() => { t.add_cleanup(() => w.close()); assert_equals(w.location.href, expectedURL); }); }); }, "Start function"); done(); }; ``` -------------------------------- ### Execute Context Initialization Flow Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/specs/v8-context-snapshot.md Comparison of the legacy context initialization flow versus the new snapshot-restored flow. ```text create_context() → register_bridge_fns() → run_bridge_iife() ``` ```text get default context from snapshot → replace_bridge_fns() → inject_globals() → run_post_restore_script() ``` -------------------------------- ### Consumer API - Simple Usage Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/arch/kernel-integration.md Demonstrates the basic usage of the secure-exec consumer API, including kernel creation, runtime mounting, and command execution. ```APIDOC ## Consumer API - Simple Usage ### Description This example shows the fundamental steps to initialize and use the secure-exec kernel. It includes mounting WasmVM, Node.js, and Python runtimes, executing commands, handling pipelines, spawning processes directly, and performing file system operations. ### Initialization ```typescript import { createKernel, createWasmVmRuntime, createNodeRuntime, createPythonRuntime } from 'secure-exec'; const kernel = createKernel({ filesystem: createInMemoryFileSystem(), permissions: allowAll, env: { HOME: '/home/user', PATH: '/bin:/usr/bin' }, }); // Mount the runtimes you need kernel.mount(createWasmVmRuntime()); kernel.mount(createNodeRuntime()); kernel.mount(createPythonRuntime()); ``` ### Command Execution ```typescript // Execute commands (goes through brush-shell) const result = await kernel.exec('echo hello | grep hello'); console.log(result); // { exitCode: 0, stdout: 'hello\n', stderr: '' } // Cross-runtime pipelines await kernel.exec('ls -la | python -c "import sys; print(len(sys.stdin.readlines()))"'); ``` ### Process Spawning ```typescript // Direct process spawning const proc = kernel.spawn('node', ['-e', 'console.log(1+1)']); await proc.wait(); ``` ### Filesystem Access ```typescript // Filesystem access await kernel.writeFile('/tmp/data.txt', 'hello world'); const data = await kernel.readFile('/tmp/data.txt'); ``` ### Cleanup ```typescript // Cleanup await kernel.dispose(); ``` ``` -------------------------------- ### Setup and Test Incumbent Host Functions Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/wasm/jsapi/functions/incumbent.html Initializes the test environment and verifies that host functions correctly report the incumbent page URL via postMessage. ```javascript setup({ explicit_done: true }); // postMessage should pick the incumbent page as its .source value to set on the MessageEvent, even // inside host functions. const expectedURL = (new URL("resources/incumbent-incumbent.html", location.href)).href; let testId = 0; window.onload = () => { const relevantWindow = frames[0].document.querySelector("#r").contentWindow; function setupTest(t) { ++testId; const thisTestId = testId; relevantWindow.addEventListener("messagereceived", t.step_func(e => { const [receivedTestId, receivedSourceURL] = e.detail; if (receivedTestId !== thisTestId) { return; } assert_equals(receivedSourceURL, expectedURL); t.done(); })); return thisTestId; } async_test(t => { const thisTestId = setupTest(t); frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*"); }, "Sanity check: this all works as expected synchronously"); async_test(t => { const thisTestId = setupTest(t); frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(thisTestId, "*"); }, "Start function"); done(); }; ``` -------------------------------- ### Run Sandboxed Code with In-Memory Filesystem Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/features/filesystem.mdx This example demonstrates executing code within a sandbox that uses an in-memory filesystem. It shows how to create the filesystem, configure the runtime, execute a script that writes to a file, and then read the file's content from the in-memory filesystem to verify the operation. Ensure the runtime is disposed after use. ```typescript import { NodeRuntime, allowAllFs, createInMemoryFileSystem, createNodeDriver, createNodeRuntimeDriverFactory, } from "../../../packages/secure-exec/src/index.ts"; const filesystem = createInMemoryFileSystem(); const runtime = new NodeRuntime({ systemDriver: createNodeDriver({ filesystem, permissions: { ...allowAllFs }, }), runtimeDriverFactory: createNodeRuntimeDriverFactory(), }); try { const result = await runtime.exec( ` import fs from "node:fs"; fs.mkdirSync("/workspace", { recursive: true }); fs.writeFileSync("/workspace/hello.txt", "hello from the sandbox"); `, { filePath: "/entry.mjs" }, ); if (result.code !== 0) { throw new Error(`Unexpected execution result: ${JSON.stringify(result)}`); } const message = await filesystem.readTextFile("/workspace/hello.txt"); console.log( JSON.stringify({ ok: message === "hello from the sandbox", message, summary: "sandbox wrote to the in-memory filesystem", }), ); } finally { runtime.dispose(); } ``` -------------------------------- ### Create and Mount Node Runtime with Kernel Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/runtimes/node.mdx Use this approach to create a kernel and mount the Node runtime driver. It's recommended for new projects. ```typescript import { createKernel, createInMemoryFileSystem, createNodeRuntime, } from "secure-exec"; const kernel = createKernel({ filesystem: createInMemoryFileSystem(), }); await kernel.mount(createNodeRuntime()); const result = await kernel.exec("node -e \"console.log('hello')\""); console.log(result.stdout); // "hello\n" await kernel.dispose(); ``` -------------------------------- ### JavaScript and WebAssembly Cycle Setup Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/wasm/webapi/esm-integration/wasm-js-cycle.tentative.html Initializes the testing environment for JavaScript and WebAssembly interactions. This setup is used for testing bindings between the two. ```javascript setup({ single_test: true }); ``` -------------------------------- ### Basic Node.js Sandboxing with Secure Exec Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/proposal-kernel-consolidation.md Demonstrates setting up a Node.js sandbox using `createKernel` and `NodeRuntime`. Requires importing `NodeFileSystem` and `allowAll` permissions. The kernel is mounted with the Node runtime and then used to execute a simple Node.js script. ```typescript import { createKernel, NodeRuntime } from "secure-exec"; // or import { createKernel } from "@secure-exec/core"; import { NodeRuntime } from "@secure-exec/nodejs"; const kernel = createKernel({ filesystem: new NodeFileSystem(), permissions: allowAll, }); await kernel.mount(new NodeRuntime()); const result = await kernel.exec("node -e 'console.log(1 + 1)'"); // { exitCode: 0, stdout: "2\n", stderr: "" } await kernel.dispose(); ``` -------------------------------- ### Initialize the kernel Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/kernel/quickstart.mdx Create a kernel instance with a specific filesystem implementation. ```typescript import { createKernel } from "@secure-exec/kernel"; import { createInMemoryFileSystem } from "@secure-exec/os-browser"; const vfs = createInMemoryFileSystem(); const kernel = createKernel({ filesystem: vfs }); ``` ```typescript import { createInMemoryFileSystem } from "@secure-exec/os-browser"; const vfs = createInMemoryFileSystem(); const kernel = createKernel({ filesystem: vfs }); ``` ```typescript import { NodeFileSystem } from "@secure-exec/os-node"; const vfs = new NodeFileSystem(); const kernel = createKernel({ filesystem: vfs }); ``` -------------------------------- ### Test WebAssembly Module Start Function Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/wasm/webapi/esm-integration/execute-start.tentative.html Asynchronously test if the start function of an imported WebAssembly module executes correctly. It verifies that the 'executed' message is logged. ```javascript const test_load = async_test( "Importing a WebAssembly module should execute the start function."); window.log = []; window.addEventListener("error", ev => { log.push(ev.message); }); window.addEventListener("load", test_load.step_func_done(ev => { assert_array_equals(log, ["executed"]); })); function unreachable() { log.push("unexpected"); } ``` -------------------------------- ### Create and Use In-Memory Filesystem Source: https://context7.com/rivet-dev/secure-exec/llms.txt Demonstrates creating a virtual filesystem for sandboxed code to interact with. Pre-populate files before execution and access them from within the sandbox. The host can also read files written by the sandbox. ```typescript import { NodeRuntime, createNodeDriver, createNodeRuntimeDriverFactory, createInMemoryFileSystem, allowAllFs, } from "secure-exec"; // Create in-memory filesystem const filesystem = createInMemoryFileSystem(); // Pre-populate files before execution await filesystem.writeFile("/config.json", JSON.stringify({ debug: true })); const runtime = new NodeRuntime({ systemDriver: createNodeDriver({ filesystem, permissions: { ...allowAllFs }, }), runtimeDriverFactory: createNodeRuntimeDriverFactory(), }); // Sandbox code can read/write to the virtual filesystem await runtime.exec( ` import fs from "node:fs"; // Read pre-populated file const config = JSON.parse(fs.readFileSync("/config.json", "utf8")); console.log("Debug mode:", config.debug); // Write new files fs.mkdirSync("/workspace", { recursive: true }); fs.writeFileSync("/workspace/output.txt", "Generated by sandbox"); `, { filePath: "/entry.mjs" } ); // Host can read files written by sandbox const output = await filesystem.readTextFile("/workspace/output.txt"); console.log(output); // "Generated by sandbox" runtime.dispose(); ``` -------------------------------- ### Create Kernel with All Permissions Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/kernel/api-reference.mdx Initialize a kernel instance with a virtual filesystem and allow all operations. ```typescript const kernel = createKernel({ filesystem: vfs, permissions: allowAll, // everything allowed }); ``` -------------------------------- ### Test Prefixed CSS Animation Start Events Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/dom/events/webkit-animation-start-event.html Use this function to test both unprefixed and prefixed animation start events. Ensure the animation CSS style is set correctly. ```javascript 'use strict'; runAnimationEventTests({ unprefixedType: 'animationstart', prefixedType: 'webkitAnimationStart', animationCssStyle: '1ms', }); ``` -------------------------------- ### Selection Object Example Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/common/security-features/README.md An example of a selection object, representing a single test configuration generated from a test expansion pattern. This includes specific values for delivery type, origin, and subresource. ```json { "delivery_type": "http-rp", "delivery_key": "referrerPolicy", "delivery_value": "no-referrer-when-downgrade", "source_context_list": "worker-classic", "expectation": "stripped-referrer", "origin": "same-http", "redirection": "no-redirect", "source_scheme": "http", "subresource": "fetch" } ``` -------------------------------- ### Test Expansion Pattern Example Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/common/security-features/README.md An example of a test expansion pattern used to define combinations of test configurations. This pattern specifies values for delivery type, expectation, origin, and source scheme. ```json { "name": "insecure-protocol", "expansion": "default", "delivery_type": "*", "delivery_value": "no-referrer-when-downgrade", "source_context_list": "*", "expectation": "stripped-referrer", "origin": ["same-http", "cross-http"], "redirection": "*", "source_scheme": "http", "subresource": "*" } ``` -------------------------------- ### Initialize TypeScript Tools Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/runtimes/node.mdx Set up the TypeScript compiler within a sandbox using shared drivers and an in-memory filesystem. ```ts import { createInMemoryFileSystem } from "@secure-exec/core"; import { createNodeDriver, createNodeRuntimeDriverFactory, } from "@secure-exec/nodejs"; import { createTypeScriptTools } from "@secure-exec/typescript"; const filesystem = createInMemoryFileSystem(); const systemDriver = createNodeDriver({ filesystem }); const runtimeDriverFactory = createNodeRuntimeDriverFactory(); const ts = createTypeScriptTools({ systemDriver, runtimeDriverFactory, }); ``` -------------------------------- ### Setup for Cyclic Linking Test Source: https://github.com/rivet-dev/secure-exec/blob/main/packages/secure-exec/tests/node-conformance/fixtures/wpt/wasm/webapi/esm-integration/js-wasm-cycle-errors.tentative.html Configures the environment to allow uncaught exceptions and initiates a test for cyclic linking between JavaScript and WebAssembly. This setup is crucial for verifying module graph integrity when JavaScript is the higher-level module. ```javascript setup({allow_uncaught_exception: true}); const test_load = async_test( "Check cyclic linking between JavaScript and WebAssembly where JavaScript is higher in the module graph."); window.log = []; window.addEventListener("error", ev => { test_load.step(() => assert_equals(ev.error.constructor, WebAssembly.LinkError)); log.push(ev.message); }); window.addEventListener("load", test_load.step_func_done(ev => { assert_equals(log.length, 10); assert_equals(log[1], 1); assert_equals(log[3], 2); assert_equals(log[5], 3); assert_equals(log[7], 4); assert_equals(log[9], 5); })); function unreachable() { log.push("unexpected"); } ``` -------------------------------- ### Quick Setup: Enable Network Access Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/features/networking.mdx Enables default network access for the sandbox by setting `useDefaultNetwork: true` and granting all network permissions. This is a quick way to allow network requests. ```typescript import { createNodeDriver, allowAllNetwork } from "secure-exec"; const driver = createNodeDriver({ useDefaultNetwork: true, permissions: { ...allowAllNetwork }, }); ``` -------------------------------- ### Register timer handles Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/arch/active-handles.md Example of registering and unregistering a timer handle. ```javascript // setTimeout const handleId = `timer:${timerId}`; _registerHandle(handleId, `setTimeout: ${delay}ms`); // When timer fires or is cleared _unregisterHandle(handleId); ``` -------------------------------- ### TypeScript integration Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/sdk-overview.mdx Install and configure TypeScript tools for sandboxed type checking and compilation. ```bash pnpm add @secure-exec/typescript ``` ```ts import { createTypeScriptTools } from "@secure-exec/typescript"; const ts = createTypeScriptTools({ systemDriver: createNodeDriver(), runtimeDriverFactory: createNodeRuntimeDriverFactory(), }); ``` ```ts const result = await ts.typecheckSource({ sourceText: "const x: number = 'hello';", }); console.log(result.success); // false console.log(result.diagnostics[0].message); // "Type 'string' is not assignable to type 'number'." ``` ```ts const result = await ts.typecheckProject({ cwd: "/app", configFilePath: "/app/tsconfig.json", }); for (const d of result.diagnostics) { console.log(`${d.filePath}:${d.line} ${d.message}`); } ``` ```ts const result = await ts.compileSource({ sourceText: "const x: number = 42; export default x;", }); console.log(result.outputText); // "const x = 42; export default x;" ``` ```ts const result = await ts.compileProject({ cwd: "/app", }); console.log(result.emittedFiles); // ["/app/dist/index.js", ...] console.log(result.success); // true ``` -------------------------------- ### Configure filesystem Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/sdk-overview.mdx Initialize the filesystem driver with specific permissions. ```ts import { createNodeDriver, allowAllFs } from "secure-exec"; const driver = createNodeDriver({ permissions: { fs: allowAllFs }, }); ``` -------------------------------- ### Secure-Exec Consumer API - Simple Usage Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/arch/kernel-integration.md Demonstrates basic usage of the secure-exec API, including kernel creation with in-memory filesystem and permissions, mounting multiple runtimes (WasmVM, Node.js, Python), executing commands, and performing filesystem operations. ```typescript import { createKernel, createWasmVmRuntime, createNodeRuntime, createPythonRuntime } from 'secure-exec'; const kernel = createKernel({ filesystem: createInMemoryFileSystem(), permissions: allowAll, env: { HOME: '/home/user', PATH: '/bin:/usr/bin' }, }); // Mount the runtimes you need kernel.mount(createWasmVmRuntime()); kernel.mount(createNodeRuntime()); kernel.mount(createPythonRuntime()); // Execute commands (goes through brush-shell) const result = await kernel.exec('echo hello | grep hello'); console.log(result); // { exitCode: 0, stdout: 'hello\n', stderr: '' } // Cross-runtime pipelines await kernel.exec('ls -la | python -c "import sys; print(len(sys.stdin.readlines()))"'); // Direct process spawning const proc = kernel.spawn('node', ['-e', 'console.log(1+1)']); await proc.wait(); // Filesystem access await kernel.writeFile('/tmp/data.txt', 'hello world'); const data = await kernel.readFile('/tmp/data.txt'); // Cleanup await kernel.dispose(); ``` -------------------------------- ### GET /dev/fd Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/kernel/api-reference.mdx Access process-aware device paths for interacting with open file descriptors. ```APIDOC ## GET /dev/fd ### Description Provides access to process-aware device paths for interacting with open file descriptors by number. ### Methods - **devFdReadDir(pid)**: Returns a list of open FD numbers for a process. - **devFdStat(pid, fd)**: Returns a VirtualStat object for the file behind the specified FD. ### Request Example // List open FDs for a process const fds = ki.devFdReadDir(pid); ### Response - **fds** (string[]) - List of open file descriptor numbers. ``` -------------------------------- ### Initialize Node.js Filesystem Wrapper Source: https://github.com/rivet-dev/secure-exec/blob/main/docs/features/filesystem.mdx This snippet shows how to initialize the NodeFileSystem, which acts as a thin wrapper around Node.js's `fs/promises`. This backend provides access to the real host filesystem, but access is gated by the permissions configured in the runtime. ```typescript import { NodeFileSystem } from "secure-exec"; const fs = new NodeFileSystem(); ``` -------------------------------- ### Install xterm headless dependencies Source: https://github.com/rivet-dev/secure-exec/blob/main/docs-internal/specs/terminal-e2e-testing.md Add the required headless terminal dependency to the kernel and WasmVM packages. ```bash pnpm -F @secure-exec/kernel add -D @xterm/headless pnpm -F @anthropic-ai/wasmvm add -D @xterm/headless ```