Skip to main content
Features

Secure Code Execution

Run untrusted, AI-generated code inside a lightweight VM that lives in a Rivet Actor.

Agents write code, and that code should not run in your process. An Actor can boot a lightweight VM with its own filesystem, shell, and JavaScript and Python runtimes, and run the code there. The VM boots in milliseconds inside the Actor’s process, so there is no separate sandbox service to deploy. The VM is powered by agentOS.

There are two ways to use it:

  • A VM per Actor. The VM lives as long as the Actor, so an agent session keeps its files and processes between runs.
  • A temporary VM. Boot a VM for one evaluation and release it when the call ends.

Quickstart

Install

npm install @rivet-dev/agentos-core

Create a VM per Actor

Boot the VM in createVars and dispose it when the Actor sleeps.

import { actor, setup } from "rivetkit";
import { AgentOs } from "@rivet-dev/agentos-core";

export const sandbox = actor({
  // One VM per Actor. It boots with the Actor and is released
  // when the Actor sleeps.
  createVars: async () => ({ vm: await AgentOs.create() }),
  onSleep: async (c) => {
    await c.vars.vm.dispose();
  },
  onDestroy: async (c) => {
    await c.vars.vm.dispose();
  },

  actions: {
    // `code` came from a model. It runs in the VM,
    // not in your process.
    run: async (c, code: string) => {
      const result = await c.vars.vm.javascript.evaluate(code);
      if (result.outcome !== "succeeded") {
        throw new Error(result.error.message);
      }
      return result.value;
    },
  },
});

export const registry = setup({
  use: { sandbox },
});

Run code from a client

import { createClient } from "rivetkit/client";
import type { registry } from "./actor";

const client = createClient<typeof registry>("http://localhost:8080");

// One Actor per agent session, so each session has its own VM.
const sandbox = client.sandbox.getOrCreate(["session-123"]);

const value = await sandbox.run("[1, 2, 3].map((n) => n * 2)");
console.log(value); // [2, 4, 6]

Evaluate code in a temporary VM

When the code has no state to keep, boot a VM for the one call and dispose it in finally.

import { actor } from "rivetkit";
import { AgentOs } from "@rivet-dev/agentos-core";

export const evaluator = actor({
  actions: {
    // Boot a fresh VM for this call and release it at the end.
    evaluate: async (c, code: string) => {
      const vm = await AgentOs.create();
      try {
        const result = await vm.javascript.evaluate(code);
        if (result.outcome !== "succeeded") {
          throw new Error(result.error.message);
        }
        return result.value;
      } finally {
        await vm.dispose();
      }
    },
  },
});

What the VM can do

The actions below belong to the same Actor as the quickstart and use its c.vars.vm.

Shell

Run a command in the VM and read its output. See Bash and Processes for background processes and interactive shells.

exec: async (c, command: string) => {
  const result = await c.vars.vm.process.exec(command);
  return result.stdout;
},

Files

The VM has a POSIX filesystem. Files the agent writes stay in that Actor’s VM. See Filesystem for directories, batch writes, and mounts.

writeFile: async (c, path: string, contents: string) => {
  await c.vars.vm.filesystem.writeFile(path, contents);
},
readFile: async (c, path: string) => {
  const bytes = await c.vars.vm.filesystem.readFile(path);
  return new TextDecoder().decode(bytes);
},

JavaScript and Python

evaluate() returns the value of an expression, as in the quickstart. execute() runs a program and captures its output. Both are available for JavaScript and Python.

python: async (c, code: string) => {
  const result = await c.vars.vm.python.execute(code);
  return result.stdout;
},

More

  • Networking: run servers inside the VM and reach them from the Actor.
  • Software: install packages and tools into the VM.
  • Schedules: run commands in the VM on a cron schedule.
  • Permissions and resource limits: control network access and cap CPU, memory, processes, and filesystem size.

Persistence

The VM’s filesystem is in memory and is released with the VM. Keep anything that must outlive a wake cycle in the Actor’s state or SQLite, or store the VM’s filesystem durably with agentOS persistence.

Next steps