Skip to content

Repository files navigation

sandbox

Cloudflare Sandbox SDK

npm version npm downloads

Run untrusted or generated code in a Linux sandbox that belongs to one user, task, or session. Your Worker decides who gets a sandbox, which hosts it can reach, and which credentials stay out of it.

A sandbox is a Durable Object and the Container it starts. The Durable Object starts the instance and runs commands with the Container API on this.ctx.container. @cloudflare/sandbox adds three things that API does not have:

  • Files streams files in and out of the running instance and reports Linux errors such as ENOENT.
  • S3Mount mounts an S3-compatible bucket at a path. Your Worker signs each storage request, so the credentials never enter the sandbox.
  • DirectoryBackup saves a directory to R2 and restores it into any Container, including one on a newer image. The Container reaches only the one object each operation needs.

Read the documentation

Try it

Create a project from the minimal template, or deploy it directly:

npm create cloudflare@latest -- my-sandbox --template=cloudflare/sandbox-sdk/examples/minimal

Deploy to Cloudflare

The template gives each name in the URL its own sandbox. At its core is a Durable Object like this one:

import { Files } from "@cloudflare/sandbox";
import { DurableObject } from "cloudflare:workers";

export class Sandbox extends DurableObject<Env> {
  async run(script: string) {
    const container = this.ctx.container;
    if (!container) throw new Error("The container binding is not configured");

    if (!container.running) {
      container.start({ image: container.images.sandbox, enableInternet: false });
    }

    const files = new Files(container);
    await files.writeFile("/workspace/task.sh", script);

    const process = await container.exec(["sh", "task.sh"], { cwd: "/workspace" });
    const { exitCode, stdout } = await process.output();
    return { exitCode, stdout: new TextDecoder().decode(stdout) };
  }
}

export default {
  async fetch(request, env) {
    // Authenticate the request, then choose the sandbox for this user or task.
    const sandbox = env.SANDBOX.getByName("user-123");
    return Response.json(await sandbox.run(await request.text()));
  },
} satisfies ExportedHandler<Env>;

The image needs the helper that Files runs, and the Worker needs nodejs_compat. Refer to Requirements.

What you can build

Goal Guide Example
Run a script and read its output Execute commands workspace
Keep a server or build running Run background processes process-workspace
Open a shell in the browser Open a terminal in the browser terminal-workspace
Process files from a bucket Mount an R2 bucket artifact-workspace
Save a workspace and resume it later Save and restore a sandbox checkpoint-workspace, backup-workspace
Preview a web app while you edit it Preview a web application preview-workspace
Share a port on its own URL Serve previews on their own hostnames share-workspace
Choose which hosts a sandbox can reach Control network access outbound-workspace
Run a coding agent on a repository Coding agents coding-agents, devin, openai/agents-api

To run JavaScript or Python without a Linux environment, use Dynamic Workers instead.

Coming from 0.x

Version 0.x provided a Sandbox class that owned the Container and ran commands for you. In 1.0, your own Durable Object starts the Container, and this package provides only file operations and bucket mounts. The migration guide maps each 0.x API to its replacement. The 0.x source is on the v0 branch.

Repository

Path Contents
packages/sandbox The @cloudflare/sandbox package
crates/sandbox-tools sandbox-shim, the Linux helper that Files, S3Mount, and DirectoryBackup run
images/sandbox-tools The cloudflare/sandbox image that ships sandbox-shim
examples Deployable Workers, one per goal

To learn how these parts fit together, read Architecture. The package and sandbox-shim exchange frames described in Shim protocol. S3 mounts design explains S3Mount and S3Gateway. To add an example, read Examples.

Build and test with Node.js and Docker:

npm install
npm run check
npm test

Testing explains what these commands check, how to build behind a TLS-inspecting proxy, and how to test in production. Releasing explains how maintainers publish the package and its image.

License

Apache License 2.0

About

Run sandboxed code environments on Cloudflare's edge network

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1.1k stars

Watchers

8 watching

Forks

Releases

Used by

Contributors

Languages