Repository navigation
Sandbox: cover all agent side effects, at any scope including per-run #326
Copy link
Copy link
Open
Description
Goal
The OS sandbox should be able to cover everything an agent can do with side effects, and be designatable at any scope: a specific run, an agent, a stage, or the entire world. Today it covers a subset, and one scope is missing.
What the sandbox covers today (verified in code)
- Shell command execution:
BuiltinToolsroutesshellthrough theShellExecutorseam into the container/namespace (crates/leviath-tools/src/context.rs,exec.rs). - Seed commands: run inside the entry stage's sandbox when the agent declares one (
crates/leviath-cli/src/daemon/seed_command.rs). - Rhai script
shell(): routed through the agent's per-stage sandbox (crates/leviath-cli/src/daemon/script_host.rs).
Scopes: global default, per agent, per stage, cascading through resolve_sandbox (crates/leviath-core/src/sandbox.rs), with the right property that a manifest can strengthen but never weaken the user's setting.
Gaps
- Network tools bypass the sandbox entirely.
web_fetch/web_searchexecute in the daemon process on the host, and Rhaifetch()does host networking throughRealScriptIo. A sandbox withnetwork = falsestill leaves the agent full host network access through these tools. This is the sharpest inconsistency: the config key reads like a network boundary and is not one. - MCP servers run on the host, outside any sandbox. The shared MCP pool (
crates/leviath-cli/src/daemon/mcp_pool.rs) spawns server processes directly, and they are shared across agents, so one sandboxed agent's MCP tool calls execute host-side with no containment and no per-agent separation. - File tools are host-side. They are workdir-confined via canonicalized path containment (a real fence, and the sandbox bind-mounts the same workdir), but they do not execute inside the sandbox, so kernel attack surface and symlink/TOCTOU exposure remain host-level even for a fully sandboxed agent.
- No per-run designation.
lev runhas no--sandbox(or similar) override; designation is blueprint/config-level only. "Run this one untrusted task in a container" currently requires editing config or the blueprint.
Suggested end state
network = falsedeniesweb_fetch/web_search/Rhaifetch()for that agent (or routes them through the sandbox's network namespace), so the key means what it says.- An option to run an agent's MCP servers inside the agent's sandbox (accepting the loss of cross-agent pooling for sandboxed agents), or at minimum per-agent server instances for sandboxed agents.
- File tools optionally executed via the sandbox when one is active, since the workdir is already bind-mounted.
- A
lev run --sandbox <kind>/--sandbox-image <img>spawn-time override, clamped by the same may-strengthen-never-weaken rule asresolve_sandbox.
Until then, the docs (security.md, comparison.md, integrations.md) describe the current scope truthfully: shell, seeds, and script shell() only.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
docs: fix the security and scripting claims a code read disproves
docs: fix the security and scripting claims a code read disproves