Files
qiming/qimingclaw/crates/agent-electron-client/docs/sandbox/ARCHITECTURE.md

17 KiB
Raw Permalink Blame History

QimingClaw Agent 沙箱架构设计

版本: 1.1.1 更新日期: 2026-04-10 状态: 已实现(持续迭代)


1. 概述

1.1 目标

为 QimingClaw Agent Electron 客户端提供一个安全、可配置、开箱即用的沙箱执行环境。

1.2 设计原则

原则 说明 实现方式
多平台支持 macOS / Linux / Windows PlatformAdapter 统一抽象 + 各平台实现
可配置 用户可控制是否启用 四种模式配置
开箱即用 无需手动安装依赖 预编译 + 系统内置
渐进增强 自动选择最优方案 平台检测 + 降级
安全隔离 保护用户系统安全 系统级沙箱

2. 架构设计

2.1 整体架构

┌─────────────────────────────────────────────────────────────┐
│                    QimingClaw 沙箱架构                          │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Layer 1: 配置管理 (SandboxConfig)                           │
│  ├─ 模式: off / on-demand / non-main / all                  │
│  ├─ 存储: electron-store                                    │
│  └─ UI: 设置界面 + 首次引导                                  │
│                                                              │
│  Layer 2: 平台抽象 (PlatformAdapter)                         │
│  ├─ 统一平台能力isWindows/isMacOS/isLinux               │
│  ├─ 统一命令探测与路径分隔符                                 │
│  ├─ 统一 helper/bwrap 资源解析                               │
│  └─ 统一推荐 backend/type                                    │
│                                                              │
│  Layer 3: 沙箱实现 (SandboxInterface)                        │
│  ├─ macOS: sandbox-exec (系统内置)                          │
│  ├─ Linux: bubblewrap (系统可用)                            │
│  ├─ Windows: Codex Sandbox (预编译二进制)                   │
│  └─ None: 无沙箱 (关闭模式)                                 │
│                                                              │
│  Layer 4: 权限管理 (PermissionManager)                       │
│  ├─ 权限检查                                                 │
│  ├─ 用户审批                                                 │
│  └─ 审计日志                                                 │
│                                                              │
└─────────────────────────────────────────────────────────────┘

2.2 目录结构

qiming-agent/
├── crates/
│   ├── qiming-sandbox/              # 沙箱源码(独立维护)
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── LICENSE (Apache-2.0)
│   │   │
│   │   ├── crates/
│   │   │   ├── windows-sandbox/    # Windows 实现(基于 Codex
│   │   │   │   ├── Cargo.toml
│   │   │   │   ├── src/
│   │   │   │   │   ├── lib.rs
│   │   │   │   │   ├── sandbox.rs
│   │   │   │   │   ├── process.rs
│   │   │   │   │   └── network.rs
│   │   │   │   └── tests/
│   │   │   │
│   │   │   ├── macos-sandbox/      # macOS 封装
│   │   │   └── linux-sandbox/      # Linux 封装
│   │   │
│   │   ├── bindings/               # Node.js 绑定
│   │   │   ├── package.json
│   │   │   ├── native/             # .gitignore
│   │   │   └── index.ts            # TypeScript 封装
│   │   │
│   │   └── prebuilt/               # 预编译产物(入库)
│   │       ├── darwin-x64/
│   │       ├── linux-x64/
│   │       └── win32-x64/
│   │           ├── index.node
│   │           └── qiming-sandbox.exe
│   │
│   └── agent-electron-client/
│       ├── docs/sandbox/           # 沙箱文档
│       │   ├── ARCHITECTURE.md     # 本文档
│       │   ├── IMPLEMENTATION.md   # 实施指南
│       │   └── API.md              # API 文档
│       │
│       ├── scripts/
│       │   └── prepare-sandbox.ts  # 复制预编译产物
│       │
│       └── resources/
│           └── sandbox/            # 运行时产物(不入库)
│               ├── darwin-x64/
│               ├── linux-x64/
│               └── win32-x64/
│                   └── qiming-sandbox.exe

2.3 统一平台抽象v1.1.1

src/main/services/system/platformAdapter.ts 提供统一平台能力抽象:

  • createPlatformAdapter():统一 darwin/linux/win32 分支入口
  • getCommandProbe():统一 which/where 命令探测
  • getRecommendedSandboxBackend()/Type():统一 backend/type 推荐
  • resolveBundledLinuxBwrapPath():统一 Linux bwrap 内置路径解析
  • resolveBundledSandboxHelperPath():统一 helper 内置路径解析

当前已接入 sandbox 关键链路:

  • system/shellEnv.ts
  • sandbox/policy.ts
  • sandbox/SandboxManager.ts
  • sandbox/serviceBootstrap.ts
  • sandbox/SandboxInvoker.ts
  • engines/acp/acpTerminalManager.ts
  • engines/acp/acpClient.ts
  • engines/acp/strictPermissionGuard.ts
  • utils/processTree.ts

3. 平台实现方案

3.1 macOS: sandbox-exec

技术: Seatbelt (sandbox-exec)

优势:

  • 系统内置macOS 10.5+
  • 零依赖
  • 性能最优(~5% 开销)

配置示例:

(version 1)
(allow default)

; 允许网络访问(白名单)
(allow network-outbound
  (remote tcp "github.com" 443)
  (remote tcp "npmjs.org" 443)
)

; 工作区读写
(allow file-read* (subpath "/Users/.../workspace"))
(allow file-write* (subpath "/Users/.../workspace"))

; 禁止敏感目录
(deny file-read* (subpath "~/.ssh"))
(deny file-read* (subpath "~/.aws"))

开箱即用:


3.2 Linux: bubblewrap

技术: bubblewrap (bwrap)

优势:

  • 主流发行版可用
  • 轻量级(~5% 开销)
  • 命名空间隔离

依赖安装:

# Debian/Ubuntu
sudo apt install bubblewrap socat ripgrep

# Fedora
sudo dnf install bubblewrap socat ripgrep

# Arch Linux
sudo pacman -S bubblewrap socat ripgrep

执行示例:

bwrap \
  --ro-bind /usr /usr \
  --bind /workspace /workspace \
  --unshare-all \
  --die-with-parent \
  bash -c "command"

开箱即用:


3.3 Windows: Codex Sandbox

技术: Rust + Windows API

来源: OpenAI Codex (Apache-2.0)

优势:

  • 完整复用 Codex 实现
  • 预编译二进制
  • Windows 原生 API

实现特性:

  • Job Objects (进程管理)
  • Restricted Tokens (权限限制)
  • Network Proxy (网络过滤)
  • Seccomp-like (系统调用过滤)

开箱即用: (预编译提供)


4. 配置系统

4.1 沙箱模式

启用/禁用SandboxPolicy

模式 主会话 其他会话 安全性 便利性 适用场景
off 无沙箱 无沙箱 完全信任环境
on-demand 询问 询问 混合场景
non-main 无沙箱 有沙箱 推荐默认
all 有沙箱 有沙箱 高安全需求

严格度模式SandboxMode

v0.10+ 新增,跨平台统一接口,各平台实现语义有差异。

Mode 说明 默认
compat 兼容优先,平衡安全与可用性 默认
strict 最小权限,最大限制
permissive 宽松模式,仅排障用途

各平台实现差异

平台 strict compat permissive
Linux (bwrap) 最小 ro-bind/usr /bin /sbin /lib /lib64 /etc /opt /usr/local 全局 ro-bind --ro-bind / / 完整 rw bind无 namespace 隔离
macOS (seatbelt) exec allowlist 仅命令本身(不含 startupExecAllowlist exec allowlist 含启动链 全局 file-write + unrestricted process-exec
Windows (helper run) writable_roots 仅首个路径workspace-first+ WRITE_RESTRICTEDAPPDATA 不在 ALLOW ACEs writable_roots 全部 + WRITE_RESTRICTEDAPPDATA 在 ALLOW ACEs writable_roots 全部 + --no-write-restricted
Windows (helper serve) --write-restricted,仅 workspace + TEMP/TMP --write-restrictedworkspace + TEMP/TMP + APPDATA 无 WRITE_RESTRICTED进程级不限制写入

v1.1.0 变更: Windows serve 子命令新增 --write-restricted flag。 Policy JSON 新增 sandbox_mode 字段Rust helper 的 compute_allow_paths() 根据此字段 决定是否将 APPDATA/LOCALAPPDATA 加入 ALLOW ACEs。 strict 模式下 APPDATA 不可写进程级真正限制compat 模式下可写。

v1.1.1 同步:

  1. macOS strict 的 seatbelt exec allowlist 不再纳入 startup chain仅命令本身
  2. Windows helper run strict 下 writable_roots 仅保留首个路径workspace-first
  3. 平台分支入口统一收敛到 PlatformAdapter

qimingcode 在 strict 模式下还包含 ACP 权限层的二次写入门控(strictPermissionGuard 写入路径必须位于 workspace/temp/isolatedHomestrict 下不含 appData 路径缺失时 fail-closed写入权限仅 allow_once

qimingcode warmup 复用同样受 sandbox policy 约束warmup 会记录 policy 指纹, 当用户修改 sandbox mode/policy 后,若指纹不一致则立即放弃复用并冷启动新引擎。

4.2 配置结构

interface SandboxConfig {
  // 沙箱类型
  type: SandboxType;
  // 运行平台
  platform: Platform;
  // 是否启用
  enabled: boolean;
  // 工作区根目录
  workspaceRoot: string;
  // 沙箱严格度模式v0.10+
  mode?: "strict" | "compat" | "permissive";

  // 网络策略
  networkEnabled?: boolean;

  // 资源限制
  memoryLimit?: string;
  cpuLimit?: number;
  diskQuota?: string;
}

4.3 默认配置

const DEFAULT_SANDBOX_CONFIG: SandboxConfig = {
  mode: "non-main",
  
  platform: {
    darwin: { enabled: true, type: "seatbelt" },
    linux: { enabled: true, type: "bubblewrap" },
    win32: { enabled: true, type: "codex" },
  },
  
  network: {
    enabled: true,
    allowedDomains: [
      "github.com",
      "*.github.com",
      "npmjs.org",
      "registry.npmjs.org",
      "pypi.org",
    ],
    deniedDomains: [],
  },
  
  filesystem: {
    allowRead: ["."],
    denyRead: ["~/.ssh", "~/.aws", "~/.gnupg"],
    allowWrite: [".", "/tmp"],
    denyWrite: [".env", "*.pem", "*.key"],
  },
  
  resources: {
    memory: "2g",
    cpu: 2,
    timeout: 300,
  },
  
  preferences: {
    showNotifications: true,
    askForDangerousOps: true,
    auditLogging: true,
  },
};

5. 统一 API

5.1 SandboxInterface

interface SandboxInterface {
  // 初始化沙箱
  initialize(config: SandboxConfig): Promise<void>;
  
  // 执行命令
  execute(
    command: string,
    cwd: string,
    options?: ExecuteOptions
  ): Promise<ExecuteResult>;
  
  // 文件操作
  readFile(sessionId: string, path: string): Promise<string>;
  writeFile(sessionId: string, path: string, content: string): Promise<void>;
  
  // 状态查询
  isAvailable(): Promise<boolean>;
  getStatus(): SandboxStatus;
  
  // 生命周期
  cleanup(): Promise<void>;
}

interface ExecuteOptions {
  timeout?: number;
  signal?: AbortSignal;
  onOutput?: (data: string) => void;
}

interface ExecuteResult {
  exitCode: number;
  stdout: string;
  stderr: string;
}

interface SandboxStatus {
  available: boolean;
  type: "seatbelt" | "bubblewrap" | "codex" | "none";
  platform: string;
  version?: string;
}

5.2 自动选择实现

class AutoSandbox implements SandboxInterface {
  private sandbox: SandboxInterface;
  
  async initialize(config: SandboxConfig): Promise<void> {
    const platform = os.platform();
    
    switch (platform) {
      case "darwin":
        this.sandbox = new MacSandbox();
        break;
      case "linux":
        this.sandbox = new LinuxSandbox();
        break;
      case "win32":
        this.sandbox = new WindowsSandbox();
        break;
      default:
        this.sandbox = new NoneSandbox();
    }
    
    await this.sandbox.initialize(config);
  }
  
  // 代理所有接口方法...
}

6. 构建和发布

6.1 构建流程

# 1. 构建 Rust 沙箱(所有平台)
cd crates/qiming-sandbox
make build

# 或构建特定平台
make build-darwin
make build-linux
make build-windows

# 2. 复制到预编译目录
make prebuilt

# 3. 准备 Electron 资源
cd ../agent-electron-client
npm run prepare:sandbox

6.2 Makefile

# crates/qiming-sandbox/Makefile

.PHONY: build clean prebuilt

build:
	cargo build --release
	cd bindings && npm run build

build-darwin:
	cargo build --release --target x86_64-apple-darwin
	cd bindings && npm run build -- --target x86_64-apple-darwin

build-linux:
	cargo build --release --target x86_64-unknown-linux-gnu
	cd bindings && npm run build -- --target x86_64-unknown-linux-gnu

build-windows:
	cargo build --release --target x86_64-pc-windows-msvc
	cd bindings && npm run build -- --target x86_64-pc-windows-msvc

prebuilt: build
	mkdir -p prebuilt/darwin-x64
	mkdir -p prebuilt/linux-x64
	mkdir -p prebuilt/win32-x64
	
	cp target/release/qiming-sandbox prebuilt/darwin-x64/ || true
	cp target/release/qiming-sandbox prebuilt/linux-x64/ || true
	cp target/x86_64-pc-windows-msvc/release/qiming-sandbox.exe prebuilt/win32-x64/ || true
	
	cp bindings/native/*.node prebuilt/darwin-x64/ || true
	cp bindings/native/*.node prebuilt/linux-x64/ || true
	cp bindings/native/*.node prebuilt/win32-x64/ || true

clean:
	cargo clean
	rm -rf bindings/native/*.node
	rm -rf prebuilt/*

6.3 prepare-sandbox.ts

// scripts/prepare-sandbox.ts

import * as fs from "fs";
import * as path from "path";

const SANDBOX_SRC = path.join(__dirname, "..", "..", "qiming-sandbox", "prebuilt");
const SANDBOX_DEST = path.join(__dirname, "..", "resources", "sandbox");

const PLATFORM = process.platform;
const ARCH = process.arch;

function prepareSandbox(): void {
  const sourceDir = path.join(SANDBOX_SRC, `${PLATFORM}-${ARCH}`);
  const targetDir = path.join(SANDBOX_DEST, `${PLATFORM}-${ARCH}`);
  
  fs.mkdirSync(targetDir, { recursive: true });
  
  if (fs.existsSync(sourceDir)) {
    const files = fs.readdirSync(sourceDir);
    files.forEach(file => {
      fs.copyFileSync(
        path.join(sourceDir, file),
        path.join(targetDir, file)
      );
    });
    console.log(`✅ Sandbox binaries copied for ${PLATFORM}-${ARCH}`);
  } else {
    console.log(` No sandbox binaries needed for ${PLATFORM}-${ARCH}`);
    fs.writeFileSync(path.join(targetDir, ".gitkeep"), "");
  }
}

prepareSandbox();

7. 许可证

7.1 许可证兼容性

项目 许可证 兼容性
Codex Apache-2.0
QimingClaw Apache-2.0 / MIT
qiming-sandbox Apache-2.0

7.2 版权声明

Copyright 2024-2026 QimingClaw Team

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

---

This project includes code from OpenAI Codex:
https://github.com/openai/codex

Original copyright notice:
Copyright 2024 OpenAI

Licensed under the Apache License, Version 2.0

8. 致谢

本沙箱方案基于以下开源项目:

  • OpenAI Codex - Windows Sandbox 实现
  • Anthropic - @anthropic-ai/sandbox-runtime
  • LobsterAI - QEMU 虚拟机沙箱参考
  • pi-mono - 配置系统参考

9. 参考


文档版本: 1.0.0 最后更新: 2026-03-27