MainSDK
Search⌘K
How-to

Run untrusted code in a sandbox

Run a user's or an agent's code in an isolated sandbox with no network, a time and cost limit, files in and out, and an audit event per run.

Building for 0.4

Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.

Stability The promise an interface ships with.

  • Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
  • Beta Usable in production; may change before it becomes stable.
  • Experimental May change or go away; needs an explicit opt-in in main.yaml.
Stability levels
Updated 2026-10-28

You will run a Python snippet in a sandbox, pass a file in, read a file back and see a limit stop a run. It takes about 15 minutes. The code never runs in your app's process.

You need

  • A MainSDK app. For development the local driver needs python3. In production use vercel-sandbox or e2b.

1. Configure it

main.yaml
sandbox:
  driver: local
  local: { python: python3 }
  limits: { timeout: 30s, output: 1MB }
permissions:
  processes: [python3]
  disk: { temp: { max: 1GB } }

The local driver is refused in production (MAIN-SANDBOX-0011 from mainsdk check).

2. Run a snippet

lib/run-snippet.ts
import { sandbox } from "mainsdk";

export async function runSnippet(code: string) {
  const out = await sandbox.run({ code, language: "python", feature: "notebook" });
  return out.stop ? `stopped: ${out.stop}` : out.stdout;
}

A stopped run returns a result with stop set: timeout, memory, output or cost. It does not throw.

3. Pass files in and read results out

lib/chart.ts
import { sandbox } from "mainsdk";

export async function chart(csv: string) {
  const out = await sandbox.run({
    language: "python",
    feature: "chart",
    files: { "data.csv": csv },
    code: "rows = open('data.csv').read().splitlines()\nopen('../out/count.txt', 'w').write(str(len(rows)))",
  });
  return out.files;   // FileRefs for what the code wrote to the out folder
}

4. Give a run one host and one secret

lib/weather.ts
import { sandbox, secret } from "mainsdk";

export function weather(code: string) {
  return sandbox.run({
    code,
    language: "python",
    feature: "weather",
    network: ["pypi.org"],
    env: { WEATHER_KEY: secret("OPENWEATHER_KEY") },
  });
}

The host must be in sandbox.network and network.allow, and the secret under sandbox.secrets.

Check it worked

Call runSnippet('print(1 + 1)'): you get 2. Call it with while True: pass and a short timeout: you get stopped: timeout. Each run writes one audit event with the code's SHA-256, never the code or its output.

Troubleshooting

  • MAIN-SANDBOX-0005: a host is not in both sandbox.network and network.allow.
  • MAIN-SANDBOX-0009: a secret() names one that is not under sandbox.secrets.
  • MAIN-SANDBOX-0006: the provider is unavailable. Retry, and check the token.
  • isolation: "weak" on a result: the local driver without a Linux namespace. Use it only for development.

See the sandbox interface.

Was this page helpful?

↑↓ moveEnter openEsc close

Not decided yet