How Sandbox Configuration in esengine/DeepSeek-Reasonix Restricts File System Access

The sandbox configuration in DeepSeek-Reasonix isolates tool execution by defining workspace_root as the primary writable boundary, extending write permissions through allow_write, and blocking sensitive reads via forbid_read, with OS-level enforcement ensuring these policies cannot be bypassed.

DeepSeek-Reasonix implements a two-layer security model to prevent unauthorized file system operations. The policy layer defined in reasonix.toml specifies permissible boundaries, while the enforcement layer uses OS-specific sandboxing technology to harden these restrictions against symlink traversal and path escape attempts.

Understanding the Policy Layer: SandboxConfig

The policy definitions reside in internal/config/config.go within the SandboxConfig struct. This structure maps directly to the [sandbox] section of the configuration file and establishes the foundational rules for file system access.

WorkspaceRoot, AllowWrite, and ForbidRead Fields

The SandboxConfig struct defines three critical fields that govern file system visibility:

type SandboxConfig struct {
    WorkspaceRoot string   `toml:"workspace_root"`
    AllowWrite    []string `toml:"allow_write"`
    ForbidRead    []string `toml:"forbid_read"`
}
  • WorkspaceRoot: Serves as the base directory for all file-writing tools (write_file, edit_file, etc.). When empty, it defaults to the current working directory.
  • AllowWrite: Specifies additional directories outside the workspace where writers may operate, such as /tmp or sibling repositories.
  • ForbidRead: Lists absolute paths or patterns that the agent must not read or list, typically including sensitive directories like ~/.ssh or credential stores.

Configuration Resolution Methods

The config layer provides helper methods to resolve raw TOML values into absolute, symlink-free paths suitable for enforcement:

  • WriteRootsForRoot(fallbackRoot string) []string (lines 1128-1150): Returns the combined writable surface including workspace_root plus all allow_write entries.
  • ForbidReadRootsForRoot(fallbackRoot string) []string (lines 1174-1194): Resolves the forbid_read list into absolute paths for runtime checking.

OS-Level Enforcement with sandbox.Spec

While the policy layer defines rules, the sandbox.Spec struct in internal/sandbox/sandbox.go carries these constraints to the OS-level enforcement engine.

type Spec struct {
    Mode            string   // "enforce" activates Seatbelt (macOS) or bubblewrap (Linux)
    WriteRoots      []string // Populated from WriteRootsForRoot
    ForbidReadRoots []string // Populated from ForbidReadRootsForRoot
    // ...
}

When Mode is set to "enforce", DeepSeek-Reasonix wraps tool execution in OS-specific sandboxing technology. If the backend is unavailable, the command is rejected with an UnavailableMessage rather than executing unsandboxed, ensuring fail-closed behavior.

Runtime Path Validation

The actual restriction logic operates in internal/tool/builtin/confine.go, where path requests are validated against the configured boundaries before any file operation executes.

Write Confinement via confineWrite

The confineWrite function validates write targets through three sequential checks implemented in the confine helper (lines 90-110):

  1. Root Confinement: Verifies the target path falls within one of the WriteRoots directories.
  2. Session Data Guard: Prevents accidental corruption of Reasonix's internal session stores.
  3. Managed Config Approval: Requires explicit human approval for writes to privileged configuration files.

If a write request targets a path outside all defined roots, the system returns a descriptive error:


path "/etc/passwd" is outside the writable roots (writes are confined to /my/project, /tmp);
write inside the workspace or a configured allow_write root, or widen [sandbox] workspace_root / allow_write in reasonix.toml

Read Restrictions via confineRead

For read operations, confineRead (lines 28-36) checks the path against forbid_read entries and a built-in secret-file denylist. When a match occurs, the system silently pretends the file is empty rather than exposing its existence, preventing information leakage about sensitive files regardless of Unix permissions.

Practical Configuration Example

To implement these restrictions in your reasonix.toml:

[sandbox]
workspace_root = "/home/user/projects"
allow_write = ["/tmp", "/var/log/build"]
forbid_read = ["~/.ssh", "~/.aws/credentials", "**/*.pem"]

The following Go code demonstrates how these values resolve at runtime:

cfg, _ := config.Load("reasonix.toml")
writeRoots := cfg.WriteRootsForRoot(".")
fmt.Println("Writable roots:", writeRoots) // ["/home/user/projects", "/tmp", "/var/log/build"]

forbidRoots := cfg.ForbidReadRoots()
if builtin.ConfineRead(forbidRoots, os.ExpandEnv("$HOME/.ssh/id_rsa")) {
    fmt.Println("Access denied: path matches forbid_read pattern")
}

Summary

  • Policy Definition: The [sandbox] section in reasonix.toml maps to SandboxConfig in internal/config/config.go, establishing workspace_root as the primary boundary for file operations.
  • Extended Permissions: allow_write extends the writable surface beyond the workspace, while forbid_read creates explicit read prohibitions for sensitive paths.
  • Path Resolution: WriteRootsForRoot and ForbidReadRootsForRoot convert configuration values into absolute, validated path lists.
  • OS Enforcement: sandbox.Spec transmits these boundaries to OS-level sandboxes (Seatbelt on macOS, bubblewrap on Linux) when Mode is "enforce".
  • Runtime Validation: confineWrite and confineRead in internal/tool/builtin/confine.go perform final authorization checks, returning descriptive errors for write violations or silently blocking sensitive reads.

Frequently Asked Questions

What happens if workspace_root is empty or unset?

When workspace_root is empty, DeepSeek-Reasonix defaults to the current working directory. The WriteRootsForRoot method uses the provided fallback root to establish the base writable boundary, ensuring tools always operate within a defined scope even without explicit configuration.

Can allow_write directories exist outside the workspace_root?

Yes. The allow_write array specifically enables writes to directories outside the primary workspace. According to the source code in internal/config/config.go, these paths are resolved independently and appended to the write roots list, allowing legitimate access to shared resources like /tmp or adjacent repositories while maintaining strict confinement elsewhere.

How does forbid_read differ from standard Unix permissions?

Unlike Unix permissions which depend on user identity, forbid_read operates at the application layer within confineRead. Even if the operating system user has read access to ~/.ssh/id_rsa, DeepSeek-Reasonix will silently treat the file as empty if its path matches the forbid_read list or built-in secret patterns, preventing credential exfiltration regardless of OS-level permissions.

What occurs when the OS sandbox backend is unavailable?

If Mode is set to "enforce" but the sandbox backend (Seatbelt on macOS or bubblewrap on Linux) is missing, DeepSeek-Reasonix rejects the command with an UnavailableMessage rather than executing unconfined. This fail-closed behavior ensures that policy violations cannot occur due to missing system dependencies.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →