Skip to main content

Sandbox Tool

The sandbox provides an isolated execution environment for running untrusted code and commands securely.

Overview

Sandboxing protects your system by:
  • Isolating execution: Commands run in separate container
  • Limiting access: Restricted file system and network access
  • Resource control: CPU and memory limits
  • Clean environment: Fresh state for each session

Supported Providers

Docker

Status: Recommended for most users Requirements:
  • Docker Desktop or Docker Engine
  • Sufficient disk space for container image
Setup:
# Enable Docker sandbox
export QWEN_SANDBOX=docker

# Build sandbox image
npm run build:sandbox

# Start Qwen Code
qwen-code

Podman

Status: Alternative to Docker Requirements:
  • Podman installed and configured
  • Rootless mode supported
Setup:
# Enable Podman sandbox
export QWEN_SANDBOX=podman

# Start Qwen Code
qwen-code

macOS Seatbelt

Status: macOS native sandboxing Requirements:
  • macOS operating system
  • System Integrity Protection enabled
Setup:
# Enable macOS sandbox
export QWEN_SANDBOX=macos

# Start Qwen Code
qwen-code

No Sandbox

Status: Not recommended (development only) Setup:
# Disable sandboxing
export QWEN_SANDBOX=false

# Start Qwen Code
qwen-code
⚠️ Warning: Only use when necessary. Commands execute with full system access.

Configuration

Environment Variable

The primary configuration method:
# In ~/.bashrc, ~/.zshrc, or ~/.env
export QWEN_SANDBOX=docker  # or podman, macos, false

Settings File

Configure in settings.json:
{
  "tools": {
    "sandbox": {
      "enabled": true,
      "provider": "docker",
      "image": "ghcr.io/qwenlm/qwen-code:latest"
    }
  }
}

Build Configuration

Default Image:
ghcr.io/qwenlm/qwen-code:<version>
Custom Image: See “Customizing the Sandbox” section below.

How It Works

Execution Flow

User Request

    v
Shell Tool

    ├─ Is sandbox enabled?

    ├─ Yes: Route to sandbox
    │     │
    │     v
    │   Sandbox Container
    │     ├─ Mount project directory
    │     ├─ Execute command
    │     ├─ Capture output
    │     └─ Return result

    └─ No: Execute directly

          v
        Host System

Container Lifecycle

  1. Session Start:
    • Pull/build sandbox image
    • Start container
    • Mount project directory
    • Set up environment
  2. Command Execution:
    • Send command to container
    • Execute in isolated environment
    • Stream output back to CLI
    • Handle errors and timeouts
  3. Session End:
    • Stop container
    • Clean up resources
    • Preserve project changes

Customizing the Sandbox

Custom Dockerfile

Note: This requires working from the source code repository, not an npm-installed package.

Requirements

  1. Clone the Qwen Code repository:
    git clone https://github.com/QwenLM/qwen-code.git
    cd qwen-code
    
  2. Install dependencies:
    npm install
    
  3. Build the project:
    npm run build
    
  4. Link the CLI globally:
    cd packages/cli
    npm link
    

Create Custom Dockerfile

Create .qwen/sandbox.Dockerfile in your project:
# Base on official Qwen sandbox image
FROM ghcr.io/qwenlm/qwen-code:sha-570ec43

# Add extra tools
RUN apt-get update && apt-get install -y \
    git \
    python3 \
    python3-pip \
    ripgrep \
    jq \
    && rm -rf /var/lib/apt/lists/*

# Install Python packages
RUN pip3 install --no-cache-dir \
    requests \
    beautifulsoup4

# Add custom scripts
COPY scripts/ /usr/local/bin/
RUN chmod +x /usr/local/bin/*.sh

# Set working directory
WORKDIR /workspace

Build Custom Image

From your project root:
QWEN_SANDBOX=docker BUILD_SANDBOX=1 qwen -s
This builds a project-specific image based on your Dockerfile.

Verify Custom Image

# Start Qwen Code
qwen-code

# Test custom tool
/shell git --version
/shell python3 --version
/shell rg --version

Restore Official CLI

After testing custom sandbox:
# Unlink source build
cd packages/cli
npm unlink

# Verify removal
which qwen  # Should show "not found"

# Reinstall official version
npm install -g @qwen-code/qwen-code

# Verify
qwen-code --version

Sandbox Limitations

File System

Accessible:
  • Project directory (mounted read-write)
  • Temp directory within container
  • Standard Unix paths
Not Accessible:
  • Home directory outside project
  • System directories
  • Other projects

Network

Default:
  • Outbound connections allowed
  • No inbound connections
  • DNS resolution available
Can be restricted further with custom configuration.

Performance

Overhead:
  • Container startup: ~1-2 seconds
  • Command execution: Minimal (less than 100ms)
  • File I/O: Slightly slower than native
Optimization:
  • Keep container running between commands
  • Use .dockerignore to exclude large files
  • Cache package installations in image

Security Benefits

Isolation

Protected:
  • System files
  • Other projects
  • User data
  • Network resources
Contained:
  • Malicious scripts
  • Unexpected side effects
  • Resource consumption
  • File system modifications

Use Cases

When to use sandbox:
  1. Untrusted code:
    # Run downloaded script safely
    ./unknown-script.sh
    
  2. Experimental commands:
    # Test potentially dangerous operation
    rm -rf suspicious-directory/
    
  3. Package installation:
    # Install untrusted package
    npm install unknown-package
    
  4. Build processes:
    # Run complex build
    make all
    
When sandbox isn’t needed:
  1. Trusted, well-known commands (git status, ls)
  2. Simple file operations
  3. Built-in tools (read_file, write_file)
  4. Development on personal projects

Troubleshooting

Image Build Fails

Error: Failed to build sandbox image Solutions:
  1. Check Docker/Podman is running
  2. Verify internet connectivity
  3. Check disk space: df -h
  4. Clear Docker cache: docker system prune
  5. Retry build: npm run build:sandbox

Container Won’t Start

Error: Container failed to start Solutions:
  1. Check Docker daemon: docker ps
  2. Review logs: docker logs <container-id>
  3. Restart Docker Desktop
  4. Check resource limits

Permission Errors

Error: Permission denied in sandbox Solutions:
  1. Check file permissions in project
  2. Verify mount points
  3. Use rootless container if possible
  4. Check SELinux/AppArmor policies

Performance Issues

Symptoms: Slow command execution Solutions:
  1. Check Docker resource allocation
  2. Reduce mounted directory size
  3. Use .dockerignore:
    node_modules/
    .git/
    dist/
    *.log
    
  4. Increase Docker Desktop resources

Network Issues

Error: Network request failed in sandbox Solutions:
  1. Check Docker network mode
  2. Verify DNS resolution: docker run alpine nslookup google.com
  3. Check firewall rules
  4. Test with --network host (temporary)

Best Practices

1. Keep Images Updated

# Pull latest official image
docker pull ghcr.io/qwenlm/qwen-code:latest

# Rebuild sandbox
npm run build:sandbox

2. Optimize Image Size

# Multi-stage build
FROM node:20 AS builder
WORKDIR /build
COPY package*.json ./
RUN npm ci --production

FROM ghcr.io/qwenlm/qwen-code:latest
COPY --from=builder /build/node_modules ./node_modules

3. Cache Dependencies

# Cache apt packages
RUN --mount=type=cache,target=/var/cache/apt \
    apt-get update && apt-get install -y git

# Cache npm packages
RUN --mount=type=cache,target=/root/.npm \
    npm install -g typescript

4. Use .dockerignore

# .dockerignore
node_modules/
.git/
dist/
build/
*.log
.env

5. Monitor Resources

# Check container resource usage
docker stats

# Check disk usage
docker system df

Configuration Reference

Full Settings

{
  "tools": {
    "sandbox": {
      "enabled": boolean,           // Enable sandboxing
      "provider": string,           // "docker", "podman", "macos", "false"
      "image": string,              // Container image
      "dockerfile": string,         // Custom Dockerfile path
      "buildArgs": object,          // Docker build arguments
      "containerOptions": {
        "memory": string,           // Memory limit (e.g., "2g")
        "cpus": number,             // CPU count
        "timeout": number,          // Timeout in ms
        "network": string,          // Network mode
      }
    }
  }
}

Environment Variables

QWEN_SANDBOX=docker              # Sandbox provider
BUILD_SANDBOX=1                  # Trigger sandbox build
DOCKER_HOST=unix:///var/run/docker.sock  # Docker socket

Implementation

Key Files:
  • scripts/build_sandbox.js - Build script
  • Dockerfile - Sandbox image definition
  • packages/core/src/services/shellExecutionService.ts - Execution routing

Shell Execution Service

export class ShellExecutionService {
  async executeCommand(
    command: string,
    options: ShellExecutionConfig,
  ): Promise<ShellResult> {
    if (this.config.isSandboxEnabled()) {
      return this.executeSandboxed(command, options);
    }
    return this.executeDirect(command, options);
  }

  private async executeSandboxed(
    command: string,
    options: ShellExecutionConfig,
  ): Promise<ShellResult> {
    const containerCmd = [
      'docker', 'exec', '-i',
      '-w', '/workspace',
      this.containerId,
      'bash', '-c', command,
    ];

    return this.spawn(containerCmd, options);
  }
}

Next Steps