Vercel Eve Sandbox Backend: Run Eve Agents on Sandbox0
Vercel Eve is a new agent framework, but one of its most important infrastructure choices is already clear: the sandbox backend is an adapter.
In Vercel's own launch post, Eve treats agent-generated code as untrusted. The agent runtime stays outside the sandbox, while every agent gets an isolated environment for shell commands, scripts, file reads, and file writes. The default hosted path uses Vercel Sandbox, local development can fall back to Docker, microsandbox, or just-bash, and Eve exposes a public backend shape for other providers.
That is exactly where Sandbox0's Vercel Eve integration fits.
Use @sandbox0/eve when you want Eve's agent model, channels, skills, tools, schedules, and durable session orchestration, but want sandbox execution to run on Sandbox0.
The short version:
bashnpm install eve sandbox0 @sandbox0/eve
Then configure Eve's agent/sandbox/sandbox.ts with sandbox0():
typescriptimport { defineSandbox } from "eve/sandbox"; import { sandbox0 } from "@sandbox0/eve"; export default defineSandbox({ backend: sandbox0({ template: process.env.SANDBOX0_TEMPLATE ?? "default", networkPolicy: "allow-all", }), revalidationKey: () => "sandbox0-eve-v1", async bootstrap({ use }) { const sandbox = await use(); await sandbox.run({ command: "python --version" }); }, async onSession({ use }) { await use({ networkPolicy: "allow-all" }); }, });
This post explains what that adapter does, what parts of Eve it does not replace, and how the lifecycle maps to Sandbox0 primitives.
What Eve Expects From A Sandbox Backend#
Eve's sandbox is the execution environment for filesystem and shell work. The agent and authored tools run in the application runtime; sandbox tools operate against a /workspace filesystem and a command runner.
The public sandbox handle includes the operations an agent framework usually needs:
| Operation | Purpose |
|---|---|
run() | Execute one command and wait for stdout, stderr, and exit code |
spawn() | Start a long-running process such as a server or watcher |
readFile() and writeFile() | Stream bytes in and out |
readTextFile() and writeTextFile() | Read and write text files |
readBinaryFile() and writeBinaryFile() | Read and write binary files |
removePath() | Delete files or directories |
resolvePath() | Anchor relative paths under /workspace |
setNetworkPolicy() | Change the sandbox egress policy at runtime |
Eve then wraps those session operations in a backend lifecycle:
prewarm()prepares reusable template state from bootstrap code and seed files.create()starts or reattaches a live sandbox session.captureState()stores enough metadata for a later turn to reconnect.dispose()releases the backend handle according to the backend policy.
The important product decision is that Eve does not require every backend to be Vercel Sandbox. A backend can point at another container runner, VM pool, sandbox service, or isolation layer as long as it returns the Eve session operations.
@sandbox0/eve implements that backend surface for Sandbox0.
Install And Environment Variables#
Eve 0.11.x requires Node.js 24 or newer. Add Eve, the Sandbox0 JavaScript SDK, and the Eve adapter:
bashnpm install eve sandbox0 @sandbox0/eve
Set Sandbox0 credentials in the runtime that starts the Eve app:
bashSANDBOX0_TOKEN=s0_... SANDBOX0_BASE_URL=https://api.sandbox0.ai SANDBOX0_TEMPLATE=default
SANDBOX0_BASE_URL can point at Sandbox0 Cloud or a private regional gateway. The adapter reads SANDBOX0_TOKEN or SANDBOX0_API_KEY by default, and uses SANDBOX0_BASE_URL when provided.
The default hosted Sandbox0 template includes Bash and /workspace, which is the contract Eve expects for seed files and file tools. If you use a custom template, keep /workspace available.
How Prewarm Maps To Rootfs Snapshots#
Eve uses prewarm to avoid repeating template setup for every session.
With Sandbox0, prewarm becomes a rootfs snapshot workflow:
The adapter claims a Sandbox0 sandbox from the configured template, runs Eve's bootstrap hook, writes seed files from agent/sandbox/workspace/, pauses the sandbox, and creates a Sandbox0 rootfs snapshot.
That pause step is not incidental. Sandbox0 rootfs snapshots are created from paused sandboxes so the writable filesystem has a stable checkpoint. The adapter handles the pause and polling before creating the snapshot.
After the snapshot is created, the adapter stores the mapping from Eve templateKey to Sandbox0 snapshotId under .eve/sandbox0/. Later, when Eve calls create() with the same templateKey, the adapter claims a fresh Sandbox0 sandbox using that snapshot ID.
This is the same underlying pattern as Initialize Once, Claim Many: prepare filesystem state once, snapshot it, and start later sandboxes from that known state without creating a new template for every dependency set.
How Runtime Sessions Resume#
Prewarm sandboxes and live session sandboxes are different.
The prewarm sandbox exists to build reusable template state. A live session sandbox is the sandbox attached to an Eve durable session.
When Eve creates a live session, the Sandbox0 adapter returns a handle whose captureState() stores the live Sandbox0 sandboxId in Eve's backend metadata:
json{ "backendName": "sandbox0", "metadata": { "sandboxId": "sb_..." }, "sessionKey": "session_..." }
On a later turn, Eve can pass that metadata back. The adapter then checks the sandbox:
| Sandbox0 state | Adapter behavior |
|---|---|
| Running | Reopens the same sandbox handle |
| Paused | Resumes the sandbox first, then opens the handle |
| Missing | Claims from the prewarmed snapshot if it is still registered; otherwise Eve must prewarm again |
This is why the article should not describe the adapter as merely a command runner. It bridges Eve's durable session metadata to Sandbox0's sandbox identity, pause/resume, file APIs, and process APIs.
Also keep the pause semantics precise: pause preserves the sandbox identity and writable rootfs checkpoint, but it does not preserve running processes, memory, sockets, PID state, or live REPL sessions. A resumed sandbox is a new runtime generation restored from filesystem state.
What File And Command Calls Do#
@sandbox0/eve maps Eve session calls to Sandbox0 SDK operations.
Commands run through Sandbox0 context streams using Bash:
typescriptawait sandbox.run({ command: "npm test", workingDirectory: "/workspace/repo", env: { CI: "true" }, });
Relative paths resolve under /workspace:
typescriptawait sandbox.writeTextFile({ path: "scripts/check.py", content: "print('ok')\n", }); const output = await sandbox.readTextFile({ path: "scripts/check.py", });
The adapter creates parent directories before writing nested files. For missing reads, it returns null, matching Eve's expected missing-file behavior. removePath() honors force for missing paths and requires recursive: true before deleting directories.
These details matter because the Eve sandbox surface is shared by framework-owned tools and authored code. An Eve tool that expects /workspace/foo.txt should see the same path behavior whether the backend is local, Vercel Sandbox, or Sandbox0.
Network Policy Mapping#
The Sandbox0 Eve adapter supports Eve's basic network policy forms:
| Eve policy | Sandbox0 behavior |
|---|---|
"allow-all" | Sandbox0 allow-all network mode |
"deny-all" | Sandbox0 block-all network mode |
| domain allow rules | block by default, then allow matching HTTP/TLS domains |
| subnet allow or deny rules | block by default, then apply CIDR rules |
For example:
typescriptexport default defineSandbox({ backend: sandbox0({ template: "default", networkPolicy: { allow: ["github.com", "registry.npmjs.org"], subnets: { deny: ["10.0.0.0/8"], }, }, }), });
There is one important boundary: Vercel-specific transform and forwardURL rules are rejected by the Sandbox0 adapter.
That is intentional. Sandbox0's credential model should not be reduced to raw header rewriting in the Eve adapter. Use Sandbox0 credential sources and egress auth when you want Sandbox0-native credential injection. That keeps the secret boundary in the platform layer instead of treating Eve network policy transforms as generic Sandbox0 credentials.
What This Integration Does Not Replace#
The adapter is intentionally scoped.
It does not replace:
- Eve's agent definition
- Eve prompts or instructions
- Eve tools, skills, channels, schedules, or subagents
- Vercel Connect behavior
- Eve's durable workflow orchestration
- every Vercel Sandbox platform feature
It replaces the sandbox backend used for command execution, file I/O, prewarm state capture, session sandbox reuse, and supported network policy translation.
That distinction is important for both architecture and migration planning. An Eve app is still an Eve app. @sandbox0/eve changes where the sandbox execution boundary lives.
When Sandbox0 Is A Good Eve Backend#
Sandbox0 is a good fit when the team wants Eve's application model but needs stronger control over the sandbox substrate.
Common reasons:
- you want a Sandbox0 regional gateway or private deployment behind the Eve app
- you want Sandbox0 templates and warm pools to own the execution runtime
- you want prewarm state captured as Sandbox0 rootfs snapshots
- you want live Eve sessions to map to Sandbox0 sandbox identities
- you want pause/resume and hard TTLs around session sandboxes
- you want Sandbox0 network policy and Sandbox0-native egress auth paths
- you want the same backend shape from Vercel-hosted or non-Vercel Node runtimes
For long-lived app data that should outlive one sandbox identity, use Sandbox0 Volumes. The default Eve lifecycle does not require Volumes because template state is captured with rootfs snapshots and live session state is tied to the session sandbox. Volumes are still the right primitive for shared workspaces, externally managed durable data, direct Volume file APIs, and data that must survive sandbox deletion.
Production Notes#
Before serving traffic, run Eve's build or prewarm flow so the .eve/sandbox0/ template registry exists. If the registry is missing for a prewarmed template, the adapter raises a template-not-provisioned error instead of guessing.
For prewarm sandboxes, the adapter applies a one hour hard TTL by default after snapshot creation. You can keep the paused prewarm sandbox briefly for inspection, delete it after snapshot capture, or change the hard TTL:
typescriptexport default defineSandbox({ backend: sandbox0({ template: "default", prewarmSandboxHardTtlSec: 3600, deletePrewarmSandbox: false, }), });
For live session sandboxes, choose TTLs based on your application. Eve durable sessions and Sandbox0 sandbox state are related, but they are not the same object. The Eve session is the agent-level workflow. The Sandbox0 sandbox is the execution environment attached to that workflow.
Use a dedicated Sandbox0 API key for the Eve deployment, keep /workspace available in custom templates, and delete stale .eve/sandbox0/ registry files when you intentionally remove the corresponding Sandbox0 rootfs snapshots.
The Takeaway#
Vercel Eve makes the agent framework and the sandbox backend separable.
That is the opening @sandbox0/eve uses. Eve keeps its filesystem-first agent structure, tools, channels, and durable session model. Sandbox0 provides the sandbox backend for command execution, file I/O, rootfs snapshot prewarm, pause/resume-backed session reuse, and supported network policy controls.
If you are building with Vercel Eve and want the sandbox backend to run on Sandbox0, start with the integration guide: