文章总结: 本文探讨AIAgent获得系统权限后的安全风险,分析OpenShell与DefenseClaw两种解决方案。OpenShell提供安全运行时环境,通过沙箱、网络代理和策略引擎控制高风险操作;DefenseClaw侧重治理层,实现技能扫描、准入控制和审计流程。文章指出两者互补构成完整防护体系,并引用2025-2026年实际漏洞案例说明Agent安全威胁的紧迫性。 综合评分: 85 文章分类: 漏洞分析,安全建设,解决方案,安全运营,威胁情报
当 Agent 拿到系统权限,谁来管它?OpenShell 与 DefenseClaw的诠释,管控底座与上层治理
原创
qianlan qianlan
帅仔回忆录
2026年4月12日 01:50 浙江
在小说阅读器读本章
去阅读
引言
如果你已经开始把 agent 真正接进工作流,那你有没有过类似时刻:
- 让它帮你整理项目,结果它顺手删掉了不该删的文件。
- 让它修一个小问题,结果它把整个环境配置改乱了。
- 让它装个依赖、跑个命令、访问一个接口,结果它做得比你预期更多。
这些事情最让人头疼的地方,不只是“它做错了”,而是很多时候它错得很快、很自动,而且往往发生在它已经拿到文件、终端、网络和 API 权限之后。
这时候你就会发现,agent 一旦从“会回答问题”变成“会替你动手”,问题的重点就不再只是模型聪不聪明,而是:
当 agent 不再只是回答问题,而是开始替你读文件、跑命令、调 API、访问外网时,我们到底该怎么把它看住?
过去几年,AI 产品的角色变化很快。
最早我们用的是“问答型模型”,主要负责写文案、做总结、解释代码。 再往后,模型开始会调工具、会联网、会访问 API。到了今天, agent 已经越来越像“执行助手”:它们能读仓库、改代码、开终端、访问 GitHub、调用云服务,甚至把整段工作流直接跑完。
问题也正是从这里开始变得不同。
一旦能力从“给建议”变成“替你执行动作”,风险就不再只是“它答错了”,而是:
- 它可能读到不该读的东西:代码仓库、
.env、SSH key、云凭证、浏览器 cookie。 - 它可能执行不该执行的动作:安装依赖、改配置、提交代码、调用外部 API。
- 它可能把不该带走的数据带出去:源码、密钥、业务数据、推理上下文。
所以,真正的问题很快就从“模型准不准”变成了 “这个助手到底有没有被好好看住”。
现在已经有了越来越多的风险案例。
- 2025 年 8 月,微软登记的
CVE-2025-53773被收录进 NVD。这个漏洞说明,攻击者可以通过 prompt injection 影响 GitHub Copilot / Visual Studio,本地执行代码。对于普通人来说,这意味着“你只是打开了一个带恶意提示的内容,AI 助手却可能替你改配置、跑命令”。 参考:NVD 在 2025 年 8 月 12 日的描述明确写到,该漏洞允许攻击者 “execute code locally”。 - 2025 年 12 月,Aikido 披露了
PromptPwnd这类问题:当 AI agent 被接进 GitHub Actions / GitLab CI 之后,攻击者可以把恶意文字藏在 issue、PR 描述或 commit message 里,再诱导 agent 使用高权限工具,结果就是 secrets 泄露、工作流被改写,甚至仓库被进一步操控。Aikido 还提到,Google 的 Gemini CLI 仓库也受到了这一模式影响,并在披露后进行了修补。 参考:Aikido PromptPwnd - 2026 年 2 月,Snyk 对 3,984 个 agent skills 做审计,发现 13.4% 含有严重安全问题,36.82% 至少有一种安全问题。更关键的不是数字本身,而是这些恶意 skill 干的事非常具体:下载外部恶意程序、用混淆命令窃取凭证、删除关键系统文件、修改服务配置制造持久化后门。也就是说,“投毒外链”“把凭证送到外部地址”“乱动系统文件”已经不是假设场景,而是技能生态里真实出现过的行为模式。 参考:Snyk Agent Hijacking
如果把这些案例放在一起看,你会发现 agent 带来的风险并不神秘,它大多还是老问题,只是执行者从“脚本和人”换成了“拥有系统权限的 AI 助手”:
- 以前担心的是钓鱼邮件、恶意脚本、被投毒的软件包。
- 现在还要再多担心一层:攻击者不一定直接攻你的机器,他也可以先骗你的 agent,再让 agent 用你的权限替他动手。
到这一步,企业和平台团队要解决的事情其实可以压缩成 两个关键问题:
- 怎么把 agent 放进一个它绕不过去的运行时边界里。
- 怎么决定它能拿到哪些能力,出了事又怎么阻断、审计、接入企业安全流程。
这也正是 OpenShell 和 DefenseClaw 各自出现的背景。
OpenShell来自 NVIDIA/OpenShell。NVIDIA 在官方 README 里把它定义为 “the safe, private runtime for autonomous AI agents”,也就是“面向自主 agent 的安全私有运行时”。它提供的不是一个普通 CLI,而是一整套沙箱、网络代理、策略引擎和模型出口控制,让 agent 的高风险动作先经过统一边界。DefenseClaw来自 Cisco AI Defense 团队,对应仓库是 cisco-ai-defense/defenseclaw。Cisco AI Defense 官方组织页把它概括为 “scan, enforce, and audit every skill, MCP server, and plugin before it runs”,也就是“在 skill、MCP server、plugin 真正运行之前,先扫描、再治理、再审计”。它更像围绕 agent 的企业治理层,而不是底层运行时。
如果把这两句话翻成人话,就会清楚很多:
OpenShell提供的是“把 agent 放进受控工作舱里”的能力。DefenseClaw提供的是“决定谁能进门、进门后怎么管、出事后怎么记账和处置”的能力。
概述:
OpenShell 解决的是“Agent 怎么被安全地运行”,DefenseClaw 解决的是“Agent 拿到哪些能力、这些能力怎么被治理、出了事如何进入企业安全流程”。
这不是一道“二选一”的选型题,而是 一张安全 Agent 栈的分层图。
1. 当 AI Agent 拿到系统权限,问题就变了
如果把前面的风险翻译成一句更容易理解的话,就是:
当一个 agent 既能看你的文件、又能替你跑命令、还能替你访问外网时,它就已经不是“聊天界面”了,而更像一个被临时雇来帮你干活的数字员工。
问题在于,这个“员工”往往干活很快,但并不真正理解公司的边界、流程和后果。它可能出于误判做错事,也可能被外部内容诱导去做危险的事。于是安全问题就会集中到两个方向:
这些能力有没有被放进一个它绕不过去的边界里? 即使边界内发生了危险行为,这些行为能不能被提前阻断、事后审计、纳入企业工作流?
也正因为如此,后面你会看到 OpenShell 和 DefenseClaw 虽然都在谈“agent 安全”,但它们其实站在同一条风险链路的不同位置:
- OpenShell 站在运行时边界,回答“如何让 agent 的所有高风险能力都先经过一个受控执行平面”。
- DefenseClaw 站在治理入口,回答“如何让 skill、MCP、plugin、代码和运行期动作先经过扫描、准入、阻断和审计”。
真正决定它们价值的,不是目录里有多少模块,而是 它们分别守在风险链路的哪个位置。
2. 竞品光谱:从轻量约束到重量治理
知道了这两个项目分别在守哪一段风险链,接下来就更容易看懂它们为什么“长得不像同一类产品”。
如果把 Agent 安全方案放在一条“从轻到重”的光谱上,大概会是这样:
| 光谱位置 | 代表方案 | 核心思路 | 优势 | 短板 | | — | — | — | — | — | | 最轻 | Prompt 约束、应用层 allowlist | 告诉 agent 不要越界 | 接入快 | 可绕过,不可信 | | 中轻 | Docker、普通工作区隔离 | 把 agent 放进容器/远程环境 | 环境隔离成本低 | 很多只能做到容器级边界,缺少 L7 粒度 | | 中重 | E2B、Daytona、Modal 一类 | 把 agent 放进更强的云/VM 沙箱 | 运行隔离更强 | 对模型出口和企业审计的控制通常不够细 | | 很重 | OpenShell | 专用安全运行时:控制面 + 沙箱 + OPA + inference routing | 拥有完整运行时边界 | 重、慢、复杂 | | 叠加层 | DefenseClaw | 专用治理层:扫描 + 准入 + block/allow + 审计 + SIEM | 企业落地路径短 | 不拥有底层运行时 |
这张表真正想说明的,不只是“谁更重”,而是为什么它们会重在不同地方。
- Docker、普通远程工作区这类方案,重点是“先把环境隔开”,所以它们上手快,但通常只回答“有没有隔离”,很难继续回答“这个请求具体能不能发、这个 API 具体能不能调”。
- E2B、Daytona、Modal 这类更强的云沙箱,重点是“把 agent 放进更可靠的执行环境”,因此它们对运行环境的隔离通常更强,但不一定天然带有企业想要的治理闭环。
- OpenShell 之所以重,是因为它不满足于“把 agent 装进容器”这一步,而是继续追问:网络是不是必须走代理?请求是不是还能细到方法和路径级别?模型出口能不能也被纳入同一套边界?
- DefenseClaw 之所以重在另一边,是因为它关心的不是“底层到底跑在哪个沙箱里”,而是“这个 skill 能不能装、这个 tool 调用该不该过、这个风险事件该不该进 SOC”。
所以真正的分界线不是“轻量还是重量”,而是它到底在解决哪一层问题:
- 有些产品在解决“agent 跑在哪里”
- 有些产品在解决“agent 被谁管、怎么管”
也正因为如此,不能直接把 DefenseClaw 和 OpenShell 当成平级竞品去比:
- 拿 OpenShell 去比,应该和 Docker/E2B/Daytona 这一类比“运行时路线”。
- 拿 DefenseClaw 去比,应该和各种 Agent Security / Governance 产品比“治理路线”。
把两者硬拽成同层竞品,会天然丢掉最重要的判断:一个是底座,一个是叠加层。
3. 项目全景:它们到底在系统里扮演什么角色
OpenShell 架构总览
如果先不看源码,只从普通使用者视角理解,两者其实很好区分。
-
你可以把
OpenShell想成“给 agent 准备的一间受控工作舱”。 -
它最核心的价值不是多了一个命令,而是它会接管 agent 的高风险动作:联网、跑命令、SSH、模型调用,都不再是想发就发。
-
对用户来说,它提供的是一条更硬的运行时边界。你可以让 agent 在里面工作,但它不再默认拥有和宿主环境一样的自由度。
-
你也可以把
DefenseClaw想成“围绕 agent 的门禁、审计和处置系统”。 -
它最核心的价值不是自己去运行所有东西,而是决定什么该放、什么该拦、什么该告警、什么该送进企业安全系统。
-
对用户来说,它提供的是治理能力。即使 agent 已经被接进开发流程,企业也知道该怎么管它、查它、拦它。
有了这层直觉,后面再去看源码时,很多模块名称就不再只是技术名词,而是在对应具体职责。
3.1 OpenShell 是“安全运行时”
先看 OpenShell。官方把它定义成 agent 的安全私有运行时,这个定位在源码里是能对上的。它的核心结构很稳定:
- Gateway 是统一控制面,承接 gRPC、HTTP、SSH、watch、inference 配置和持久化,见
OpenShell/crates/openshell-server/src/lib.rs:116-190 MultiplexedService用单端口承接 gRPC 和 HTTP,把入口全部收口,见OpenShell/crates/openshell-server/src/multiplex.rs:128-188- Sandbox 负责 policy 装载、provider env、network namespace、proxy、SSH server、进程启动,见
OpenShell/crates/openshell-sandbox/src/lib.rs:200-290、314-760 - OPA/Rego 负责策略判断。简单理解,OPA 是策略引擎,Rego 是它的规则语言,见
OpenShell/crates/openshell-sandbox/src/opa.rs:160-217 inference.local把模型调用收敛成一条受控数据面。简单理解,它相当于把“调用模型”这件事也变成平台托管的出口,而不是让每个 agent 自己随便连模型服务,见OpenShell/crates/openshell-server/src/inference.rs:70-125、382-417,OpenShell/crates/openshell-sandbox/src/proxy.rs:1172-1195
它的产品哲学是:
只要 agent 需要高权限能力,这些能力就必须先进入专用运行时,再由运行时决定它能做多少。
3.2 DefenseClaw 是“治理控制台”
再看 DefenseClaw。Cisco AI Defense 官方把它描述成 “scan, enforce, and audit every skill, MCP server, and plugin before it runs”,而这句话在实现里也几乎是一一落地的。它的核心结构同样很明确:
- OpenClaw 插件贴在最靠近 agent 的入口,
before_tool_call时把请求送到 sidecar inspect API,见defenseclaw/extensions/defenseclaw/src/index.ts:91-145 - Gateway 负责 inspect、准入判定、OPA policy evaluate、guardrail、CodeGuard API 和审计动作,见
defenseclaw/internal/gateway/inspect.go:54-155、defenseclaw/internal/gateway/api.go:1454-1763 - 审计库用 SQLite 保存
audit_events、scan_results、findings、actions四类核心对象,见defenseclaw/internal/audit/store.go:31-157 - Splunk HEC forwarder 说明它天然面向 SIEM / SOC,而不是只面向本地开发者控制台,见
defenseclaw/internal/audit/splunk.go - 与 OpenShell 的集成主要表现为 policy 塑形和 runtime 命令调用,而不是自己重做运行时,见
defenseclaw/internal/sandbox/network_policy.go:12-88、defenseclaw/internal/sandbox/openshell.go:79-129
它的产品哲学是:
运行时安全很重要,但企业真正会先买单的是“能力准入、阻断、审计、导出”这一层。
3.3 一张图看清上下层关系
flowchart TD
A["Skill / MCP / Plugin / Code"] --> B["DefenseClaw Scan + Admission"]
B --> C["OpenShell Runtime Boundary"]
C --> D["Proxy / OPA / netns / Landlock / seccomp"]
D --> E["Allowed Network + inference.local + SSH"]
E --> F["Logs / Events / Findings"]
F --> G["DefenseClaw Audit + Action State + SIEM"]
看到这里,就可以把两者的关系彻底讲清楚了。
这张图里最关键的一点是: DefenseClaw 影响 OpenShell 的行为结果,但不拥有 OpenShell 的执行内核。
4. OpenShell 的核心设计:把所有高风险能力都收进运行时
OpenShell 真正厉害的地方,不是它用到了哪些 Linux 原语,而是它把这些原语组织成了一条完整的控制链。
如果把这一节先翻成人话,OpenShell 主要给用户提供了四类能力:
- 受控启动 agent 工作环境:不是随手起一个容器,而是起一个带身份、策略和出口规则的工作舱。
- 受控联网:agent 不是“默认能连外网”,而是“默认先经过代理和策略判断,再决定能不能连、能连到哪”。
- 受控模型调用:调用模型这件事也不再是普通 HTTP 请求,而是进入统一的模型出口。
- 受控观测:哪些请求被放行、哪些被拦截、哪些策略被命中,系统会持续记录和同步。
带着这四个能力去看后面的实现,代码就不会只是“模块很多”,而是在回答这些能力是怎么落地的。
4.1 为什么控制面必须统一到一个 Gateway
对普通使用者来说,Gateway 的意义可以简单理解成一句话:它是整个 OpenShell 的总门口。
你看到的是 openshell sandbox create、openshell sandbox connect 这些命令,但这些动作背后最终都要经过同一个控制面。这样做的好处是,sandbox 生命周期、认证、watch、SSH 和模型配置不会散落在不同入口里。
run_server() 的启动顺序非常说明问题。它不是“先开个 HTTP server 再慢慢补”,而是:
- 连接 store
- 创建 sandbox client
- 构建
SandboxIndex、SandboxWatchBus、TracingLogBus - 启动 watcher / reconciler / event tailer
- 最后才开始对外监听
见 OpenShell/crates/openshell-server/src/lib.rs:116-190。
这个顺序背后的动机是:
- sandbox lifecycle 必须与 store、watch stream、SSH/inference 服务一起处于一致状态
- gateway 必须成为单一真相来源,否则 CLI、TUI、SDK 和 sandbox supervisor 会看到不同世界
进一步看 MultiplexedService,它在单端口上按 content-type 分流 gRPC 与 HTTP,见 OpenShell/crates/openshell-server/src/multiplex.rs:158-188。这看似只是协议复用,实际上是在做一个更重要的取舍:
对外只暴露一个可信入口,把认证、TLS、路由、入口发现和未来扩展全部收口。
如果不这么做会怎样?
- gRPC、HTTP、SSH CONNECT、watch 会变成多个松耦合入口
- mTLS 和入口发现逻辑会在多处重复
- Cloudflare / NodePort / 单机部署场景下的接入复杂度会上升
代价当然也有:gateway 更重、更像平台而不是工具。但对于 OpenShell 这种目标明确的运行时产品,这是对的。
4.2 为什么 OpenShell 很在意“先记账,再起环境”
CreateSandbox 的实现不是“发个 RPC 创建 Pod”那么简单,见 OpenShell/crates/openshell-server/src/grpc/sandbox.rs:49-171:
- 先校验 spec、provider 是否存在、policy 是否安全
- 构造 sandbox record
- 先写 store
- 再去创建 Kubernetes resource
- 如果 K8s 创建失败,再回滚 store 和 index
从能力上看,这一步解决的是一个很现实的问题:当你创建一个 sandbox 时,系统里其他组件要不要立刻知道它存在,而且知道的是不是同一份状态。
这背后的架构动机非常清晰:
watcher 与 watch stream 必须先看到一份已经持久化、结构完整的 sandbox 记录。
如果反过来先建 K8s 再写 store,会出现什么问题?
- watcher 可能先看到一个 store 里还不存在的对象
- CLI/TUI 收到的状态更新可能缺少 spec 或元数据
- provider / policy delivery 这些依赖持久化对象的流程更容易踩空
这是一个非常“平台化”的思路。普通项目遇到这种问题,常常靠 eventually consistent 的容忍度硬扛;OpenShell 则选择在创建路径上先把一致性条件布好。
4.3 OpenShell 真正提供的,是一条“先约束、再运行”的启动链
OpenShell 如果只看 README,很容易被理解成“K3s 里拉起一个 sandbox pod”。真正决定它气质的,是 run_sandbox() 这条装配链:
flowchart TD
A["load_policy"] --> B["fetch provider env"]
B --> C["build TLS state / CA"]
C --> D["create netns + bypass rules"]
D --> E["start CONNECT proxy"]
E --> F["start embedded SSH server"]
F --> G["spawn entry process"]
G --> H["poll policy / aggregate denials / push logs"]
关键实现见 OpenShell/crates/openshell-sandbox/src/lib.rs:200-290、314-470、481-760。
如果只从能力角度概括,这条链做的事情其实很简单:
- 先把策略装好
- 再把网络出口收好
- 再把 SSH 和进程接进来
- 最后才允许 agent 真正开始干活
这条链路最值得品的地方,不是“步骤很多”,而是步骤顺序本身就在表达设计哲学:
- 策略先于进程:不是进程先跑起来,再给它打安全补丁
- 代理先于流量:不是让子进程自由联网后再靠日志补救
- SSH 也走同一套边界:不是因为“用户要连进去”就单独开旁路
尤其是 ssh_proxy_url 与 ssh_netns_fd 的计算逻辑,见 OpenShell/crates/openshell-sandbox/src/lib.rs:499-535,这说明 OpenShell 很清楚:
只要有一个通道没进同一套 netns + proxy,它迟早会成为绕过策略的洞。
4.4 OpenShell 的“纵深防御”不是口号,而是真的层层互补
#
OpenShell 纵深防御图
OpenShell 的防线可以抽成三层主结构,加两层横向兜底:
flowchart TD
A["AI Agent 进程"] --> B["第一层:netns + veth pair"]
A -. "文件访问" .-> L["Landlock 文件白名单"]
A -. "系统调用" .-> S["seccomp syscall / socket 过滤"]
B --> C["第二层:HTTP CONNECT 代理 + OPA L4"]
C --> D["第三层:TLS 终止 + L7 per-request 检查"]
D --> E["允许的外部 API / inference backend"]
对使用者来说,这张图最值得记住的不是技术名词,而是 OpenShell 在连续回答三件事:
- 这个 agent 的流量是不是必须走指定通道?
- 就算连上了,它到底能访问哪些服务?
- 就算访问到了服务,它具体能执行哪些请求?
这几层的职责分别是:
- netns + veth pair:强制所有 TCP 流量只能到代理,不靠 agent 自觉
- OPA L4:在连接建立前先判“这个进程能不能连这个目标地址和端口”。如果用更通俗的话说,L4 关注的是“连不连得上”
- L7 检查:在 TLS 终止后继续判“这个 HTTP 方法 + 路径能不能过”。通俗一点说,L7 关注的是“连上之后具体想做什么”
- Landlock:兜住文件系统边界
- seccomp:兜住危险 syscall 和 socket family
这套设计的真正价值在于:它不是依赖某一个安全机制,而是让这些机制彼此补位。
如果没有 netns,会怎样?
- 代理可以不走 CONNECT proxy 直接发 TCP 连接,OPA 和 L7 检查会被绕过
如果没有 L7,会怎样?
- 你只能做到“能不能访问 GitHub”,做不到“能 GET /repos 但不能 POST /issues”
如果没有 Landlock / seccomp,会怎样?
- 网络守住了,但 agent 仍可能越界读文件或调用危险系统能力
这就是为什么 OpenShell 像“安全笼子”,而不是“安全建议”。
4.5 为什么 OpenShell 的策略语义这么“硬”
在 load_policy() 里,只要你用了 policy,不管是 file mode 还是 gRPC mode,网络模式都会被收敛为 NetworkMode::Proxy,见 OpenShell/crates/openshell-sandbox/src/lib.rs:1429-1465。
这其实是在用代码表达一句很强的话:
只要你希望系统裁决网络访问,就不能允许网络绕过统一代理面。
很多系统会选择更柔和的路线:有策略时尽量走代理,代理不可用时回退直连。那样实现更轻、更兼容,但安全语义已经变了。OpenShell 选择的是更硬的版本。
继续看 evaluate_network(),它不仅拿 host 和 port,还把执行二进制路径、祖先进程链、命令行路径一起送进 Rego,见 OpenShell/crates/openshell-sandbox/src/opa.rs:160-217。这让策略不再是“谁都一样的网络 ACL”,而是:
某个具体执行主体,能否访问某个目标。
这一步很贵,也很值。Agent 安全最怕的就是把所有流量都当成同一种流量。
4.6 inference.local 的真正意义,是把“调模型”也变成受控能力
OpenShell 最有辨识度的创新,不是 Landlock,也不是 seccomp,而是 inference.local。
这个名字第一次看会有点硬,但它其实可以理解成一件很简单的事:
模型调用不再是 agent 随手发出的普通 HTTP 请求,而是先经过平台认可的一道“模型专用出口”。
控制链是这样的:
- gateway 通过
SetClusterInference存 provider/model 配置,并在 bundle 生成时解析 provider、API key、protocols、base_url,见OpenShell/crates/openshell-server/src/inference.rs:77-108、382-417 - sandbox proxy 只拦截
CONNECT inference.local:443 - 命中后交给 router 选第一条兼容协议的 route,并立即流式返回响应头和 chunk,见
OpenShell/crates/openshell-sandbox/src/proxy.rs:1172-1195 - router 负责注入 auth、剥离用户传入的敏感 header、重写 model 字段,见
OpenShell/crates/openshell-router/src/backend.rs:104-163
sequenceDiagram
participant Agent
participant Proxy as Sandbox Proxy
participant Router as OpenShell Router
participant Gateway
participant Backend as Model API
Gateway->>Proxy: inference bundle
Agent->>Proxy: CONNECT inference.local:443
Proxy->>Router: protocol + path + headers + body
Router->>Backend: rewritten auth/model request
Backend-->>Router: streaming response
Router-->>Proxy: headers + chunks
Proxy-->>Agent: streamed response
如果再翻译得更直接一点,inference.local 给用户带来的能力是:
- agent 不需要自己保存各家模型密钥
- 平台可以统一决定它到底能调哪个模型
- 模型流量也和普通外网流量一样,进入审计和策略面
这里真正厉害的地方在于:
OpenShell 把“模型调用”从普通 HTTP 客户端行为提升成了受控运行时原语。
收益非常具体:
- 模型出口有统一身份和统一策略面
- API key 不必直接暴露给 agent
- model ID 可以被平台重写
- streaming 体验不会因为中间层而垮掉
如果不这样做,模型调用就会继续散落在各 agent SDK 里,最终成为运行时安全体系里最大的漏网之鱼。
5. DefenseClaw 的核心设计:把风险翻译成治理动作
如果说 OpenShell 像“安全运行时内核”,DefenseClaw 更像“安全治理控制台”。它不想重做所有底层安全机制,而是把 Agent 生态里最混乱、最贴近企业流程的那部分东西收进治理闭环。
如果也先不看代码,只看它给用户提供什么能力,DefenseClaw 主要做的是五件事:
- 扫描:skill、MCP、plugin、代码先检查再运行。
- 准入:根据风险级别决定放行、告警还是阻断。
- 运行期检查:不是只看安装阶段,工具调用和消息内容也继续检查。
- 审计:把扫描结果、告警、处置动作留下来。
- 导出:把这些结果接进企业常见的 SOC / SIEM 流程。
这也是为什么它更像“治理层”,而不是另一个 OpenShell。
DefenseClaw 治理决策流图
5.1 DefenseClaw 最先解决的,不是隔离,而是“能不能过门”
defenseclaw/defenseclaw-spec.md:13-19 把 V1 范围说得非常直:
- scan everything before it runs
- block or allow with lists
- surface alerts in a TUI
这三件事听起来没有 OpenShell 那么“底层”,但非常接近企业真正的第一痛点:
- 哪个 skill 能装?
- 哪个 MCP 必须封?
- 哪段 agent 生成代码需要拦?
- 谁来批,谁来查,谁来接入 SOC?
所以 DefenseClaw 的思路天然不是“我也做一个沙箱”,而是“我先把能力入口和处置入口抓住”。
5.2 对用户最有感知的能力,其实来自插件入口
DefenseClaw 最关键的一段代码,不在后端,而在插件:
before_tool_call时,插件把tool + args发到/api/v1/inspect/tool- 如果是
message,则把 outbound content 一并送检 - 如果 verdict 是
block且 mode 是action,插件直接返回{ block: true }
见 defenseclaw/extensions/defenseclaw/src/index.ts:91-145。
从能力角度看,这里解决的是:在 agent 真正动手之前,能不能先给它一个“最后检查口”。
这条链路表达的是一个很企业产品化的选择:
尽量在离用户和 agent 最近的地方,做第一层治理判定。
这么做的好处很直接:
- 插件层阻断比事后补救更便宜
/scan、/block、/allow可以直接嵌进聊天工作流- 用户不需要切到另一个控制台才能做安全动作
坏处也有:
- 插件层只是“入口阻断”,不拥有最终执行边界
- 它需要和 OpenClaw / OpenShell 的生态接口长期同步演进
但对 DefenseClaw 的目标用户来说,这是正确取舍。因为企业最先要买单的,通常不是“再多一层内核安全”,而是“能不能把安全动作嵌进现有工作流”。
5.3 DefenseClaw 真正在判断的,不是工具名,而是意图
inspectToolPolicy() 的代码不复杂,但非常能说明问题,见 defenseclaw/internal/gateway/inspect.go:54-155:
- 查静态 block list
- 对参数跑规则扫描
- 对
write_file/edit_file再跑 CodeGuard - 按最高 severity 映射成
allow / alert / block
这里有两个关键点。
第一,它看的不是“工具名”,而是“工具意图”
很多系统做到这里就停在“shell 很危险,web_search 不危险”的粒度。但 DefenseClaw 明显不满足于此。它会看:
- 参数里有没有 secret / command / sensitive path / c2 / trust exploit 模式
- 写入内容里有没有 hardcoded credential、危险执行、弱加密、path traversal 等
也就是说,它试图判断的是:
这个调用到底要干什么。
这比传统 API gateway 的思路更适合 Agent,因为 Agent 最危险的往往不是“用了 shell”,而是“打算把什么写进 shell”。
第二,它把生成代码视为一等风险对象
CodeGuard 既能扫描路径,也能直接扫描写入内容,见:
/api/v1/scan/code:defenseclaw/internal/gateway/api.go:1728-1763- 规则实现:
defenseclaw/internal/scanner/codeguard.go:48-250
CodeGuard 的 builtin rules 很克制,不走 SAST 大而全路线,而是盯住 Agent 场景里最常见、最值钱的风险:
- hardcoded secrets
- unsafe command execution
- outbound HTTP to variable URL
- unsafe deserialization
- SQL injection
- weak crypto
- path traversal
这套设计的优点在于:它不是最完美,但很像真实生产环境里最先要拦住的那批错误。
5.4 DefenseClaw 想统一的,不只是准入,而是一整组治理动作
policy.Engine 暴露的不是单一 admission 接口,而是一组策略面,见 defenseclaw/internal/policy/engine.go:83-185:
- admission
- guardrail
- firewall
- sandbox
- audit
- skill_actions
再看 API 层:
/policy/evaluate/firewall,见defenseclaw/internal/gateway/api.go:1507-1549/policy/evaluate/audit,见...:1556-1596/policy/evaluate/skill-actions,见...:1602-1646/policy/reload热重载 OPA,见...:1652-1698
如果从用户价值来理解,这意味着 DefenseClaw 不只是回答“这个东西能不能装”,它还在回答:
- 运行时这个动作该不该拦?
- 这个事件要不要记进审计?
- 这类 skill 以后要不要自动触发额外处置?
这说明 DefenseClaw 真正想做的不是“把几个 scanner 拼起来”,而是把多个治理决策统一到一套策略契约下面。
但它也很务实。evaluateAdmissionPolicy() 的逻辑是:
- 优先尝试 OPA
- 如果 OPA 不可用,就退回 block list → allow list → severity 这条默认判定链
见 defenseclaw/internal/gateway/api.go:1454-1486。
这是一种非常企业化的保守:
- 理想上,一切都抽象成策略
- 现实里,安全系统不能因为策略引擎失效就失去默认防线
5.5 它不只在入口拦,还会继续盯运行期事件
如果只看插件,会误以为 DefenseClaw 只是个“工具调用前拦截器”。其实它还有 sidecar / gateway 事件路径:
handleToolCall()会对 OpenClaw gateway 发来的tool_call做静态 block list 和规则扫描,见defenseclaw/internal/gateway/router.go:674-725handleApprovalRequest()会对 exec approval 做命令模式检测,危险时自动 deny,再通过ResolveApproval回写结果,见defenseclaw/internal/gateway/router.go:760-858
这意味着它给用户的不是“一次性检查”,而是双通道的持续治理:
- 插件负责最靠近 agent 的“软阻断”
- gateway sidecar 负责接入事件流后的“运行期治理”
这个设计挺聪明。只有插件,没有事件流,治理太依赖单入口;只有 sidecar,没有插件,用户工作流又会很生硬。DefenseClaw 把两者接起来了。
5.6 它为什么坚持把 OpenShell 只当底座
这件事在两处代码里非常清楚:
internal/sandbox/network_policy.go:只对 OpenShell policy 做 network policy 的外科修改,见defenseclaw/internal/sandbox/network_policy.go:57-88internal/sandbox/openshell.go:通过openshell policy reload、openshell start这种外部命令去驱动底座,而不是自己托管 sandbox lifecycle,见defenseclaw/internal/sandbox/openshell.go:79-129
从能力分工上看,这背后是很成熟的边界感:
- 如果它自己重做运行时,产品边界会立刻失控
- 如果它只做治理层,就能把研发预算集中在扫描、准入、审计、导出和运营界面
当然,代价也是真实的:
- 能力天花板受 OpenShell 约束
- 生态耦合偏深
但对一个企业治理产品来说,这个取舍是合理的。
5.7 DefenseClaw 的审计模型,天然面向 SOC
DefenseClaw 的 SQLite schema 很有“安全产品味道”,见 defenseclaw/internal/audit/store.go:31-157:
audit_eventsscan_resultsfindingsactions
其中 ActionState 还把 install / runtime / file 三个维度分开记录,说明它不是只想存日志,而是想存一套“处置状态机”。
继续看写入路径,见 defenseclaw/internal/audit/store.go:288-520:
- 事件、扫描结果、finding 是独立对象
- action 通过 upsert 方式维护当前治理状态
HasAction()可以被运行期逻辑直接拿来判某个目标是否 blocked / allowed
再加上 Splunk HEC forwarder,说明它默认要接的不是开发者日志面板,而是企业 SIEM。
对企业用户来说,这一步很关键,因为安全系统真正有没有落地,很多时候不取决于“有没有扫描”,而取决于“能不能进入已有运营体系”。
这也是它和 OpenShell 在“可观测性”上的根本不同:
- OpenShell 更像运行时事件系统
- DefenseClaw 更像安全运营系统
6. 一个拥有数据面,一个拥有治理面
#
DefenseClaw 与 OpenShell 协同图
把前面所有分析压缩成一句话:
OpenShell 亲自托管数据面,DefenseClaw 主要托管治理面。
这不是抽象概念,而是可以落到实现上:
OpenShell 拥有数据面
它自己处理:
- gateway 到 sandbox 的 bundle / watch / SSH / logs
- sandbox 内的 proxy / netns / L7 policy
inference.local的 route resolution、auth injection、model rewrite、streaming
数据真正从它身体里流过去。
DefenseClaw 拥有治理面
它自己处理:
- 资产扫描
- 名单准入
- tool / message inspect
- exec approval deny
- action state / audit / SIEM
但真正的网络、推理、文件系统边界,最终还是要落到底座运行时上。
这就是为什么它们不是“谁更先进”的关系,而是“谁控制栈的哪一段”的关系。
如果把这句话再翻译成人话,就是:
- OpenShell 更像负责“动手那一刻”的系统
- DefenseClaw 更像负责“动手之前和动手之后”的系统
7. 设计哲学与真实权衡
7.1 OpenShell 的设计哲学
我从源码里读到的 OpenShell 核心哲学是:
显式优于隐式,强边界优于弱约束,一致性优于局部便捷。
这体现在:
- 单端口 gateway 收口
store first, k8s second- policy 一上场就强制
NetworkMode::Proxy - SSH 也必须进 netns + proxy
- 模型调用也要进
inference.local
如果不这么做,系统会更轻、更快、更友好;但它也会更像普通容器工具,而不是安全 Agent 运行时。
7.2 DefenseClaw 的设计哲学
DefenseClaw 的哲学更像:
治理优先于执行,运营优先于纯粹,实用优先于统一。
这体现在:
- 多语言栈并存,只要能贴合各运行边界就接受
- 插件、gateway、OPA、CodeGuard、审计库拼成完整闭环
- 不重写 OpenShell,只做 policy 塑形和动作编排
- 默认回退逻辑优先保证“安全系统仍然有默认动作”
如果不这么做,系统会更纯、更优雅;但它也会更难落地到企业安全流程。
8. 诚实评价:亮点、短板与改进方向
OpenShell 的亮点
- 平台边界完整,控制面、策略面、数据面是连起来的
run_sandbox()、CreateSandbox、inference.local这几条主链路都很有系统感- 纵深防御不是宣传语,而是真的层层互补
- 对运行时一致性要求非常高,不靠“大家自觉别绕过”
OpenShell 的短板
- 系统重,首次启动慢,门槛高
- gateway 职责很重,复杂度与调试成本都不低
- 仍处 alpha 阶段,产品成熟度要追技术野心
- 从当前实现和公开文档看,它对企业运营层的资产治理能力仍然偏薄,需要上层系统补
DefenseClaw 的亮点
- 清楚知道自己解决的是企业治理问题,不去和底座抢角色
- 插件入口、sidecar 事件流、OPA 策略面、审计库和 SIEM 输出形成了完整治理链
- CodeGuard 的粒度虽然不深,但很贴合 Agent 生成代码的真实风险
- 审计模型天然适合 SOC / 合规 / 报表体系
DefenseClaw 的短板
- 对 OpenClaw / OpenShell 生态耦合偏深
- 多语言实现很务实,但长期演进成本不会低
- 真正的运行时强制力最终依赖底层 runtime,本身不拥有硬边界
- 当前文档和产品表达更强调“治理叠加层”,但与底座之间的长期边界契约还可以更清晰
#
9. 如果让我选型
如果把前面的所有技术细节都收起来,回到一个普通团队真正会遇到的问题,其实大多数决策都绕不开这三种场景。
场景一:你只是想让 agent 别乱跑
-
如果你是平台团队,优先选 OpenShell。
-
因为没有 runtime boundary,治理动作最终都更像建议,而不是硬约束。
场景二:你已经能跑 agent,但团队开始担心审计、审批和告警
-
如果你已经有底层运行时,只缺治理、审计、SIEM 和能力准入,优先参考 DefenseClaw。
-
因为它更接近企业安全团队的实际工作方式。
场景三:你想做的是企业级安全 Agent 平台
如果目标是企业级安全 Agent 平台,我不会二选一,而会明确分层:
- OpenShell 负责运行时硬边界
- DefenseClaw 负责能力入口治理与运营闭环
- 两者之间通过 policy shaping、event export、action injection 建立清晰契约
这其实也是两个项目今天在代码里已经隐含表达出来的最佳协作方式。
10. 最终判断
如果你不是安全工程师,也不是底层平台开发者,其实不需要记住前面所有实现细节。你真正需要带走的,应该只是三个判断。
- 当一个 agent 已经开始替你读文件、跑命令、访问外网时,企业需要的绝不是一句“请小心使用”,而是系统级边界和治理流程。
OpenShell解决的是“别让它想做什么就做什么”,DefenseClaw解决的是“它做了什么、该不该做、出了事怎么办”。- 真正成熟的企业方案,通常不会只买其中一半,而是把运行时边界和治理闭环一起补齐。
所以这两个项目真正教给人的,不只是“某个开源项目怎么实现”,而是一种更重要的安全认知:
Agent 不是普通软件功能,它更像一个会替你行动的新执行体。既然它会替你行动,你就不能只关心它聪不聪明,还必须关心它有没有边界、有没有门禁、有没有审计。
如果只用一个最简单的比喻来记,那就是:
OpenShell 像笼子,DefenseClaw 像门禁、监控和保安。前者负责别让它乱跑,后者负责决定谁能进、出了事谁来处理。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:帅仔回忆录 qianlan qianlan《当 Agent 拿到系统权限,谁来管它?OpenShell 与 DefenseClaw的诠释,管控底座与上层治理》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论