How the OpenDerisk Sandbox Code Agent Safely Executes Dynamically Generated Code

The OpenDerisk sandbox code agent isolates untrusted code in a resource-constrained subprocess using macOS sandbox profiles, strict filesystem controls, and configurable timeouts to prevent host system compromise.

The OpenDerisk sandbox code agent provides a secure execution environment for AI-generated code within the derisk-ai/openderisk repository. It combines process isolation, platform-specific sandboxing, and resource constraints to safely run Python snippets without exposing the host system to malicious or erroneous operations.

Core Safety Mechanisms

The safety architecture relies on multiple defensive layers implemented across specific source files.

Process Isolation via Subprocess Execution

In packages/derisk-ext/src/derisk_ext/sandbox/local/improved_runtime.py, the ImprovedLocalSandboxRuntime.execute method writes user code to a temporary script file and launches it using asyncio.create_subprocess_exec. This creates a separate PID with no shared parent process state, ensuring that crashes or infinite loops in the user code cannot destabilize the main application.

macOS Sandboxing with sandbox-exec

For macOS environments, the MacOSSandboxWrapper class in macos_sandbox.py generates SBPL (Sandbox Profile Language) profiles that restrict filesystem access, deny network connections, and limit CPU usage. The ImprovedLocalSandboxRuntime prepends sandbox-exec to the command, enforcing these restrictions at the operating-system level before the Python interpreter starts.

Linux Resource Controls

On Linux systems, the runtime applies ulimit-style constraints including max_memory and max_cpus through the subprocess execution environment. While the current implementation uses standard resource limits, the architecture supports extension to Linux cgroups for more sophisticated resource management.

Timeout Enforcement

The default_timeout parameter in LocalSandboxConfig (defaulting to 300 seconds) is strictly enforced within ImprovedLocalSandboxRuntime.execute. If the subprocess exceeds this limit, the runtime terminates the process and returns an ExecutionResult with a timeout error status, preventing runaway computations from consuming host resources indefinitely.

Filesystem and Network Isolation

The LocalSandboxConfig.work_dir parameter defaults to /workspace, creating a dedicated temporary directory per sandbox session that confines all file read and write operations. Network access is controlled via the allow_network boolean; when disabled (the default), the macOS SBPL profile explicitly denies network privileges, and the Linux subprocess can be configured to run in a network namespace to prevent external communication.

Language Guardrails and Output Sanitization

The AutoSandbox.run_code method in improved_provider.py enforces a whitelist of supported languages—currently restricted to "python"—raising NotImplementedError for unsupported languages. Both stdout and stderr are captured and stripped of control characters before being wrapped in an ExecutionResult object, ensuring that error messages cannot leak internal stack traces or execute terminal escape sequences.

Execution Flow

The sandbox code agent follows a four-stage pipeline when processing dynamically generated code:

  1. Session Creation: AutoSandbox.create() initializes a LocalSandboxConfig, instantiates an ImprovedLocalSandboxProvider, and builds an ImprovedLocalSandboxRuntime with the specified constraints.

  2. Code Submission: AutoSandbox.run_code(code, language) validates the language against the whitelist and forwards the snippet to ImprovedLocalSandboxProvider.run_code.

  3. Secure Execution: The runtime writes the code to a temporary file, constructs a command (optionally wrapped by sandbox-exec on macOS), and launches the subprocess with resource limits and timeout enforcement active.

  4. Result Sanitization: The agent captures output streams, measures execution time, and returns an ExecutionResult containing the output string, error status (SUCCESS, TIMEOUT, or ERROR), and timing metrics.

Implementation Examples

Basic Sandbox Usage

The following pattern demonstrates the standard approach for executing Python code safely:

from derisk.sandbox.sandbox_client import AutoSandbox

async def demo():
    # Create a sandbox (defaults to a temporary work dir)

    sandbox = await AutoSandbox.create()

    # Run a Python snippet safely

    result = await sandbox.run_code(
        code="print('Hello from sandbox!')",
        language="python",
    )

    print("Output:", result.output)
    print("Error :", result.error)
    print("Time  :", result.execution_time)

Source: tests/test_local_sandbox.py demonstrates sandbox creation and run_code usage.

Custom Security Configuration

You can harden the sandbox further by explicitly disabling network access and reducing memory limits:

from derisk_ext.sandbox.local.provider import LocalSandboxConfig
from derisk.sandbox.sandbox_client import AutoSandbox

config = LocalSandboxConfig(
    work_dir="/tmp/my_sandbox",
    default_timeout=60,            # 1-minute limit

    allow_network=False,           # network disabled

    max_memory=128 * 1024 * 1024, # 128 MiB

)

sandbox = await AutoSandbox.create(config=config)

# The same run_code call, now respecting the custom limits

result = await sandbox.run_code("import os; print(os.listdir('.'))")

Source: packages/derisk-ext/src/derisk_ext/sandbox/local/improved_provider.py defines the LocalSandboxConfig dataclass with these security parameters.

Handling Execution Timeouts

To detect and handle code that exceeds time limits:

result = await sandbox.run_code(
    code="while True: pass",  # infinite loop

    language="python"
)

if result.execution_time >= sandbox.config.default_timeout:
    print("The code timed out.")

Source: ImprovedLocalSandboxRuntime.execute returns a timeout error in ExecutionResult.error when limits are exceeded.

Summary

  • Process isolation via asyncio.create_subprocess_exec in improved_runtime.py ensures user code runs in a separate PID without shared state.
  • Platform-specific sandboxing uses sandbox-exec with SBPL profiles on macOS and ulimit constraints on Linux to restrict filesystem, network, and resource access.
  • Configurable timeouts (default 300 seconds) automatically terminate runaway processes and return timeout-specific error states.
  • Filesystem isolation confines all I/O to a temporary work_dir (default /workspace), preventing accidental host filesystem access.
  • Language whitelisting in improved_provider.py restricts execution to approved languages like Python, blocking unsupported or potentially dangerous interpreters.

Frequently Asked Questions

What happens when sandbox code exceeds the timeout limit?

When execution time exceeds the default_timeout configured in LocalSandboxConfig, the ImprovedLocalSandboxRuntime.execute method forcibly terminates the subprocess and returns an ExecutionResult with an error status indicating the timeout. The output contains a specific timeout message rather than partial execution results, ensuring deterministic failure handling for long-running or infinite loops.

Does the sandbox code agent support both Linux and macOS?

Yes. On macOS, the agent utilizes the MacOSSandboxWrapper to prepend sandbox-exec commands with generated SBPL profiles for kernel-level isolation. On Linux, it falls back to ulimit-based resource constraints and process isolation via subprocess execution, with architectural support for future cgroups integration to match macOS security parity.

How does the sandbox prevent access to the host filesystem?

The agent creates a dedicated temporary directory specified by LocalSandboxConfig.work_dir (defaulting to /workspace) for each session. All file operations are confined to this directory, and on macOS, the SBPL profile explicitly denies access to paths outside this workspace. The subprocess runs with no access to parent process files or sensitive host directories.

Can I customize memory and CPU limits for sandbox executions?

Yes. The LocalSandboxConfig accepts max_memory (in bytes) and max_cpus parameters that the ImprovedLocalSandboxRuntime applies to the subprocess environment. On macOS, these translate to SBPL profile constraints, while on Linux they configure ulimit restrictions, allowing fine-grained control over resource consumption per execution session.

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 →