Reasonix Sandbox Enforcement: How File Writers and Bash Commands Are Isolated
Reasonix enforces sandbox isolation through two distinct mechanisms: path-constrained file writer built-ins that validate all targets against allowed roots, and OS-level Seatbelt sandboxing for bash commands on macOS using sandbox-exec profiles.
DeepSeek-Reasonix implements a dual-layer security model to prevent AI-generated code from escaping predefined boundaries. The system applies specific sandbox enforcement techniques to file-writing operations and shell command execution, ensuring that model-generated actions remain confined to approved directories and resource limits regardless of symlinks or path traversal attempts.
File-Writer Sandbox Enforcement via Path Confinement
When a Reasonix run initializes, the composition root invokes builtin.ConfineWriters from internal/tool/builtin/confine.go to wrap all file-writing built-ins (write_file, edit_file, move_file, etc.) with path validation logic. This mechanism ensures that write operations can only occur within explicitly defined boundaries.
Root Resolution and Validation
The confinement system begins by processing the list of writable roots—comprising the workspace directory plus any additional paths specified via allow_write in reasonix.toml. The realRoots function resolves each configured root to an absolute, symlink-free path before any validation occurs. This resolution prevents path traversal attacks that attempt to bypass restrictions using relative path components or symbolic links.
Runtime Path Verification
Every writer built-in stores the resolved root slice and invokes the confine(roots, target) function on each write request. This function performs three critical operations:
- Resolves the target path to a real absolute path using
realPath - Checks whether the resolved target resides within any allowed root using the
withinhelper - Returns an error if the path lies outside permitted boundaries (see lines 71-86 of
internal/tool/builtin/confine.go)
If the validation fails, the model receives a clear diagnostic message rather than the write proceeding outside the sandbox. This guarantees that file modifications remain strictly limited to the workspace or explicitly approved extra directories.
Bash Command Isolation with Seatbelt
For shell command execution, Reasonix leverages builtin.ConfineBash to create sandbox-aware bash tool instances. Unlike the path-based validation used for file writers, bash command enforcement relies on operating system-level sandboxing available on macOS.
Sandbox Spec Configuration
The bash tool accepts a sandbox.Spec defined in internal/sandbox/sandbox.go that controls confinement behavior:
Mode: Must be set to"enforce"to activate restrictionsWriteRoots: Directories where the command may write filesNetwork: Boolean controlling whether network access is permitted
macOS Seatbelt Profile Generation
On macOS systems, the sandbox.Command function in internal/sandbox/seatbelt_darwin.go constructs a Seatbelt profile and wraps commands with sandbox-exec. The seatbeltProfile function generates a policy that:
- Starts with an "allow default" stance
- Explicitly denies all file writes system-wide
- Re-allows writes only under paths returned by
writeAllowDirs(derived fromWriteRoots) - Optionally denies network access unless
spec.Networkistrue
OS-Level Command Wrapping
When spec.enforce is true and sandbox-exec is available, sandbox.Command prefixes the user command with sandbox-exec -p <profile>, enforcing kernel-level restrictions on file system and network access. On non-macOS platforms or when the sandbox tool is unavailable, sandbox.Command returns the original command unchanged, relying on higher-level permission layers to block unauthorized calls.
Implementation Examples
The following Go code demonstrates configuring a sandboxed bash command that permits network access but restricts writes to the workspace:
spec := sandbox.Spec{
Mode: "enforce",
WriteRoots: []string{"/home/user/project"},
Network: true,
}
bashTool := builtin.ConfineBash(spec)
// Execute within a Reasonix skill
result, err := bashTool.Run(ctx, tool.Params{
Command: "git clone https://github.com/example/repo.git",
})
To restrict file-writer built-ins to specific directories, use ConfineWriters:
roots := []string{"/home/user/project", "/tmp/extra-writes"}
writers := builtin.ConfineWriters(roots)
// Register confined writers in the tool registry
for _, w := range writers {
registry.Register(w.Name(), w)
}
Summary
- Path-based confinement in
internal/tool/builtin/confine.govalidates all file writer targets against absolute, symlink-free roots before allowing modifications - OS-level sandboxing via
sandbox-execand Seatbelt profiles restricts bash commands to specific write directories and optional network access on macOS - The
sandbox.Specstructure centralizes configuration for enforcement mode, writable roots, and network permissions across both mechanisms - File writer validation occurs in-process through the
confineandwithinhelpers, while bash isolation relies on externalsandbox-execinvocation when available
Frequently Asked Questions
How does Reasonix prevent file writers from escaping the sandbox directory?
Reasonix calls builtin.ConfineWriters at initialization to wrap all file-writing built-ins with root validation. Each write request passes through the confine function, which resolves the target path to its absolute, symlink-free form and verifies it resides within the permitted roots using the within helper. If the path lies outside allowed directories, the operation returns an error before any file system modification occurs.
Why is bash command sandboxing limited to macOS?
The bash sandbox implementation relies on sandbox-exec, a macOS-specific utility that applies Seatbelt policies to processes. The internal/sandbox/seatbelt_darwin.go file contains the platform-specific logic for generating Seatbelt profiles and invoking sandbox-exec. On Linux or Windows systems, sandbox.Command returns the unmodified command, though higher-level permission checks may still prevent execution based on tool policies.
What happens if sandbox-exec is not available on a macOS system?
If sandbox-exec is unavailable, the Available() check in internal/sandbox/seatbelt_darwin.go returns false, causing sandbox.Command to return the original command without wrapping. In this scenario, the bash tool runs unconfined at the OS level, though Reasonix may still block the call through its higher-level permission layer depending on the tool registry configuration.
How are writable directories configured for Reasonix sandboxes?
Writable directories are specified through the WriteRoots field in sandbox.Spec for bash commands, or passed directly to builtin.ConfineWriters for file writers. Additionally, users can declare extra writable paths in the allow_write configuration option within reasonix.toml. All paths are resolved to absolute, canonical forms via realRoots before enforcement begins.
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 →