feat(tools): add "sandbox" toolset to run code snippets in an ephemeral, isolated container#3639
feat(tools): add "sandbox" toolset to run code snippets in an ephemeral, isolated container#3639dwin-gharibi wants to merge 6 commits into
Conversation
|
To discuss with the team but I don't think it would work well with sandboxes like sbx which are designed for such purpose. Here giving the choice to the Agent to use the sandbox tool is not very secure and will probably not be very efficient |
You’re right @aheritier, I agree that giving the Agent full freedom to decide when to use the sandbox might not be the best approach from a security and efficiency perspective, especially since sandboxes like sbx are already designed specifically for this purpose. With the current implementation, the user can only choose whether the sandbox should be enabled or disabled globally for all cases. However, there are scenarios where the user may not enable the sandbox, but the Agent can determine that a specific command should still be executed inside a sandbox for security or isolation reasons. Without having access to the sandbox tool at the Agent level, that kind of decision-making is not possible. The Agent would have no way to enforce isolation when it identifies a potentially risky operation. So I think the question is more about finding the right balance: keeping user control over sandbox availability while allowing the Agent to request or require sandbox execution for specific actions when needed. |
Also, this is a first step toward enabling remote code execution for the Agent on cloud environments and adding broader execution support in the future. The goal is to build the foundation for the Agent to safely execute tasks across different environments with proper isolation and security controls. This is also aligned with the approach used by projects like Crabbox, where the execution environment is treated as a separate capability that can be controlled and integrated by the Agent. Please take some time to think about this approach with team and let me know whether you think we should continue with the implementation or reconsider the direction. However It's almost implemented and only needs triage. |
Closes #3638
Summary
Adds a new built-in toolset,
sandbox, that runs a code snippet (python,node, orbash) inside an ephemeral, isolated container and returns stdout, stderr, and the exit code. Every run is disposable (--rm), resource-limited (memory / CPU / PID), time-bounded, and network-disabled by default.Tool:
run_code(language, code, timeout_seconds?, network?).Motivation
Agents often need to run code — compute a result, transform data, verify an approach — not just read/write files. Today the only option is
shell, which runs on the host with full access. The sandbox runs untrusted / model-generated code in a disposable, isolated container instead. It fits docker-agent naturally, since a container runtime is already the environment it ships on.Works with docker or other runtimes
Execution goes through an injectable
Executor, and the default one auto-detects a docker-compatible CLI in order: docker → podman → nerdctl (they sharerun --rm -i --network none …syntax). If none is present,run_codereturns a clear error.What changed
pkg/tools/builtin/sandbox/sandbox.gorun_code, purebuildRunArgs,Executorseam, runtime detection.pkg/tools/builtin/sandbox/sandbox_test.gopkg/teamloader/toolsets/toolsets.gosandboxcreator.pkg/teamloader/toolsets/catalog.gosandboxcatalog entry (required by the drift-guard test).docs/configuration/tools/index.mdsandboxto the built-in toolsets table.docs/tools/sandbox/index.mdDesign for testability
The container command is a pure
buildRunArgsfunction, and execution goes through anExecutorinterface. Tests cover argument construction, language aliasing, timeout capping, output formatting, and every error path with a fake executor — everything except the literaldocker run, which needs a daemon (covered by CI/integration).Example
The command it builds:
Tool output:
Testing
go test ./pkg/tools/builtin/sandbox/ ./pkg/teamloader/toolsets/buildRunArgs(isolation flags, limits, image;--network nonepresent by default and absent whennetwork: true), language aliasing,run_code(success, non-zero exit, empty code, unknown language, timeout cap, executor error), and the tool/interface check.TestBuiltinToolsetsCatalogMatchesRegistrypasses withsandboxin both registry and catalog.All pass;
gofmt -landgo vetclean. (CI runstask lint/task test.)Safety / scope
--rm,--network none,--memory 512m,--cpus 1,--pids-limit 256, and a time limit (default 30s, capped 300s).network: trueopts into a network only when the agent explicitly asks.