How the Workspace Sandbox Provides Isolation for Agent Operations in Reasonix
Reasonix uses an OS-level workspace sandbox to jail every tool call, ensuring that even user-approved write operations cannot escape the designated workspace directories or perform unauthorized network access.
The workspace sandbox in Reasonix is a defense-in-depth mechanism that operates beneath the permission system. While Reasonix's higher-level [permissions] configuration controls which tools a user allows, the sandbox enforces strict capability boundaries at the operating system level. This article examines how Reasonix implements this isolation across platforms, how developers can configure sandbox behavior, and why the design guarantees fail-closed security.
What the Workspace Sandbox Protects Against
Agent-based systems like Reasonix execute arbitrary commands on behalf of users. Without sandboxing, a tool call approved for "write to workspace" could:
- Follow symbolic links outside the workspace
- Write to system directories like
/etcor/usr - Exfiltrate data via unrestricted network access
- Persist malicious code in global temp directories
The sandbox eliminates these risks by wrapping every command in an OS-specific jail that resolves paths and enforces boundaries before execution.
Core Components: The sandbox.Spec Structure
All sandboxed commands receive a sandbox.Spec configuration defined in internal/sandbox/sandbox.go (lines 21-60). This structure declares the exact boundaries of what a command may access:
| Field | Purpose |
|---|---|
Mode |
"enforce" enables confinement; "off" disables it |
WriteRoots |
Directories where writes are permitted |
ForbidReadRoots |
Locations explicitly denied read access |
Network |
Boolean controlling outbound network egress |
SessionTemp |
Persistent temp directory shared across session commands |
The SessionTemp field enables practical workflows: successive bash tool calls can share temporary files while remaining inside the same jail.
OS-Level Backend Implementation
Reasonix selects sandbox backends based on the host operating system:
macOS: Seatbelt (sandbox-exec)
On macOS, Reasonix leverages Apple's Seatbelt framework. The sandbox-exec binary applies fine-grained BSD-level policies that restrict file system and network operations without requiring root privileges or containers.
Linux: Bubblewrap (bwrap)
Linux systems use bubblewrap, a lightweight sandboxing tool used by Flatpak and other container systems. Bubblewrap creates a minimal user namespace with filtered filesystem access and optional network isolation.
Windows: No Native Sandbox
Windows currently has no OS-level Bash sandbox backend. As documented in sandbox.go (lines 81-90), the UnavailableRemediation forces sandbox settings to "off" on Windows. This explicit degradation prevents false security assurances.
Fail-Closed Behavior
If a backend is requested but unavailable, Reasonix refuses execution. The UnavailableMessage (lines 72-78) triggers an error rather than falling back to unconfined execution. This fail-closed design prevents accidental privilege escalation when sandbox dependencies are missing.
Integration with Built-In Tools
Reasonix's built-in tools (bash, file readers/writers, search utilities) call sandbox.PrepareArgs to inject sandbox specifications into command execution. The ConfineBash helper in internal/tool/builtin/confine.go (lines 28-33) creates a Bash tool instance bound to a specific Spec:
import "reasonix/internal/sandbox"
spec := sandbox.Spec{
Mode: "enforce",
WriteRoots: []string{cfg.Sandbox.WorkspaceRoot},
Network: true,
SessionTemp: "/tmp/reasonix-session-1234",
}
bashTool := builtin.ConfineBash(spec, sessionGuard, nil)
The sessionGuard parameter ties the sandbox to the agent session lifecycle, ensuring that temp directories and other resources are properly scoped.
Enforcement Guarantees
The sandbox operates as an enforcement layer independent of permission approval. Even when reasonix.toml grants explicit write permissions, the sandbox still:
- Blocks writes outside
WriteRoots - Prevents reads from
ForbidReadRoots - Resolves
..sequences and symlinks before permission checks - Denies network access when
Network: false
This prevents symlink escape attacks where a permitted writer follows a link pointing outside the workspace. The sandbox resolves all paths within the jail context before applying access rules.
Verification: Sandbox Isolation Tests
The test suite in internal/tool/builtin/confine_test.go validates these guarantees. Lines 347-352 demonstrate that writes outside the workspace root are rejected:
spec := sandbox.Spec{Mode: "enforce", WriteRoots: []string{work}}
tool := builtin.ConfineBash(spec, guard, nil)
_, err := tool.Run(ctx, map[string]any{"cmd": "echo hi > /etc/passwd"})
if err == nil {
t.Fatalf("bash write outside the workspace should be denied by the sandbox")
}
These tests verify that the OS-level jail, not merely Go-level path checks, prevents escape attempts.
Configuring Workspace Sandbox Behavior
Users control sandbox settings through reasonix.toml:
[sandbox]
workspace_root = "." # Base directory for all operations
allow_write = ["/tmp"] # Additional writable paths beyond workspace
bash = "enforce" # "enforce" (default on macOS/Linux), "off", or "warn"
The bash setting deserves particular attention:
"enforce"(default): Requires functional sandbox backend; fails closed if unavailable"off": Disables sandboxing entirely, falling back to pre-1.16 unconfined behavior"warn": Attempts sandboxing but logs warnings rather than failing (not recommended for production)
The workspace_root defaults to the current working directory. The allow_write array extends WriteRoots for workflows requiring access to specific external directories like /tmp or cache locations.
Architecture: Sandbox vs. Permission System
Understanding the relationship between sandbox and permissions clarifies Reasonix's security model:
- Permission system (user-facing): Controls which tools may execute and what types of operations they perform
- Sandbox (enforcement layer): Controls where those operations may occur and what resources they may access
A user might approve "allow bash write operations" in permissions, but the sandbox still restricts where those writes land. This separation means:
- Permissions can be coarse-grained without sacrificing security
- The sandbox provides defense in depth if permissions are misconfigured
- Audit trails distinguish "user approved" from "technically possible"
Summary
- OS-level isolation: Reasonix uses Seatbelt (macOS) and bubblewrap (Linux) to jail every tool call in a workspace sandbox
- Fail-closed design: Missing sandbox backends cause execution failure rather than unconfined fallback
sandbox.Specconfiguration: Controls write roots, read prohibitions, network access, and session-scoped temporary directories- Enforcement layer: The sandbox resolves paths and symlinks before access checks, preventing escape attacks
- User configuration:
reasonix.tomloffersworkspace_root,allow_write, andbashmode settings
Frequently Asked Questions
What happens if the sandbox backend is not installed on my system?
Reasonix refuses to execute sandboxed commands and returns an error. As implemented in sandbox.go (lines 72-78), the UnavailableMessage triggers this fail-closed behavior. You must either install the required backend (sandbox-exec on macOS, bwrap on Linux) or explicitly set bash = "off" in reasonix.toml to acknowledge the security degradation.
Can the sandbox be bypassed through symbolic links or directory traversal?
No. The sandbox resolves all .. sequences and symbolic links within the jail context before applying access rules. A symlink pointing outside WriteRoots is resolved to its absolute path and then blocked by the OS-level enforcement, not merely by application-level path checks.
How do I share temporary files across multiple Bash tool calls?
Use the SessionTemp field in your sandbox.Spec. This provides a dedicated directory that persists across commands within the same session while remaining confined to the sandbox jail. Successive bash tool calls can read and write to this location without escaping workspace isolation.
Why does Windows lack sandbox support?
The current Reasonix implementation has no OS-level Bash sandbox backend for Windows. According to sandbox.go (lines 81-90), the UnavailableRemediation explicitly sets sandbox mode to "off" on Windows. This platform limitation is acknowledged rather than hidden, preventing false security assurances. Future versions may add Windows sandboxing through alternative mechanisms.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →