# 宿主机沙箱与权限系统说明（2026-05）

本文档用于完整说明当前项目在 **宿主机模式（`TERMINAL_SANDBOX_MODE=host`）** 下的安全执行机制，包括：

- OS 级沙箱执行
- 执行环境（Execution Mode）
- 权限模式（Permission Mode）
- 路径授权（Path Authorization）
- `run_command` / `terminal` / `sub_agent` 的实际行为

---

## 1. 设计目标

在保留宿主机开发效率的前提下，降低误操作与越权风险，核心目标是：

1. 默认命令执行必须经过系统沙箱（而非裸 host）
2. 权限控制尽量由执行层强制（减少“猜指令”误判）
3. 对高风险写操作引入用户审批与单次授权机制
4. 保持可运维：可配置、可回退、可解释

---

## 2. 两层控制模型

当前系统分为两层控制，且叠加生效：

### 2.1 权限模式（产品层）

- `readonly`
- `approval`
- `auto_approval`
- `unrestricted`

作用：决定工具是否允许调用、是否先只读执行、是否需要用户审批。

### 2.2 执行环境（系统层）

- `sandbox`（默认）
- `direct`

作用：决定进程最终在 OS 沙箱中执行，还是直接在宿主机执行。

> 推荐默认：`permission_mode=approval` + `execution_mode=sandbox`

---

## 3. OS 级沙箱方案

宿主机模式下，默认执行环境为 `sandbox`，各系统实现如下：

- **macOS**：`sandbox-exec`
- **Linux**：`bubblewrap (bwrap) + seccomp`
- **Windows**：`WSL2`

若宿主机沙箱不可用，关键执行路径会拒绝执行，不允许静默回退到裸 host。

---

## 4. 路径授权模型

路径授权分两类：

1. **可读可写路径（writable_paths）**
2. **仅可读路径（readable_extra_paths）**

语义：

- 可读集合 = 可读可写 + 仅可读
- 可写集合 = 可读可写

前端“路径授权”弹窗支持这两类路径的维护（新增/编辑/删除），并由后端策略模块统一读取。

---

## 5. 各权限模式的实际行为

## 5.1 readonly

- `run_command`：允许调用，但在**只读沙箱**执行
- 若命令触发写入：由系统返回权限拒绝（例如 `Operation not permitted`）
- `write_file` / `edit_file` / 其他写入类工具：直接拒绝

## 5.2 approval

- `run_command` 采用“两段式”：
  1) 先在只读沙箱执行  
  2) 若出现权限拒绝，再发起前端审批  
  3) 审批通过后，仅该次命令以可写沙箱重试
- 工具结果返回“最终执行结果”（即重试后结果），不会把中间权限拒绝作为最终结果返回给模型
- 审批拒绝或超时：返回 rejected，不执行写入重试

## 5.3 auto_approval

- `write_file` / `edit_file`：
  - 目标路径在当前工作区内：直接执行
  - 目标路径不在当前工作区内：进入审批流程
- `run_command` 采用“两段式”：
  1) 先在只读沙箱执行  
  2) 若出现权限拒绝，触发自动审批（审批智能体）  
  3) 自动审批通过后，仅该次命令可写重试
- 自动审批拒绝：返回“工具调用被拒绝 + 原因”，主智能体继续下一步（不强制中断整轮任务）
- 用户可随时人工接管审批结果（同意/拒绝/切换无限制）

## 5.4 unrestricted

- 权限模式层不拦截工具
- 是否沙箱执行取决于执行环境：
  - `sandbox`：仍在 OS 沙箱中执行
  - `direct`：宿主机直接执行

---

## 6. 执行环境（sandbox/direct）细节

## 6.1 sandbox（默认）

- 命令在 OS 沙箱执行
- 配合路径授权限制写边界（与读边界策略）
- 可结合权限模式实现只读优先与单次升级写权限

## 6.2 direct（高权限）

- 命令直接在宿主机执行
- 仅建议临时用于必须操作
- 支持 TTL 自动回退（会话级）到 `sandbox`

---

## 7. 关键工具与执行路径

### 7.1 run_command

- 支持权限模式联动（readonly/approval/unrestricted）
- 在 host + sandbox 下可走只读沙箱或可写沙箱
- 在 approval 模式可触发“权限拒绝 -> 审批 -> 单次可写重试”
- 在 auto_approval 模式可触发“权限拒绝 -> 自动审批 -> 单次可写重试”

### 7.2 terminal 系列

- 终端会话从启动时就在沙箱里（host+sandbox）
- 同一会话中的后续输入继承该会话沙箱上下文
- 若路径授权更新，需要新开终端会话才能让该会话使用新策略

### 7.3 子智能体（sub_agent）

- 宿主机下已接入执行环境策略：
  - `sandbox`：子智能体进程经宿主机沙箱启动
  - `direct`：直接宿主机启动
- Docker 模式维持容器执行

### 7.4 自动审批（approval agent）

- 自动审批由独立审批智能体执行（与主智能体分离）
- 配置文件：`config/auto_approval.json`
  - `name` / `url` / `key` / `model` / `extra_params`
  - `timeout_seconds` / `max_rounds` / `max_command_timeout`
- 审批智能体可调用能力：
  - `run_command`（用于只读核查）
  - 审批决策工具（approved / rejected + reason）
- 调试开关（代码变量）：
  - `modules/approval_agent.py` 中 `DEBUG_SAVE_APPROVAL_AGENT_TRANSCRIPT`
  - 开启后记录到 `logs/approval_agent/`

---

## 8. 配置与运行建议

## 8.1 推荐默认策略

1. `TERMINAL_SANDBOX_MODE=host`
2. 执行环境默认 `sandbox`
3. 权限模式默认 `approval`
4. 路径授权默认最小化（工作区 + 临时目录）

## 8.2 何时使用 direct

仅在以下场景短时开启：

- 明确需要系统级高权限访问
- 沙箱下无法完成且替代方案不可行

执行完成后应尽快回到 `sandbox`。

---

## 9. 已知权衡

1. `run_command` 若严格收紧读路径，可能导致大量系统命令可用性下降  
2. 权限拒绝识别基于错误特征，需持续优化误判/漏判边界  
3. 不同 OS 的沙箱能力不完全对齐（Windows 侧为 WSL2 路径）
4. Docker 模式下目前不存在与宿主机同等的 OS 只读沙箱机制；`sandbox_write_access=False` 不会提供同等级只读隔离（需后续补充容器侧只读策略）

---

## 10. 文案与产品约束

- 面向用户的提示词仅描述“能力边界”和“可操作建议”
- 不暴露内部实现细节（如内部判定逻辑、实现细节名称）
- 审批流程文案要强调“单次授权、最小权限、可回退”
