Sandbox Providers
Code the agent runs (execute, and skill scripts) runs in a sandbox. The
provider decides where; everything else — governance, the workspace bridge,
telemetry, your credentials — stays the same and stays in your process.
Each hosted provider needs its own credentials in the environment (for
example
modal token new, E2B_API_KEY, DAYTONA_API_KEY, VERCEL_TOKEN).
Those credentials stay in your process: they are never put inside a sandbox.
A sandbox that dies is reported, not retried blindly
Every provider can lose a sandbox under a run — E2B reports one that died mid-command as a timeout, and a sandbox’s lifetime (timeout_seconds) ends
whatever it is doing. The adapter tells a lost sandbox from a slow command,
the run drops that session, the model is told what happened, and the next
command opens a fresh sandbox. The trace records the session closed as
lost; the Execution page has the details.
A sandbox with no network is checked, not trusted
A sandbox that must have no network is checked from the inside, once, when it is created: it tries one outbound connection, and a sandbox that reaches the internet is destroyed and refused with an error. This is not hypothetical — E2B and Daytona both accept “no internet”, report it back, and on the accounts this was tested against still hand back a sandbox that reaches the internet. A promise of isolation the provider does not keep is worse than no sandbox, because a policy may be allowing the work only because it is isolated. The check needspython in the image; an image without one is refused for the
same reason (it cannot be shown to be isolated). If you know your provider and
accept the risk, turn the check off per provider:
network_isolation: "unchecked" instead of
"checked", and a manifest that allows the network records "not required".
Common options: image, max_output_bytes, and timeout_seconds. Docker
adds user, workdir_size, pids_limit, runtime ("runsc" for gVisor)
and pull; see Security Model.
What each run’s sandbox is
sandbox_config says which provider runs the sandbox; sandbox_manifest
says what the sandbox is — its network, image, working directory, resources
and plain environment. Without one, a run’s sandbox has no network, the
provider’s default image, and /workspace as its working directory.
sandbox.network.configure, an image is sandbox.image.use, a plain
environment is sandbox.environment.set: the development profiles ask a
person before the network goes on (the run pauses on that approval like any
other, see Durable Runs), and
strict-production allows none of them without a rule. A manifest that
cannot be read — an unknown field, a provider or session of its own — is
refused when the agent is built.
Your own sandbox service (http)
For anything without a native adapter — a Cloudflare Worker using
Cloudflare’s Sandbox SDK, a service inside your own network — run a small
service and point the agent at it:
Your service is responsible for the isolation it promises: the manifest says
what network policy the run expects, and a service that cannot honour it
should refuse the session. Only the plain environment is sent; secret
references stay in the harness.
Writing another provider
register_sandbox_provider("name", factory) adds a provider of your own; it
then works anywhere a provider name does (bring your own sandbox).