The checklist
Work down this list before putting an agent that drives sandboxes into production. Each row links to the section that explains it, so this doubles as the page outline.A production skeleton
The most concise and stable production skeleton: aSimpleBox with resources
and strong isolation configured, cleaned up automatically by async with.
The example above uses theSimpleBox“lazy box creation” path. If you need finer-grained options across multiple sandboxes (strong isolation, volumes, secrets, etc.), use the runtimeBoxlite+BoxOptionsdirectly (see the concurrency and security sections below).
Concurrency model
Two modes; choose based on your isolation needs. Choosing between the two modes:Mode A: one sandbox, many execs (recommended default)
A single sandbox can carry manyexec() calls; each exec spawns a new process
inside the same VM. The VM startup cost is paid once, and the VM boundary itself
already provides hardware isolation from the host. This fits the vast majority
of agent scenarios.
Note: when called through the wrapper,runtime.create(...)returns a nativeBox(an async context manager). Here we obtain the box viaawait runtime.create(...)and then stop/remove it manually. The native signature ofbox.exec(...)takesargs: listas its second argument, and its timeout parameter istimeout_secs(unlike the high-levelSimpleBox.exec’stimeout).
Mode B: one sandbox per agent / task
When you need strong cross-tenant isolation, different images, or independent resource ceilings, give each task its own sandbox.Timeouts and zombie-process protection
asyncio.wait_for() only cancels the Python coroutine; it does not kill the
process inside the sandbox --- the process keeps running inside the VM. The two
correct approaches follow.
Approach 1 (recommended): use SimpleBox.exec(timeout=...)
The high-level SimpleBox.exec has a built-in timeout (float, seconds). On
timeout, BoxLite terminates the process on the sandbox side via signal, leaving
no stray process.
Key point: aSimpleBox.exectimeout does not raiseTimeoutError--- it returns anExecResultwhoseexit_codeis negative (the process is terminated bySIGTERM, soexit_code == -15). Always checkresult.exit_code; do not useexcept TimeoutError.
Approach 2: manual wait_for + kill() (native Execution)
When you use the native box.exec(...) directly to obtain an Execution, you
must call kill() explicitly in the timeout branch.
Resource ceilings
Set hard ceilings on a sandbox via theBoxOptions / SimpleBox constructor
parameters to prevent a runaway agent from exhausting host resources.
Resource defaults: whenChoose a configuration by workload (the following are suggested starting points; adjust as needed):cpus/memory_mibare not passed, the underlying engine allocates a default. To inspect the actual resources inside a box, usenproc//proc/meminfo. For predictability and cost control, set them explicitly in production. See Compute Resources.
Observe runtime resource usage
Use the runtime-levelmetrics() for global metrics, noting the actual field
names. Although Boxlite is a synchronous context manager, metrics() is an
async method (requires await), so call it inside an async function.
Security: strong isolation
Security options are passed viaadvanced; there is no top-level
security= keyword. AdvancedBoxOptions is not exported at the top level and
must be imported from boxlite.boxlite.
Security presets
SecurityOptions has three preset static methods (there is no .minimum();
the weak preset is called development()):
You can also construct a custom one (keyword arguments):
In the Python bindings,network_enabledis currently a macOS-side control. On Linux, network isolation is typically achieved viaNetworkSpec(BoxOptions(network=...)) together with publishing no ports. To disconnect the network entirely, use it together withBoxOptions(network=NetworkSpec(...)); see Network Access.
Read-only volumes: the third element is a bool, not a string
When mounting data into a sandbox, use a read-only volume to prevent it from being overwritten. The third element of a volume is thebool read_only
(True = read-only / False = read-write), not the string "ro"/"rw"; a
2-tuple also works (default read-write).
Passing a string raises directly:TypeError: 'str' object cannot be cast as 'bool'(see Troubleshooting). The CLI’s-v host:box:rosyntax usesro/rwstrings and belongs to the CLI parsing layer --- it is different from the SDK’s bool, so do not confuse them.
Inject secrets (Secret / Vault entry point)
Do not write tokens in cleartext into commands or the environment; useBoxOptions(secrets=[Secret(...)]).
Cleanup: guarantee sandboxes are reclaimed
Boxes outlive the process that created them, so a hard kill leaves them running and holding disk and host ports. Recover from the command line:
List withruntime.list_info()(notlist()); it is an async method (requiresawait). Note the distinction:box.info()is a synchronous getter (do notawaitit), whereasruntime.list_info()/runtime.metrics()/runtime.remove()/runtime.create()/runtime.shutdown()are all async (requireawait).BoxInfo.stateis aBoxStateInfo, and the sandbox status string is ininfo.state.status.
File transfer (production patterns)
copy_in/copy_out for dynamic, per-request files;
read-only volumes for shared datasets; and inline base64 only for tiny payloads.
Troubleshooting
Passing a string for a volume -> TypeError: 'str' object cannot be cast as 'bool'
bool read_only: use True for read-only, False or
omit it (2-tuple) for read-write. The CLI’s :ro/:rw belongs to the CLI layer
syntax and is unrelated to the SDK API.
AttributeError: module 'boxlite' has no attribute 'AdvancedBoxOptions'
AdvancedBoxOptions lives in the boxlite.boxlite submodule, not the top level — import it from there:
advanced; there is no top-level
security=:
BoxOptions(advanced=AdvancedBoxOptions(security=SecurityOptions.maximum())).
See Also
- Lifecycle Management --- create / get / remove / shutdown
- Compute Resources --- cpus / memory_mib / disk_size_gb
- Volumes --- the read_only bool
- Network Access --- NetworkSpec and outbound control
- Secrets and Security --- Secret / SecurityOptions detail
- Run code in any language --- SimpleBox.exec
- Deploy in Docker or Kubernetes --- Docker / Kubernetes

