When to use this recipe
- Running snippets an LLM produced as part of a tool-use loop.
- Evaluating user-submitted answers in a coding interview or learning product.
- Sandboxing third-party plugins or untrusted webhook payloads that happen to contain code.
- A “scratch interpreter” backend for an internal tool.
Prerequisites
- A Brimble account with API access enabled (paid plan, API key from the profile drawer).
- The TypeScript, Python, or Go SDK installed (see SDKs).
BRIMBLE_SANDBOX_KEYset in your environment.
Recipe
The key options here areblockOutbound: true (no outbound network), oneShot: true (auto-destroy when the main process exits), and a tight timeout_seconds on the exec call. Together they give you a single-use, networkless, time-bounded executor.
What’s happening
createReadyovercreate. We block until the sandbox isready, so the next call doesn’t need to coordinate the wait.blockOutbound: true. Outbound network is denied. The sandbox can’tcurlexternal services, exfiltrate data, or pivot. Inbound calls from the Brimble API (your exec, your file ops) still work.oneShot: true. When the main process exits, the sandbox auto-destroys. You don’t have to remember to clean up.destroyTimeout: "30m". A backstop: even ifoneShotmisfires (the process never returns, hangs in a loop), the sandbox is gone after 30 minutes.- Small
specs. 0.5 vCPU equivalent, 512 MB memory, 2 GB ephemeral disk. Pick a size that matches the work; the sandbox is hard-capped at these limits. timeout_seconds: 30. Wall-clock cap on the exec itself. The process is killed at the limit and you get a non-zero exit code.try/finallyplusdestroy. Belt and suspenders. TheoneShotflag should already handle cleanup, but if the SDK call itself fails before the process can exit, the explicitdestroyensures we don’t leave an idle sandbox running.
Variations
- Use
runCodewithlanguage: "node"for JavaScript snippets. Pick a Node-friendly template likenode-22. - Capture larger output by lifting
timeout_secondsand increasingspecs.memoryandspecs.disk. The exec result is fully buffered; very large stdout streams should be written to a file inside the sandbox and downloaded withgetFileinstead. - Reuse a sandbox for many calls by dropping
oneShot: trueand callingrunCoderepeatedly. Cheaper per-call (no provisioning latency) but you’re responsible for cleanup. - Provide read-only inputs by pre-uploading files with
putFilebefore therunCodecall. The snippet can read them at known paths. - Surface failures cleanly by mapping non-zero
exit_codeto your own error type. Non-zero doesn’t throw, the SDK returns a normal result with the exit code and stderr.
Next steps
- Sandboxes overview, the lifecycle and billing model.
- Run an AI coding agent, the same untrusted-code idea scaled up to a multi-step agent loop.
- Persistent dev environment, the opposite end of the spectrum: long-lived, stateful sandboxes.