close

Volume 2 · Chapter 29

审批、权限与沙箱:模型动作的闸门

这是 harness 的「信任边界」域:审批(approval)拦「要不要做」,权限(permission)管「哪些动作免审批」,沙箱(sandbox)限「做的时候能碰什么」。三者叠在 14 页工具流水线的 pre-execute 与 15/16 页的执行世界上。

(卷一连接点) 14 页 pre-execute 的 ask · 17 页 approveEscalation · 16 页 subprocess 本域:user-approval / permission-presets / sandbox / sandbox-local / sandbox-policy / bash-sandbox / pwsh-sandbox (回心脏) 审批结果决定 14 页流水线 allow/deny/ask

示例本次示例:模型要联网时的升级审批

示例轨迹 29-1 · sandbox_permissions 升级(挂载 bash-sandbox 时)
# 沙箱化 shell 下,模型想 curl 一个外网 URL:
# bash({command:'curl ...', sandbox_permissions:['network']})
# → tool-bash 能力探针:ctx.shell.sandboxMode 非 undefined(17 页 192 行)
# → approveEscalation(17 页 223-227 行)→ approver.request
# → approval/request waterfall(user-approval/src/index.ts:192 的服务)
# → 用户在 UI 看到「模型请求 network 权限」→ 批准/拒绝
# → 批准:本次调用带升级权限执行;拒绝:按原沙箱权限(无网络)执行或失败
# 这是「默认沙箱 + 升级要审批」两段式的完整实例
来源:17 页 223-227 行 + 29 页 §3
示例轨迹 29-2 · 权限预设决定免审还是必审
# 模型:bash('ls -la')(本地 shell,无沙箱升级)
# 14 页 pre-execute → permission-presets(inject=['shell','approval','sessions']):
#   读命令类型 → 「只读命令」→ 预设规则命中 → allow(免审)
# 模型:bash('rm -rf build/') → 「破坏性命令」→ 预设要求审批
#   → PreToolDecision: ask → approval/request → 用户确认
# 预设的「会话记忆」:本会话已批准过的同类命令可跳过(sessions 依赖的用途)
来源:29 页 §3 + permission-presets/src/index.ts:175,196

§1挂载条目

  • approval → @deepseek-ai/dsh-user-approval——审批服务
  • permission → @deepseek-ai/dsh-permission-presets——权限预设(175 行)
  • sandbox → dsh-sandbox-local——本地沙箱
  • sandbox-policy → dsh-sandbox-policy——沙箱策略
  • bash-sandbox / pwsh-sandbox——沙箱化 shell provider(15 页 sandboxMode 的 override 实现)

§2包文件地图

规模角色
packages/interaction/user-approval/ApprovalService extends Service(src/index.ts:192)——approval/request waterfall 的派发方
packages/interaction/permission-presets/PermissionPresetService extends Service(src/index.ts:175),static inject = ['shell', 'approval', 'sessions'](196 行)——预设规则判断「免审还是必审」
packages/sandbox/sandbox-policy/SandboxPolicyService extends Service(src/index.ts:91)——沙箱模式解析
packages/sandbox/sandbox-windows-acl/12 文件 / 2530 行Windows ACL 沙箱实现(平台专用)

§3机制:审批链 → 权限预设 → 沙箱升级

  1. 审批链(14 页的 ask)tools/pre-execute 返回 ask 时,走 approval/request waterfall——用户批准/拒绝。17 页的 approveEscalation(sandbox_permissions 升级)也走它。
  2. 权限预设(免审清单):permission-presets 决定哪些动作默认允许(如只读文件命令)、哪些必审(如写文件)。它的 inject 里同时有 shell 和 approval——预设既看动作类型,也调审批。
  3. 沙箱(执行限制):sandbox-policy 解析当前沙箱模式;bash-sandbox 是沙箱化的 shell provider(override 15 页的 sandboxMode)。Windows 上还有 ACL 沙箱(sandbox-windows-acl,2530 行——平台级能力)。

§4关键代码

packages/interaction/permission-presets/src/index.ts权限预设的依赖面175, 196
175export class PermissionPresetService extends Service {
196  static inject = ['shell', 'approval', 'sessions']
packages/sandbox/sandbox-policy/src/index.ts沙箱策略服务91
91export class SandboxPolicyService extends Service {
175, 196

权限预设的三个依赖面说明它的位置:shell(看命令类型)、approval(发起审批)、sessions(按会话记忆免审状态)。它是「审批的预处理器」。

91

sandbox-policy 是纯策略解析——它不执行沙箱,只决定「哪个沙箱模式生效」。执行者是沙箱化 provider(bash-sandbox 等)。

§5易错点

14 页的坍缩语义与审批的关系:mode: 'code' 下模型调非 run_code 工具,审批 ask 和 guards 都看不到(14 页 createExecution 的注释)——防止策略批准一个必然失败的调用。审批链不是万能的闸门,坍缩检查在它之前。

沙箱升级的审批走 approval/request(17 页 223-227 行)——模型请求 sandbox_permissions 升级时,升级本身是一个审批请求。这形成了「默认沙箱 + 升级要审批」的两段式安全模型。