Skip to content
Sandbox SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Security

What Sandbox SDK protects and what it leaves to the provider. Trust boundaries, keys, secret redaction, network policy, agent tool limits, previews, and reporting a vulnerability.

Sandbox SDK is a library over each provider’s API. It does not add an isolation layer of its own. The provider you choose supplies the security boundary, its authentication, its network controls, and how it hardens the machine. Read this page before you run code from users or models.

Trust boundaries

Boundary Who provides it
Isolation between the sandbox and your servers The provider: a microVM on E2B and Vercel Sandbox, Daytona’s sandbox, a Docker container on Local
Isolation between sandboxes The provider
Who may create and reach sandboxes Your provider credentials
Which user may use which sandbox Your app
Outbound network The provider, when you set network

Local is a container, not a VM. Containers share the host kernel. Don’t run untrusted code from strangers with local() on a machine that holds secrets. Use a cloud provider for that.

Memory is not a sandbox. Handlers run in your process with your process’s privileges. Use it only for tests.

Keys stay on the server

Provider factories read credentials from their arguments or the provider’s own environment variables. Call the SDK from server code only, and never import a provider in a browser bundle. Sandbox SDK adds no telemetry and sends nothing anywhere except to the provider you configured.

Secrets

Values you pass as secrets to createSandbox become environment variables in the sandbox. The SDK redacts them from every command result, log page, tool result, and error message it returns. connectSandbox reads the secret names back from the sandbox before the first command or file call and redacts them again.

Redaction has limits:

  • Code in the sandbox can read its own environment and send a secret anywhere the network allows. Pair secrets with a network policy.
  • Raw box.files.read is not redacted. The agent tools’ read_file is.
  • A secret that a program transforms, for example base64-encoded, no longer matches and isn’t redacted.

Use env for values that are safe to show and secrets for everything else.

Errors don’t leak credentials

SandboxError.cause is a redacted string, never the provider’s error object, because native errors can carry credentials in their fields. Response text never appears. A failure the adapter doesn’t recognize, such as a TypeError inside the provider’s SDK, keeps its name and message, with URLs, auth headers, credential-looking values, the provider’s API key, and your secrets replaced by [REDACTED]. See Causes. Still, treat message and cause as internal: log them, and show users the code and hint.

To write a file only its owner can read, pass mode: box.files.write(".env", text, { mode: 0o600 }). On providers without native modes the SDK runs chmod right after the write, so the file is briefly readable with default permissions. Put secret files in a directory only the sandbox user can enter, such as one made with mkdir -m 700.

Network policy fails closed

network: "none" and network: { allow: [...] } are enforced by the provider. If the provider can’t enforce what you asked, createSandbox throws unsupported instead of creating an open sandbox. E2B goes further: it reads the settings back after creation and destroys the sandbox if they don’t match.

Host allow lists are only as precise as the provider’s filter. E2B matches on the HTTP Host header and TLS SNI and leaves DNS open, for example. Check the provider’s documentation before you rely on a list to contain sensitive data.

Agent tools

sandboxTools options narrow what a model can do. They are conveniences, not a security boundary:

  • root keeps file paths and working directories the model passes inside one directory. A shell command can still cd out or use an absolute path.
  • allow and deny decide which tools exist.
  • beforeRun sees every run and start_process command and can refuse or rewrite it. Matching strings is easy to get around, so treat it as a guard against mistakes, not against an attacker.

The sandbox and its network policy are the real boundary. Assume anything the model can run, it will eventually run.

Previews

A public preview URL is reachable by anyone who has it. Don’t put secrets in a preview app, and don’t share the URL beyond the user it belongs to. A private preview needs the header from preview.headers. Keep that header on your server and proxy the preview. Local previews bind to 127.0.0.1 on the Docker host. The Preview URL row of the capability matrix says which providers give public URLs and which need a header.

Snapshots

A snapshot captures the file system, and on E2B the memory. It doesn’t remove secrets written to disk or environment variables baked into the image. Treat snapshot IDs as sensitive.

Your app’s job

The SDK doesn’t validate user code, block malicious commands, scan files, rotate credentials, enforce quotas, or decide which user owns which sandbox. Derive sandbox keys from the authenticated user, rate-limit sandbox creation, set lifetime limits, and run a reaper.

Report a vulnerability

Email security@opencore.dev with a minimal reproduction, the affected version, and the impact. Don’t open a public issue before coordinated disclosure, and don’t include production credentials, customer data, file contents, or full authenticated preview URLs.

Was this page helpful?