Sandbox Execution Environment
Relevant source files
The following files were used as context for generating this wiki page:
The Sandbox Execution Environment provides a secure, isolated layer for executing potentially untrusted code or commands within the OpenCode Swarm ecosystem. Its primary purpose is to protect the host system from unauthorized access, malicious activities, or accidental corruption during code generation and testing phases. By abstracting the isolation mechanism, the system supports multiple execution backends tailored to different operating systems and security requirements.
The environment operates by encapsulating execution requests into specific "Executor" implementations that leverage OS-native security features, such as Linux namespaces or Windows Job Objects. This ensures that resources like file system access, network connectivity, and process lifespans are strictly controlled and monitored.
System Architecture
The sandbox system is built on a modular architecture where a central manager coordinates with platform-specific executors. The SandboxManager serves as the primary entry point, determining the appropriate execution strategy based on the host environment and configuration.
Core Components
| Component | Description | Source |
|---|---|---|
SandboxManager | Orchestrates sandbox lifecycle, including initialization and task routing. | src/sandbox/manager.ts |
SandboxExecutor | Abstract interface defining the contract for all platform-specific executors. | src/sandbox/executor.ts |
BubblewrapExecutor | Linux-specific implementation using bwrap for namespace-based isolation. | src/sandbox/executors/bubblewrap.ts |
WindowsExecutor | Windows-specific implementation using Job Objects and restricted tokens. | src/sandbox/executors/windows.ts |
SandboxRunner | A specialized Rust-based binary responsible for low-level process management. | runners/swarm-sandbox-runner/src/main.rs |
Architecture Overview Diagram
The following diagram illustrates the relationship between the management layer and the various execution backends.
Execution Lifecycle
The execution of a sandboxed task follows a rigorous lifecycle to ensure isolation is maintained from start to finish. This involves environment preparation, resource binding, execution via a specialized runner, and result capture.
Process Flow
- Request Initiation: The system receives a request to execute a command with a specific working directory and environment variables.
- Executor Selection:
SandboxManagerselects the backend (e.g.,BubblewrapExecutor). - Environment Setup: The executor creates a temporary profile, binds necessary directories (like the project root), and mounts system libraries in read-only mode.
- Execution: The command is wrapped and passed to the
swarm-sandbox-runner. - Cleanup: Once execution finishes (or times out), the manager ensures all orphaned processes are terminated and temporary mounts are unlinked.
Platform-Specific Implementations
Linux (Bubblewrap)
On Linux systems, isolation is achieved using bubblewrap (bwrap). This executor creates a new mount namespace, user namespace, and PID namespace. Key features include:
- Read-Only Mounts: Critical system paths like
/usr,/bin, and/libare mounted read-only. - Private Tmpfs: A private
/tmpand/devare created to prevent host interference. - Unshare Networking: Optionally disables network access by unsharing the network namespace.
Sources: src/sandbox/executors/bubblewrap.ts:20-85
Windows (Job Objects)
The Windows executor utilizes Job Objects and restricted security tokens to limit process capabilities.
- Resource Limits: Limits memory usage and CPU cycles per task.
- Token Restriction: Strips dangerous privileges (e.g.,
SeDebugPrivilege) from the execution token. - Job Cleanup: Ensures that if the parent process dies, all child processes in the job are automatically terminated.
Sources: src/sandbox/executors/windows.ts:15-70
Sandbox Runner (Rust)
The swarm-sandbox-runner is a low-level utility written in Rust. It acts as the final wrapper before the target command is executed. Its responsibilities include:
- Signal Handling: Correctly forwarding signals (like
SIGTERM) to the child process. - I/O Redirection: Efficiently capturing and streaming stdout/stderr back to the TypeScript layer.
- Timing: Enforcing hard wall-clock timeouts at the system level to prevent infinite loops or hangs.
// runners/swarm-sandbox-runner/src/main.rs (Concept)
fn main() {
let args: Vec<string> = env::args().collect();
// Parse constraints (memory, timeout, cwd)
let mut child = Command::new(&args[1])
.args(&args[2..])
.spawn()
.expect("failed to execute process");
// Wait for completion or timeout signal
}
Sources: runners/swarm-sandbox-runner/src/main.rs:1-150
Configuration and Constraints
The execution environment can be tuned via SandboxOptions. These constraints are enforced by the executors and validated by the manager.
| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 30000 | Execution limit in milliseconds. |
memoryLimit | number | 512 | Memory limit in Megabytes. |
allowNetwork | boolean | false | Whether to permit outbound network calls. |
workingDir | string | process.cwd() | The root directory for the sandboxed process. |
readOnlyPaths | string[] | [] | Additional paths to be mounted as read-only. |
Sources: src/sandbox/executor.ts:5-25, src/sandbox/manager.ts:15-30
Summary
The Sandbox Execution Environment in opencode-swarm provides a robust, multi-platform safety net for code execution. By combining high-level TypeScript management with low-level platform primitives (Bubblewrap and Windows Job Objects) and a dedicated Rust runner, it achieves a balance between performance and strict security isolation. This system ensures that the Swarm can safely interact with a variety of codebases without risking the integrity of the underlying host system.