Quick Start
1
Isolate an explicit execute_code() call
Agent(sandbox=…) gives you the caller-invoked execute_code() API. It adds no tools and does not isolate tools= callables.2
Isolate everything the model runs
AgentFlow(run_on="docker") puts every step’s shell and file tools inside one shared container boundary, so model-driven tools route through the shared sandbox.Guarantee Matrix
Each surface below isolates a different thing — read the row before you rely on it.With the docker backend, cross-command filesystem state is provided:
write_file(), run_command(), and execute() share a /sandbox bind mount, so a file written by one is visible to the next. That mount does not expose the host filesystem (ls /Users fails), and code inside the container cannot swap a symlink into the mount to redirect the host’s write_file / read_file — both open descriptor-relative with O_NOFOLLOW at every path component. list_files() never returns host paths — even on platforms where TMPDIR sits behind a symlink (macOS /var → /private/var).Why sandbox= is not a capability grant
Agent(sandbox=…) is a restriction flag, not a way to hand the model an execution tool.
DockerSandbox is different — as of PR #4303 it does enforce the command-level parts of SecurityPolicy on the host before Docker is invoked.- Enforced on docker:
blocked_commands,allowed_commands,blocked_paths,allowed_pathson everyrun_command();max_output_sizeon bothrun_command()andexecute(). - Not enforced on docker:
allow_subprocess— the container itself is the boundary that clause approximates on the host, so blockingshinside the container would refuse every command rather than harden it. - Not a substitute for the container: the container still bounds where code runs; policy enforcement is additional, not a replacement for the isolation boundary.
praisonai-sandbox must be installed to run any sandbox backend — pip install praisonaiagents alone is not enough. Install a backend, e.g. pip install "praisonai-sandbox[docker]".Reliability: no leaked containers
Two guarantees close the container-leak story end to end — a timed-out execution and an exitedrun_on= script both leave zero running containers.
Verified before/after:
See Reclaim Stray Sandboxes for the full mechanism and Placement for how the leaks fit the placement story.
Common Patterns
- Explicit code execution
- Give the model a sandbox tool
- Whole-workflow container
Best Practices
Treat sandbox= as a restriction, not a grant
Treat sandbox= as a restriction, not a grant
Agent(sandbox=…) configures the explicit execute_code() API. It never hands the model a tool — add one yourself only when you intend the model to run code.Use a real container for untrusted or model-driven code
Use a real container for untrusted or model-driven code
The default subprocess backend is for trusted development only. For untrusted or model-driven execution, use
AgentFlow(run_on="docker"), LocalAgent(compute="docker"), or sandlock for a kernel-enforced local boundary.Remember autonomy= injects a host tool
Remember autonomy= injects a host tool
With
autonomy=True, the agent still carries the host execute_command tool. sandbox= does not protect that path — isolate the whole workflow with AgentFlow(run_on=…) instead.Install a sandbox backend first
Install a sandbox backend first
pip install praisonaiagents cannot execute any sandbox. Install praisonai-sandbox with the backend you need before relying on isolation.Related
Sandbox
Configure the explicit
execute_code() API and choose a backendShared Sandbox
Share one container across every agent with
run_on=
