Give your coding agents a cloud sandbox
RWX sandboxes let you execute code in isolated cloud environments—useful for running complex setups or testing untrusted AI-generated code. While sandboxes work great for any developer workflow, they're particularly well-suited for coding agents.
Why sandboxes work well for agents
The same properties that make RWX fast and ergonomic for developers (content-based caching, file syncing, reproducible environments) happen to be exactly what coding agents need too.
The sandbox model keeps your agent running locally while offloading execution to the cloud. This "agent outside" approach gives you:
- Full local control: Your agent runs on your machine, with your configuration, your tools, and your oversight
- Fast cloud execution: RWX's content-based caching means sandbox environments spin up in seconds, not minutes
- Reproducible environments: The same run definitions you use for CI work for sandboxes, so your agent tests against the same environment as your pipelines
This tight feedback loop between local development and cloud execution is central to how RWX tooling works—sandboxes just extend that pattern to agent workflows.
Getting started
1. Initialize a Sandbox Configuration
rwx sandbox init
This creates .rwx/sandbox.yml with a starter template. Customize it for your project's environment—the same task definitions you'd use for CI work here.
A minimal sandbox configuration looks like this:
on:
cli:
init:
commit-sha: ${{ event.git.sha }}
base:
image: ubuntu:26.04
config: rwx/base 1.2.1
tasks:
- key: code
call: git/clone 2.4.0
with:
preserve-git-dir: true
repository: https://github.com/your-org/your-repo.git
ref: ${{ init.commit-sha }}
github-token: ${{ github.token }}
- key: sandbox
use: code
run: rwx-sandbox
A more complex example with language dependencies and background processes can be seen below.
2. Execute commands in the sandbox
rwx sandbox exec -- npm test
Your local changes are automatically synced up to the sandbox before execution, and synced back down after execution. The sandbox persists between commands, so subsequent calls reuse the same environment.
Working with coding agents
Parallel agents with git worktrees
Sandboxes are uniquely identified by git branch and the absolute path to the config file. This means agents running in separate git worktrees automatically get isolated sandboxes:
repo/ → sandbox A
repo-worktree-1/ → sandbox B
repo-worktree-2/ → sandbox C
Each agent can execute commands in its own sandbox without interference. This also works seamlessly with worktrees created natively within coding agents like Claude Code or Codex.
Preview changes
With an active sandbox, start a managed background process, such as a development server, and forward its port to a local URL:
rwx sandbox background --key web --port 3000 -- npm run dev
The command syncs local changes, starts a managed process with the key web, forwards port 3000 from the sandbox, and prints a preview URL. It returns after the port is ready while the server continues running in the sandbox. Open the URL on the machine running the CLI to preview your changes.
Local changes sync before every rwx sandbox exec. To sync without running a command, use rwx sandbox push.
If the development server needs a restart to pick up changes, use rwx sandbox background restart. This syncs local changes before restarting the original command and reuses its local port if available:
rwx sandbox background restart --key web
Inspect the process output or follow it as the server runs:
rwx sandbox background logs --key web
rwx sandbox background logs --key web --follow
When you are finished with the preview, stop the process and its local port forward:
rwx sandbox background stop --key web
Starting another background command with the same key replaces the existing managed process. You can run multiple previews or supporting processes at once by giving each one a different key.
If you started the sandbox from a custom config file, pass that path to each command, or use --id <run-id>. For example, for a sandbox started from .rwx/preview.yml:
rwx sandbox background .rwx/preview.yml --key web --port 3000 -- npm run dev
rwx sandbox push .rwx/preview.yml
rwx sandbox background restart .rwx/preview.yml --key web
Preview a configured background process
If your development server is already declared in the sandbox task's background-processes, use its configured key to open a tunnel without restarting it. For example, a sandbox task that uses your installed dependencies could declare:
- key: sandbox
use: npm-install
background-processes:
- key: web
run: npm run dev
run: rwx-sandbox
After starting the sandbox, forward the server's port:
rwx sandbox tunnel --key web --port 3000
rwx sandbox tunnel waits for the port to accept connections and prints a local URL. It does not sync files. You can also use it to expose a process started earlier with rwx sandbox background without --port.
The same background logs, background restart, and background stop commands work with configured process keys. After restarting a configured process, run rwx sandbox tunnel again to reopen its tunnel.
Pre-warming sandboxes
For environments with complex startup (background services, large dependencies), pre-start the sandbox:
rwx sandbox start --wait
Most of the time, lazy startup is fast enough thanks to content-based caching—but pre-warming can help when you need the environment immediately available.
Managing sandboxes
List all running sandboxes:
rwx sandbox list
Stop the current sandbox:
rwx sandbox stop
Stop all sandboxes:
rwx sandbox stop --all
Reset to a fresh state (discarding any changes):
rwx sandbox reset
Sandboxes automatically stop after 30 minutes of inactivity, but the rwx-sandbox directive in the sandbox.yml file supports the following flags for customizing the timeout:
| Flag | Default | Description |
|---|---|---|
--first-exec-timeout | 30m | How long to wait for the first rwx sandbox exec before stopping the sandbox |
--inactivity-timeout | 30m | How long the sandbox stays alive without activity before stopping |
Timeouts are specified as durations like 5m or 1h.
Example with language dependencies and background processes
Below is a more complete/realistic example of a sandbox.yml file that includes language dependencies and background processes.
on:
cli:
init:
commit-sha: ${{ event.git.sha }}
base:
image: ubuntu:26.04
config: rwx/base 1.2.1
tasks:
- key: code
call: git/clone 2.4.0
with:
preserve-git-dir: true
repository: https://github.com/your-org/your-repo.git
ref: ${{ init.commit-sha }}
github-token: ${{ github.token }}
- key: tool-versions
use: code
call: rwx/tool-versions 1.1.0
filter:
- .tool-versions
- key: node
call: nodejs/install 1.2.1
with:
node-version: ${{ tasks.tool-versions.values.node }}
- key: npm-install
use: [code, node]
run: npm install
filter:
- package.json
- package-lock.json
- key: docker-images
use: code
docker: preserve-data
run: docker compose pull
filter:
- docker-compose.yml
- key: sandbox
use: [code, docker-images, npm-install]
docker: true
background-processes:
- key: start-databases
run: docker compose up
ready-check: rwx-docker-ready-check
run: |
npm run migrate
rwx-sandbox
For more complex setups, reference the CI workflow guide.
Next steps
- Sandbox CLI Reference — Full command documentation
- CI Reference Workflow — Patterns for environment setup that apply to sandboxes
- Content-Based Caching — How RWX achieves fast startup times