第 16 讲:沙箱隔离(bwrap / Landlock / Seatbelt / e2b)

DeepSeek Harness 源码解析 · 第 16 讲

DeepSeek Harness 源码解析系列 第 16 讲:沙箱隔离(bwrap / Landlock / Seatbelt / e2b) 基于 DeepSeek Harness 源码 · 2026-08-31 💡 本讲一句话: Agent 要执行命令,但绝不能让它碰坏宿主机。DeepSeek Harness 把"隔离"做成一个能力缝(capability seam):上层只声明"这次调用允许写哪里",底层按平台挑 runner——Linux 用 bwrap/Landlock、macOS 用 Seatbelt、Windows 用 ACL 受限令牌、远端直接换到 e2b microVM。读完整篇你能带走三件事: fail-closed 的选型链 (没有可用隔离就拒绝执行)、 三种内核方言如何表达同一份策略 ,以及 "命令失败"和"被沙箱拦截"为什么必须分开归因 。 一、能力缝:先定义"隔离"长什么样 第 14 讲我们拆过 subprocess 怎么 spawn、怎么收尸;但 spawn 之前还有一道闸门—— 这条命令允许碰哪些文件 。这道闸门就是 sandbox 能力缝,它的 Service Definition 在 packages/sandbox/sandbox/src/index.ts 。先看它给"模式"下的定义: 📄 packages/sandbox/sandbox/src/index.ts(第 29-52 行) export type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access' /** A confining (non-danger-full-access) mode — the modes a SandboxPolicy can carry. */ export type ConfinedSandboxMode = Exclude<SandboxMode, 'danger-full-access'> export interface SandboxExecutionPolicy { /** The file-effect mode this execution runs under. */ mode: SandboxMode /** Absolute root directory workspace-write may write under. */ workspaceRoot: string /** Opaque identity of the calling session; backends key per-session state off it. */ sessionId?: SessionId } 为什么这样设计: 整个词汇表只有三个模式,而且刻意 不含网络、进程可见性 ——注释里明说 "Network and process visibility are outside this vocabulary"。这是刻意的收缩:沙箱只承诺"文件效果"这一件事,把边界画小才能画牢。三档是严格递增的梯子: read-only (只能写 /dev/null 这类必需 sink)→ workspace-write (额外允许工作区 + 后端定义的临时区)→ danger-full-access (绕过隔离)。 再看 confine() 的返回值——这是整条缝里信息量最大的一个类型: 📄 packages/sandbox/sandbox/src/index.ts(第 95-116 行) export interface ConfinedArgv { /** The wrapped argv (runner, profile, separator, then the caller's argv). */ argv: string[] /** How completely the selected backend enforces the policy's file effects. */ enforcement: SandboxEnforcement /** * The selected backend's denial DIALECT…

阅读全文:DeepSeek Harness 源码解析 第 16 讲