jeevesagent.security.sandbox

Sandbox layer.

Sandboxes wrap a ToolHost and mediate every call. The wrapper is itself a ToolHost (it re-exports list_tools / call / watch) so it slots straight into Agent(tools=sandbox) with zero changes to the agent core.

What’s here today:

  • NoSandbox — pass-through. Useful as a layer placeholder and to demonstrate the wrapping pattern.

  • FilesystemSandbox — validates path-typed arguments don’t escape one or more declared roots; symlinks are resolved before the containment check. Auto-detects path arguments by name (path, file, directory, …) or by the value containing /; callers can also pass an explicit path_args= allowlist.

OS-level isolation backends (Bubblewrap on Linux, Seatbelt on macOS, gVisor/Docker for cross-platform) live in subsequent slices.

Submodules

Classes

FilesystemSandbox

Restrict a tool host's path-typed arguments to declared roots.

NoSandbox

Pass-through wrapper around a ToolHost.

SubprocessSandbox

Run each tool call in a fresh child Python process.

Package Contents

class jeevesagent.security.sandbox.FilesystemSandbox(inner: jeevesagent.core.protocols.ToolHost, *, roots: collections.abc.Iterable[str | pathlib.Path], path_args: collections.abc.Iterable[str] | None = None, auto_detect: bool = True)[source]

Restrict a tool host’s path-typed arguments to declared roots.

async call(tool: str, args: collections.abc.Mapping[str, Any], *, call_id: str = '') jeevesagent.core.types.ToolResult[source]
async list_tools(*, query: str | None = None) list[jeevesagent.core.types.ToolDef][source]
async watch() collections.abc.AsyncIterator[jeevesagent.core.types.ToolEvent][source]
property inner: jeevesagent.core.protocols.ToolHost
property roots: tuple[pathlib.Path, Ellipsis]
class jeevesagent.security.sandbox.NoSandbox(inner: jeevesagent.core.protocols.ToolHost)[source]

Pass-through wrapper around a ToolHost.

async call(tool: str, args: collections.abc.Mapping[str, Any], *, call_id: str = '') jeevesagent.core.types.ToolResult[source]
async list_tools(*, query: str | None = None) list[jeevesagent.core.types.ToolDef][source]
async watch() collections.abc.AsyncIterator[jeevesagent.core.types.ToolEvent][source]
property inner: jeevesagent.core.protocols.ToolHost
class jeevesagent.security.sandbox.SubprocessSandbox(inner: jeevesagent.core.protocols.ToolHost, *, timeout_seconds: float = 30.0)[source]

Run each tool call in a fresh child Python process.

async call(tool: str, args: collections.abc.Mapping[str, Any], *, call_id: str = '') jeevesagent.core.types.ToolResult[source]
async list_tools(*, query: str | None = None) list[jeevesagent.core.types.ToolDef][source]
async watch() collections.abc.AsyncIterator[jeevesagent.core.types.ToolEvent][source]
property inner: jeevesagent.core.protocols.ToolHost
property timeout_seconds: float