Documentation Index
Fetch the complete documentation index at: https://mintlify.com/QwenLM/qwen-code/llms.txt
Use this file to discover all available pages before exploring further.
Sandbox Execution
Qwen Code supports sandboxed execution environments to isolate command execution and enhance security. This is particularly useful when running untrusted code or working in sensitive environments.
Supported Sandbox Runtimes
Qwen Code supports three sandbox backends:
Docker
Container-based isolation using Docker Engine.
Podman
Rootless container runtime, ideal for environments without Docker daemon privileges.
macOS Seatbelt (sandbox-exec)
Native macOS sandboxing without containers. Only available on macOS.
Configuration
Environment Variables
Enable Sandbox
# Auto-detect available runtime (seatbelt on macOS, manual on Linux)
export QWEN_SANDBOX=true
# Specify runtime explicitly
export QWEN_SANDBOX=docker
export QWEN_SANDBOX=podman
export QWEN_SANDBOX=sandbox-exec # macOS only
Custom Sandbox Image
# Use a custom Docker/Podman image
export QWEN_SANDBOX_IMAGE=my-custom-image:latest
Additional Configuration
# Pass custom flags to Docker/Podman
export SANDBOX_FLAGS="--cpus=2 --memory=4g"
# Mount additional paths (comma-separated)
export SANDBOX_MOUNTS="/path/on/host:/path/in/container:ro,/another/path:/mnt/data:rw"
# Pass environment variables to sandbox
export SANDBOX_ENV="API_KEY=secret,DEBUG=true"
# Expose ports from sandbox to host
export SANDBOX_PORTS="3000,8080"
# Control UID/GID mapping (Linux only)
export SANDBOX_SET_UID_GID=true # Default on Linux
export SANDBOX_SET_UID_GID=false # Use image default user
Command Line Options
# Enable sandbox with auto-detection
qwen --sandbox
# Specify runtime
qwen --sandbox=docker
qwen --sandbox=podman
# Custom image
qwen --sandbox-image=myorg/qwen-sandbox:v1
Settings File Configuration
In .qwen/settings.json:
{
"tools": {
"sandbox": "docker"
}
}
Docker/Podman Sandbox Details
How It Works
When using Docker or Podman:
-
Container Creation: Qwen Code spawns a container with:
- Current working directory mounted
- User settings directory (
~/.qwen) mounted
- Temporary directory mounted
- Network access configured
-
Environment Inheritance: The following are passed through:
- API keys (GEMINI_API_KEY, OPENAI_API_KEY, etc.)
- Terminal settings (TERM, COLORTERM)
- Virtual environment paths (VIRTUAL_ENV)
- Google Cloud credentials
-
Lifecycle: Container is automatically removed on exit (
--rm flag)
Volume Mounts
By default, these are mounted:
# Working directory
/path/to/project -> /path/to/project (inside container)
# User settings
~/.qwen -> /home/node/.qwen
# Temporary directory
/tmp -> /tmp
# Google Cloud config (if exists)
~/.config/gcloud -> ~/.config/gcloud:ro
UID/GID Handling
On Linux, Qwen Code automatically matches the host user’s UID/GID to prevent permission issues:
// From packages/cli/src/utils/sandbox.ts:68
async function shouldUseCurrentUserInSandbox(): Promise<boolean> {
const envVar = process.env['SANDBOX_SET_UID_GID']?.toLowerCase().trim();
if (envVar === '1' || envVar === 'true') return true;
if (envVar === '0' || envVar === 'false') return false;
// Default: true on Linux, false elsewhere
if (os.platform() === 'linux') return true;
return false;
}
This creates a user inside the container with matching UID/GID:
# Inside container setup
groupadd -f -g ${gid} qwen
useradd -o -u ${uid} -g ${gid} -d ${homeDir} -s /bin/bash qwen
su -p qwen -c '<command>'
macOS Seatbelt Sandbox
Built-in Profiles
Qwen Code includes six built-in seatbelt profiles:
export SEATBELT_PROFILE=permissive-open # Default
export SEATBELT_PROFILE=permissive-closed
export SEATBELT_PROFILE=permissive-proxied
export SEATBELT_PROFILE=restrictive-open
export SEATBELT_PROFILE=restrictive-closed
export SEATBELT_PROFILE=restrictive-proxied
Profile Locations
- Built-in:
packages/cli/src/utils/sandbox-macos-{profile}.sb
- Custom:
.qwen/sandbox-macos-{profile}.sb (project-specific)
Custom Profile Example
Create .qwen/sandbox-macos-custom.sb:
(version 1)
(deny default)
; Allow reading from project directory
(allow file-read* (subpath (param "TARGET_DIR")))
; Allow writing to temp directory
(allow file-write* (subpath (param "TMP_DIR")))
; Allow network access
(allow network*)
; Allow process execution
(allow process-exec)
Then use it:
export SEATBELT_PROFILE=custom
qwen
Seatbelt Variables
Available in .sb files:
TARGET_DIR: Current working directory
TMP_DIR: System temporary directory
HOME_DIR: User home directory
CACHE_DIR: macOS cache directory
INCLUDE_DIR_0 through INCLUDE_DIR_4: Additional workspace directories
Proxy Support
For sandboxed environments with restricted network access:
Container-Based Proxy
# Proxy command runs in separate container with network access
export QWEN_SANDBOX_PROXY_COMMAND="mitmproxy --mode transparent"
export HTTPS_PROXY=http://localhost:8877
qwen --sandbox
The proxy container:
- Runs on port 8877 by default
- Connected to both host network and internal sandbox network
- Automatically started/stopped with sandbox
macOS Seatbelt Proxy
export QWEN_SANDBOX_PROXY_COMMAND="mitmproxy --mode transparent"
export HTTPS_PROXY=http://localhost:8877
export SEATBELT_PROFILE=permissive-proxied
qwen
Custom Sandbox Images
Building Custom Image
Create .qwen/sandbox.Dockerfile:
FROM node:20-bookworm
# Install additional tools
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
git \
curl \
&& rm -rf /var/lib/apt/lists/*
# Install Python packages
RUN pip3 install --no-cache-dir requests numpy pandas
# Set working directory
WORKDIR /workspace
# Copy entrypoint if needed
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Build and Use
# Build the image
export BUILD_SANDBOX=1
qwen --sandbox
# Or build manually
docker build -t my-qwen-sandbox -f .qwen/sandbox.Dockerfile .
# Use custom image
export QWEN_SANDBOX_IMAGE=my-qwen-sandbox
qwen --sandbox
Startup Scripts
Container Bashrc
Create .qwen/sandbox.bashrc to customize the container environment:
# .qwen/sandbox.bashrc
# This file is sourced inside the sandbox container
# Set up Python virtual environment
if [ -d "venv" ]; then
source venv/bin/activate
fi
# Add project bin to PATH
export PATH="$PWD/bin:$PATH"
# Set up Node.js version
if command -v nvm &> /dev/null; then
nvm use
fi
# Custom aliases
alias ll='ls -la'
alias gs='git status'
This file is automatically sourced on container startup.
Troubleshooting
Permission Issues (Linux)
Problem: Files created in sandbox have wrong ownership.
Solution: Enable UID/GID matching:
export SANDBOX_SET_UID_GID=true
qwen --sandbox
Image Not Found
Problem: Sandbox image 'qwen-code-sandbox' is missing
Solution: Build the sandbox image:
# For linked development builds
export BUILD_SANDBOX=1
qwen --sandbox
# Or pull from registry (if available)
docker pull qwen-code-sandbox:latest
Network Access Issues
Problem: Container cannot access network.
Solution: Check Docker/Podman network configuration:
# Test network access
qwen --sandbox -- curl -I https://google.com
# Check network mode
docker inspect <container-name> | grep NetworkMode
Virtual Environment Issues
Problem: Python venv not working in sandbox.
Solution: The sandbox creates a separate venv directory:
# In .qwen/sandbox.bashrc
if [ ! -d ".qwen/sandbox.venv/bin" ]; then
python3 -m venv .qwen/sandbox.venv
fi
source .qwen/sandbox.venv/bin/activate
Port Binding Issues
Problem: Cannot access exposed ports.
Solution: Ensure ports are properly exposed:
# Expose ports
export SANDBOX_PORTS="3000,8080"
# Verify port mapping
docker ps
# Should show: 0.0.0.0:3000->3000/tcp
macOS Seatbelt Issues
Problem: Seatbelt denies file access.
Solution: Use a more permissive profile or create custom profile:
# Use permissive profile
export SEATBELT_PROFILE=permissive-open
# Check sandbox logs
log stream --predicate 'process == "sandbox-exec"'
Security Considerations
Container Isolation
- Containers run with
--init flag for proper signal handling
- Containers auto-removed on exit (
--rm)
- Host Docker socket NOT mounted by default
- Network can be restricted using internal networks + proxy
Seatbelt Isolation
- File system access restricted to defined paths
- Network access can be blocked in restrictive profiles
- Process execution can be limited
Best Practices
- Use restrictive profiles in production
- Mount only necessary paths with appropriate permissions (ro/rw)
- Review custom Dockerfiles before building
- Use proxy mode for network filtering
- Keep sandbox images updated with security patches
Integration Tests
For testing with sandbox enabled:
export QWEN_CODE_INTEGRATION_TEST=true
export QWEN_SANDBOX=docker
qwen --test
Integration test mode:
- Uses unique container names with random suffixes
- Supports checkpoint/resume functionality
- Handles temporary file cleanup
Advanced Topics
Multiple Workspaces
Mount additional workspace directories:
export SANDBOX_MOUNTS="/workspace1:/ws1:ro,/workspace2:/ws2:rw"
Custom Entrypoint
Override container entrypoint:
export SANDBOX_FLAGS="--entrypoint /custom-entrypoint.sh"
Resource Limits
export SANDBOX_FLAGS="--cpus=2 --memory=4g --memory-swap=8g"
Debug Mode
Enable debugging:
export DEBUG=true
export DEBUG_PORT=9229
qwen --sandbox
# Debugger listening on 0.0.0.0:9229
Source Code References
- Sandbox implementation:
packages/cli/src/utils/sandbox.ts
- Sandbox config:
packages/cli/src/config/sandboxConfig.ts
- Seatbelt profiles:
packages/cli/src/utils/sandbox-macos-*.sb