云计算百科
云计算领域专业知识百科平台

7大开源Agent源码对比解读——安全与权限控制

7大开源Agent源码对比解读——安全与权限控制

本文是「7大开源Agent源码对比解读」系列第 10 篇,也是本系列的收尾篇。评估对象:codex、gemini-cli、qwen-code、opencode、kimi-code、deepseek-harness(下称 dsh)、oh-my-pi(下称 omp)。

篇文章内容速览
总述 拆了七大开源 Agent 的源码,最高分竟然不是 Codex 总体结论、评估方法与评分卡
01 架构对比 四种流派与分化根源、主循环与事件机制、插件化与耦合风险
02 上下文管理 压缩触发阈值、摘要方式、token 计数口径、跨会话记忆
03 会话管理 持久化模型三层次、并发控制、崩溃恢复与 resume / fork
04 工具调用 注册与可见性、并行调度四种语义、审批门控、错误处理
05 重连与容错 重试预算、流中断处理、降级链、副作用安全
06 系统提示词与指令遵循 四种组装范式、动态注入、注入防御三层与共同敞口
07 思维链与工作流编排 思维链接入、plan 模式语义、子代理治理、工作流引擎
08 性能设计 前缀缓存三档分化、启动优化、成本核算
09 可扩展性 MCP 接入、自定义工具、多 provider、SDK 与 API
10 安全与权限控制 沙箱两种语义、审批默认姿态、企业管控、敏感数据保护

七个项目的安全层次两极分化:codex 和 gemini-cli 构成第一梯队,前者有三平台原生沙箱加网络代理加完整企业管控链,后者有六级策略引擎加六种沙箱后端;另一端,opencode 在 SECURITY.md 里明确声明不提供沙箱,omp 出厂默认全自动批准。读安全设计之前,先要澄清「沙箱」这个词的两种语义。

先澄清:两种正交的隔离

七家说的「沙箱」其实指两种完全不同的隔离,选型时必须分清:

系统调用与进程隔离(codex、gemini-cli、qwen-code、dsh):用 OS 原生机制约束子进程能做什么,能调哪些系统调用、能访问哪些路径、能连哪些网络。防的是「agent 逃逸到系统」。

工作区文件系统视图隔离(omp 的 pi-iso):给子代理一个工作区的写时复制副本干活,产物 diff 回主工作区。约束的是「改动落在哪」,不约束系统调用。子代理在副本里仍能任意执行命令,只是改不坏用户仓库。防的是「agent 改坏仓库」。

两者正交,理想方案是叠加。比如 omp 若补一层 Landlock,隔离就完整了。

#mermaid-svg-rs9poj4AeGfdDLPp{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rs9poj4AeGfdDLPp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rs9poj4AeGfdDLPp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rs9poj4AeGfdDLPp .error-icon{fill:#552222;}#mermaid-svg-rs9poj4AeGfdDLPp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rs9poj4AeGfdDLPp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rs9poj4AeGfdDLPp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rs9poj4AeGfdDLPp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rs9poj4AeGfdDLPp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rs9poj4AeGfdDLPp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rs9poj4AeGfdDLPp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rs9poj4AeGfdDLPp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rs9poj4AeGfdDLPp .marker.cross{stroke:#333333;}#mermaid-svg-rs9poj4AeGfdDLPp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rs9poj4AeGfdDLPp p{margin:0;}#mermaid-svg-rs9poj4AeGfdDLPp .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-rs9poj4AeGfdDLPp .cluster-label text{fill:#333;}#mermaid-svg-rs9poj4AeGfdDLPp .cluster-label span{color:#333;}#mermaid-svg-rs9poj4AeGfdDLPp .cluster-label span p{background-color:transparent;}#mermaid-svg-rs9poj4AeGfdDLPp .label text,#mermaid-svg-rs9poj4AeGfdDLPp span{fill:#333;color:#333;}#mermaid-svg-rs9poj4AeGfdDLPp .node rect,#mermaid-svg-rs9poj4AeGfdDLPp .node circle,#mermaid-svg-rs9poj4AeGfdDLPp .node ellipse,#mermaid-svg-rs9poj4AeGfdDLPp .node polygon,#mermaid-svg-rs9poj4AeGfdDLPp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rs9poj4AeGfdDLPp .rough-node .label text,#mermaid-svg-rs9poj4AeGfdDLPp .node .label text,#mermaid-svg-rs9poj4AeGfdDLPp .image-shape .label,#mermaid-svg-rs9poj4AeGfdDLPp .icon-shape .label{text-anchor:middle;}#mermaid-svg-rs9poj4AeGfdDLPp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rs9poj4AeGfdDLPp .rough-node .label,#mermaid-svg-rs9poj4AeGfdDLPp .node .label,#mermaid-svg-rs9poj4AeGfdDLPp .image-shape .label,#mermaid-svg-rs9poj4AeGfdDLPp .icon-shape .label{text-align:center;}#mermaid-svg-rs9poj4AeGfdDLPp .node.clickable{cursor:pointer;}#mermaid-svg-rs9poj4AeGfdDLPp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rs9poj4AeGfdDLPp .arrowheadPath{fill:#333333;}#mermaid-svg-rs9poj4AeGfdDLPp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rs9poj4AeGfdDLPp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rs9poj4AeGfdDLPp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rs9poj4AeGfdDLPp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rs9poj4AeGfdDLPp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rs9poj4AeGfdDLPp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rs9poj4AeGfdDLPp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rs9poj4AeGfdDLPp .cluster text{fill:#333;}#mermaid-svg-rs9poj4AeGfdDLPp .cluster span{color:#333;}#mermaid-svg-rs9poj4AeGfdDLPp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rs9poj4AeGfdDLPp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rs9poj4AeGfdDLPp rect.text{fill:none;stroke-width:0;}#mermaid-svg-rs9poj4AeGfdDLPp .icon-shape,#mermaid-svg-rs9poj4AeGfdDLPp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rs9poj4AeGfdDLPp .icon-shape p,#mermaid-svg-rs9poj4AeGfdDLPp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rs9poj4AeGfdDLPp .icon-shape .label rect,#mermaid-svg-rs9poj4AeGfdDLPp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rs9poj4AeGfdDLPp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rs9poj4AeGfdDLPp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rs9poj4AeGfdDLPp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

正交,理想是叠加

无 OS 沙箱

kimi-code:靠工具层敏感文件过滤兜底

opencode:SECURITY.md 明示不提供隔离

工作区视图隔离 —— 防「agent 改坏仓库」

omp pi-iso:工作区 CoW 副本,产物 diff 回主区,APFS / overlayfs / btrfs / zfs / ProjFS 等 8 种后端

系统调用 / 进程隔离 —— 防「agent 逃逸到系统」

codex:Seatbelt / Landlock+seccomp / Win 受限令牌,另有 MITM 网络代理

gemini-cli:docker / podman / sandbox-exec / runsc / lxc / win-native

qwen-code:Docker 镜像 + 6 套 macOS Seatbelt profile

dsh:bwrap / Landlock / Seatbelt / Win ACL,仅文件效果,不含网络

OS 沙箱对比

项目沙箱方案
codex Seatbelt / Landlock+seccomp / Win 受限令牌,三平台原生
gemini-cli 6 个沙箱命令:docker、podman、sandbox-exec、runsc、lxc、windows-native
qwen-code Docker 镜像 + macOS 6 套 Seatbelt profile(2 策略 × 3 网络模式)
opencode 无,SECURITY.md 明示
kimi-code 无 OS 沙箱
dsh bwrap、Landlock、Seatbelt、Win ACL,仅文件效果
omp pi-iso 工作区隔离,8 种后端(APFS、overlayfs、btrfs、zfs、ProjFS 等)

几个值得展开的实现:

codex 的三平台原生指三个平台各用一套原生机制,不走容器化:macOS Seatbelt、Linux Landlock 加 seccomp、Windows 受限令牌(sandboxing/src/manager.rs:36-76)。

gemini-cli 的自动探测:getSandboxCommand() 按平台自动选后端,macOS 优先 sandbox-exec,否则 docker 或 podman(sandboxConfig.ts:43-109)。六种命令覆盖了从容器到 gVisor 再到原生令牌的强度梯度。

dsh 的能力收窄是有意声明:沙箱词汇表只管文件读写效果,网络访问和进程可见性明确写在「不在词汇表内」(sandbox/src/index.ts:27)。声明边界比含糊覆盖更诚实,但网络不管确实是短板。

omp 的 pi-iso 是跨平台抽象层:每个后端给出「只读下层树的可写合并视图」,不做深拷贝。macOS 用 APFS clonefile,Linux 用 overlayfs(fallback 到 fuse-overlayfs)、btrfs 快照、zfs、reflink,Windows 用 ProjFS 和块克隆,都不支持就走 git worktree 或递归拷贝(pi-iso/src/lib.rs:47-66)。diff 模块在 merged 视图是 git 仓库时委托 git diff 产出字节级补丁。

网络管控

只有 codex 做了完整的网络层:独立的网络代理 crate 在沙箱内拦截子进程的 HTTPS 流量(MITM),按域名白黑名单放行或阻断;凭据代理在转发时注入认证(内置 GitHub 和 OpenAI 两个 provider),子进程既不直接持有密钥,也不能随意联网(network-proxy/src/)。域名策略同时进提示词,模型能看到 <network> 标签下的允许与拒绝列表。

其余项目的网络管控基本空白:qwen 的 macOS profile 有三档网络模式,kimi 的 kap-server 有回环绑定加 bearer token,都是局部措施。

审批默认姿态谱系

从紧到松排列:

项目默认姿态缺省行为
dsh ask fail-closed:审批支持缺席时,ask 转 deny
codex OnRequest 未受信项目用 UnlessTrusted,要求审批
opencode ask 无匹配规则即弹窗询问
gemini-cli default 策略引擎裁决,缺省询问
qwen-code AUTO LLM 分类器动态裁决
kimi-code manual hooks 超时放行(fail-open)
omp yolo 全自动批准

给非专家用户做产品的项目必须改默认值。omp 和 kimi 的姿态适合开发者自用,放进托管服务就是事故。

逐家安全特色

codex:完整的企业管控链

配置栈有 9 层 ConfigLayerSource,按优先级从打包默认、MDM 下发、系统级、企业托管、用户、项目到会话 flag(config_layer_source.rs:6-49),再叠加同序的 requirements 层。requirements.toml 承载企业需求(权限、文件系统),MDM 有两个接入变体。这是七家中唯一能对接企业设备管理的完整链条。

审批侧配了独立的 guardian 评审器和审批缓存(见工具调用篇)。凭据用系统 keyring 加密存储,进程加固保证凭据不进子进程环境。漏洞报告走 Bugcrowd。

gemini-cli:策略引擎与 Always-Allow 收窄

五级策略带:Admin > User > Workspace > Extension > Default,高 tier 覆盖低 tier(policy/config.ts:66-71)。

Always-Allow 的收窄做得细:用户对某个 exec 命令选「始终允许」,只对该命令前缀放行;对编辑操作,只对该文件路径模式放行;对 MCP 工具,收窄到该服务器的所有工具(scheduler/policy.ts:207-273),没有一放全放。

safety checker 是正则型工具参数规则,从 TOML 加载,编译时做 ReDoS 防护。一条安全边界:扩展不能为 YOLO 模式贡献 safety checker,尝试会被忽略并记录。漏洞报告走 Google VRP,5 个工作日响应。

一个常见误解要澄清:gemini-cli 没有硬编码屏蔽 .env。沙箱禁用路径来自用户的 .geminiignore,.git 是指令文件遍历的边界标记,与安全屏蔽无关。

qwen-code:AUTO 分类器与密钥防入库

AUTO 模式的四道门槛(编辑快速通道、安全工具白名单、破坏性命令正则硬阻断、两阶段 LLM 分类器)见工具调用篇。安全侧的重点在记忆:

  • secret-scanner:gitleaks 规则子集扫描记忆内容,命中高置信凭证模式就阻止写入。
  • 团队记忆守卫:团队记忆目录会提交进仓库共享给所有协作者,任何写入前必扫密钥,命中无条件拒绝,日志只记规则 ID 不记匹配内容,因为匹配内容本身就是密钥(team-memory-secret-guard.ts:18-33)。
  • trusted folders:未受信工作区下,MCP 和扩展安装被门控。

opencode:把边界写清楚

SECURITY.md 的威胁模型直说:权限系统是 UX 特性,帮助用户了解 agent 在做什么,不提供安全隔离;需要真正隔离就在 Docker 或 VM 里跑。.env 和 .env.* 的读取默认需要确认,.env.example 放行。拒绝声明比虚假的安全感有价值。改进空间是至少提供官方容器化运行模板。

kimi-code:敏感文件硬过滤

七家中唯一把「防提示注入外泄凭据」落到工具策略代码的设计:.env、id_rsa、id_ed25519、credentials、.aws/credentials 等模式的文件被屏蔽 Read/Write/Edit,带 .bak、.pem、.key、.old 后缀的变体也覆盖,.env.example 和 .pub 公钥豁免(tools/policies/sensitive.ts:8-53)。模块注释写明目标:「被注入的 prompt 无法通过工具外泄凭据」。模式列表故意保持小,避免误报。

这个方案便宜、有效、可抄。其余项目要么靠沙箱的网络拒绝做最后防线(codex),要么没有。

dsh:凭据引用化与封闭词汇

凭据设计有三条规则:配置文件只存环境变量名(引用),值由 provider 持有;每次操作重新解析引用,不跨操作缓存,凭据变更立即生效;配置界面只描述引用,绝不展示值(credentials/src/index.ts:2-68)。

沙箱升级走封闭词汇:每个模式在执行期检查(不烘焙进工具 schema),非扩权请求永不提示人类,结果词汇是 cancelled、unavailable 这类封闭集,缺失和异常一律归一化为不可用(sandbox/src/escalation.ts)。审批事件成对追加,有提交与回放边界包夹,可审计。

短板是仓内没有独立 SECURITY.md,安全说明散在沙箱子系统的实现笔记里。

omp:默认姿态与可选增强

默认 yolo 已在前面说过,用户配置里的工具级 deny 在 yolo 下仍然生效,这是唯一保留的闸门。secrets 混淆是可选增强:凭据形状的 token 在出站流量做可逆混淆(带 key 的占位符,本地工具执行前还原),默认关闭。工作区隔离用 pi-iso。SECURITY.md 在 .github/ 下,走私密披露,best-effort 响应。

给 Agent 开发者的借鉴清单

  • 选型先分清沙箱语义。 防逃逸(系统调用隔离)和防改坏(工作区隔离)是两回事,供应商宣传的「沙箱」要追问是哪一种,理想是叠加。
  • 托管部署只考虑 fail-closed 的默认姿态。 dsh 的「审批缺席即拒绝」是唯一可以放心托管的缺省语义。
  • 敏感文件硬过滤值得立即抄。 工具层屏蔽 .env 和私钥的读写,是防提示注入外泄最便宜的一道闸(kimi 的 sensitive.ts)。
  • 凭据存引用不存值。 配置里只放环境变量名,每次操作重解析,界面永不展示值(dsh 三条规则)。
  • Always-Allow 必须收窄。 按命令前缀、文件路径模式收窄,一次批准不等于全量放行(gemini-cli)。
  • 破坏性判定用确定性规则前置。 正则硬阻断放在任何模型判断之前(qwen 的教训:分类器误判不能放行破坏性命令)。
  • 网络管控配凭据代理。 沙箱内进程不直接持密钥,转发时注入(codex),密钥泄露面显著缩小。
  • 把安全边界写进文档。 「不提供什么」和「提供什么」同样重要(opencode 的 SECURITY.md 是范本)。
  • 系列小结

    十个板块走下来,七个项目展示了 2026 年开源 Agent Harness 的三条演化路线:向系统要深度(codex、omp 的 Rust 化与沙箱)、向架构要可审计性(dsh、opencode、kimi v2 的事件溯源)、向生态要覆盖面(qwen、kimi 的全端矩阵)。没有全能冠军,对 Agent 开发者最有价值的,是这些项目在各自约束下做出的具体设计。希望这个系列能成为一份可对照源码的参考资料。


    文档地图

    篇文章内容速览
    总述 拆了七大开源 Agent 的源码,最高分竟然不是 Codex 总体结论、评估方法与评分卡
    01 架构对比 四种流派与分化根源、主循环与事件机制、插件化与耦合风险
    02 上下文管理 压缩触发阈值、摘要方式、token 计数口径、跨会话记忆
    03 会话管理 持久化模型三层次、并发控制、崩溃恢复与 resume / fork
    04 工具调用 注册与可见性、并行调度四种语义、审批门控、错误处理
    05 重连与容错 重试预算、流中断处理、降级链、副作用安全
    06 系统提示词与指令遵循 四种组装范式、动态注入、注入防御三层与共同敞口
    07 思维链与工作流编排 思维链接入、plan 模式语义、子代理治理、工作流引擎
    08 性能设计 前缀缓存三档分化、启动优化、成本核算
    09 可扩展性 MCP 接入、自定义工具、多 provider、SDK 与 API
    10 安全与权限控制 沙箱两种语义、审批默认姿态、企业管控、敏感数据保护
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 7大开源Agent源码对比解读——安全与权限控制
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!