首页 / DeepSeek Harness 入门教程 / 沙箱与权限审批

DeepSeek Harness 入门教程

沙箱与权限审批

本教程共 32 篇 · 第 16 篇 · 更新于 2026-08-15 · 约 6 分钟阅读

dsh沙箱审批权限预设安全approval

本节目标:搞懂 dsh 怎么约束 Agent 的危险动作——沙箱圈定进程能碰什么文件,审批决定某一次操作能不能做,以及两个机制如何组合成权限预设。

两道闸门,一个问题

Agent 想执行 rm -rf、想删一个文件、想往外发数据,凭什么拦?dsh 给了两道闸门:

  • 沙箱(sandbox):管「命令跑在什么边界里」。它把子进程的 argv 包装起来,按策略限制文件系统效果。
  • 审批(approval):管「这个具体操作是否被允许」。它把问题交给人类或机器应答者,做一次性决策。

一句话:沙箱管边界,审批管授权。两者都默认失败关闭(fail closed)——拿不准就当拒绝处理。

沙箱机制

沙箱的服务是 ctx.sandbox。消费方交出确切的 argv(程序加参数,不是 shell 字符串),沙箱按策略返回替换后的 argv,消费方再 spawn 它。比如 bash 工具会传 ['bash', '-c', command] 这样的形状。

沙箱模式(SandboxMode)只管控文件系统效果,不含网络与进程可见性,共三档:

模式行为
read-only拒绝写入,只允许必需的接收端(如 /dev/null
workspace-write允许在工作区根目录及后端承诺的临时区域下写入
danger-full-access绕过隔离,消费方直接 spawn 原始 argv,根本不进沙箱

注意 danger-full-access 不经过 ctx.sandbox。这保证了一个安全性质:受限执行必然到达沙箱,静默的无隔离透传永远不合法

策略按每次调用解析:普通工具调用从调用会话的不可变 cwd 派生工作区边界;已批准的提权重试可以显式传更宽的模式。没有可用后端时,confine 抛出 SANDBOX_UNAVAILABLE

本地提供方按平台选执行器:Linux 用 bwrap/Landlock,macOS 用 Seatbelt,Windows 用 ACL 受限令牌。后端还会报告强制执行完整度:full(管控了该模式承诺的所有文件效果)或 partial(只管控子集——比如较旧的 Landlock ABI 和 Windows ACL 的 Everyone/硬链接边界)。要求绝对保证的消费方必须把 partial 当「不够」处理。

Note

沙箱还带回两种 stderr 分类器:denialSignatures 识别「沙箱正常工作但拒绝了命令」(bwrap 的 EROFS、Landlock 的 EACCES、Seatbelt 的 EPERM);runnerFailureRules 识别「沙箱 runner 自己没启动」。前者是策略拒绝,后者是基础设施故障,不能混为一谈。

审批流程

审批服务 ctx.approval 回答一个很窄的问题:这个具体操作可以继续吗?

它通过 approval/request waterfall 把问题分发给应答者(answerer)。应答者负责处理就返回结果,不负责就调用 next() 委托;第一个应答者占据唯一的决策槽位。结果类型是闭合的:

结果含义
allowed-once一次性放行,只授权所询问的那一个操作
rejected明确拒绝
cancelled请求被撤回
unavailable无应答者、应答者抛异常或返回值不合规

关键安全性质:缺失应答者产生 unavailable,而不是放行。调用方对 rejectedcancelledunavailable 一律执行拒绝。

每次询问都会记录一对仅日志的审计事件:approval/askedapproval/decided。它们不进入模型可见的 transcript——模型看到的是工具结果和运行时上下文快照,不是审批过程本身。

按会话的审批策略有两种:

策略行为场景
ask(默认)委托给应答者链;无应答者时回退 unavailable交互式 UI,需要人做决定
never确定性返回 rejected,不分发任何应答者CI、无人值守运行
Warning

never 不是「永远允许」,而是「永远不弹审批,所有 ask 一律拒绝」。它是严格的无人值守姿态,不是放行开关。

权限预设

沙箱模式(sandbox/mode)和审批策略(approval/policy)是两个相互独立的旋钮(knob)。ctx.permissionPresets 把它们捆绑成具名预设,客户端(比如 Web 界面右上角的权限下拉框)只需选一个名字:

预设沙箱模式审批策略含义
workspace-writeworkspace-writeask可写工作区,敏感操作问用户
danger-full-accessdanger-full-accessnever绕过沙箱、不询问

预设表是配置驱动的,默认自带上面两个;名字 custom 被保留给「派生的非预设状态」——当两个旋钮的组合不在表里时,界面显示 custom,但它不是可切换目标。

切换预设时,服务会追加一条仅日志的 permission/preset 事件,然后通过每个旋钮自己的 setter 写入。两个预设共享同一个旋钮组合时,这条事件让系统仍能分辨用户选的到底是哪一个。

信任模型

把这三层合起来看,dsh 的信任模型很直白:

  • 默认信任人类:交互模式下 ask,人来做最终决策;
  • 默认不信任无人值守never 确定性拒绝,机器应答者(如 ACP 桥接层)也只做一次性决策;
  • danger-full-access 只配给可丢弃环境:官方事故复盘明确提醒过,绕过沙箱的预设应只用于一次性、可丢弃的沙箱环境,比如 CI 的临时容器。

典型的审批交互长这样:模型想执行一条命令,UI 在已流式输出的工具调用卡片上挂出询问(通过 callId 关联,不重复渲染参数),你点「允许」放行这一次,点「拒绝」或让卡片过期,调用都以拒绝收场。

Tip

排错时先分清是哪道闸门拦的:报 [sandbox: file access denied under <mode> mode] 是沙箱策略拒绝;报审批超时或 unavailable 是审批链的问题。两者修法完全不同。

小结

  • 沙箱管文件效果边界:read-only / workspace-write / danger-full-access,失败关闭。
  • 审批管单次授权:allowed-once 是唯一放行,缺应答者一律 unavailable
  • 权限预设 = 沙箱 + 审批两个旋钮的具名组合,custom 是派生的非预设状态。
  • 信任模型:交互问人,无人值守拒绝,全放行只给可丢弃环境。