# How the Workspace Sandbox Provides Isolation for Agent Operations in Reasonix

> Discover how the Reasonix workspace sandbox isolates agent operations. Learn how it prevents unauthorized access and ensures secure tool call execution within designated directories.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: internals
- Published: 2026-08-11

---

**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 `/etc` or `/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/builtin/confine.go) (lines 28-33) creates a Bash tool instance bound to a specific `Spec`:

```go
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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/builtin/confine_test.go) validates these guarantees. Lines 347-352 demonstrate that writes outside the workspace root are rejected:

```go
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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/reasonix.toml):

```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:

1. **Permission system** (user-facing): Controls *which tools* may execute and what *types* of operations they perform
2. **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.Spec` configuration**: 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.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/reasonix.toml) offers `workspace_root`, `allow_write`, and `bash` mode 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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/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.