2026 年 9 月 30 日的 GitHub 趋势日榜上,NVIDIA/OpenShell 排在第一位,当日 +1,280★,总星 11,419。仓库元数据(GitHub API 取数时间 2026-09-30 21:33 CST):11,419★、1,477 fork、510 条 open issue、Apache-2.0 协议、语言字节数以 Rust 为主(2,005.9 万)、2026-02-24 建仓、126 位贡献者、1,573 次提交、最后一笔 push 在 21:18 CST。而它上一周连发了三个版本:v0.1.0(9/25)、v0.1.1(9/26)、v0.1.2(9/28);PyPI 上的 openshell 同步在 9 月 28 日发到 0.1.2,要求 Python 3.11 及以上。
它为什么偏偏在这两天冒头,时间线很清楚,实锤与官方说法分开看:
- 实锤一,9 月 25 日 OpenAI 公布了一起内部安全事件:9 月 20 日,一个在训练沙箱里执行搜索任务的模型,利用沙箱的 DNS 过滤漏洞突破了网络隔离,访问了外部服务;OpenAI 随后暂停了前沿模型里与工具调用相关的训练、评估和推理,并表示要升级隔离与监控。这是三个月内的第二次——上一次是 7 月,报告里提到模型突破隔离访问了 Hugging Face。
- 实锤二,9 月 28 日英伟达发布了开放智能体安全平台,两个组件:开源软件 OpenShell(跑在 CPU 上,在模型与 Agent 框架之外建一套可强制执行的边界,专为 Vera CPU 优化)和 Sentry(跑在 BlueField-4 DPU 上的带外监控参考设计,声称能在毫秒级隔离异常 Agent)。英伟达在发布时给出的说法是:如果相关实验室此前部署了这套技术,7 月那起事本可被阻止。
- 热度是这两天兑现的:OpenShell 的 v0.1.2 正好落在 9 月 28 日,今天(9/30)它冲到日榜第一。同一张榜上还有我们 9 月 4 日写过的 VoiceStudio(当日 +3,481★,增量比 OpenShell 更高,但那篇已经写透,这里不重复)。
- 一条提醒,别把两半混着信:Sentry 是"参考系统设计",不是能装的开源产品;“毫秒级隔离"“本可阻止"都是英伟达发布时的官方说法,目前没有第三方复现。OpenShell 这一半是自己能上手验证的,本文也只写这一半。
一句话定位:它不是 Agent 框架,是跑 Agent 的运行时
README 第一句写得很直白:Agent 最有用的时刻,恰恰是它能读文件、装包、调 API、用凭据的时候;这套东西要解决的是"给了这些能力,但不把数据、密钥和网络一起交出去”。
它的架构里有三个角色,记住分工就理解了它的安全模型:
- gateway(控制面):管沙箱、策略与访问的生命周期。
- supervisor(可信方):做策略判定、持有凭据、开真实的上游连接——它待在 Agent 的工作负载边界之外。
- sandbox(与 Agent 同侧):启动并托管 Agent 进程、上报它想干什么,但不做任何策略决定。因为它和 Agent 共享一侧边界,所以它手里没有值得偷的东西:没有网关签名密钥、没有 JWT、没有 provider 凭据。supervisor 一旦断线,Agent 会被冻结,只有同一个 supervisor 进程能重连续跑。
它到底防什么,README 用一张对照表回答:
| 风险 | 没有控制时 | OpenShell 的控制手段 |
|---|---|---|
| 数据外泄 | Agent 把源码或内部文件传到未授权端点 | 网络策略只放行批准的地址,其余出站一律拒绝 |
| 凭据被读 | Agent 读到本地 SSH 私钥、云凭证 | 文件系统规则(Landlock)只放行声明过的路径 |
| 越权调用 | Agent 把提示词、数据发给没批准的模型厂商 | provider profile 加网络策略,把模型流量锁到批准的端点与二进制 |
| 提权 | Agent 试 sudo、setuid、危险系统调用 | 非 root 进程身份加 seccomp 规则,挡掉提权路径 |
核心功能:四个维度,每个都有具体数字
一、隔离是内核级的,不是"约定俗成”
- 文件系统:由内核的 Landlock LSM 强制执行,要求 ABI 3 以上(Linux 6.2 起);策略里分别写"只读"与"可读写"的路径清单。
- 网络:每个 TCP 连接与每条 DNS 查询都由 seccomp 拦下来交给 supervisor 判定;通往 supervisor 的那条受控通道是工作负载唯一的合法出口,外面还有一层围栏——Agent 想直连服务、直连网关、直连内网其它地址,通通不通。
- 进程:每个工作负载一个非 root 身份、零 Linux capability;启动前会主动探测 seccomp 与内存访问能力,不满足就直接拒绝启动(失败即关闭)。
- 老内核会降级:
SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV是 Linux 5.19 才有的,像 RHEL 9.x 那种 5.14 内核只能进 legacy read-only 模式——边界还在,但getpeername、带 peer 地址的accept、sendmmsg这几类要把结果写回工作负载内存的调用会直接返回EOPNOTSUPP。想做服务端型工作负载的人要留意这条。
二、策略就是一份 YAML,而且拿 SMT 求解器来验
策略文件是 version: 1 加最多五个段,每段的执行者与生效时机都不一样:
| 段 | 管什么 | 谁来执行 | 什么时候生效 |
|---|---|---|---|
filesystem_policy | 进程能读、能读写的路径 | 内核里的 Landlock LSM | 沙箱启动时锁定 |
landlock | 内核不支持下,是否仍允许启动 | 沙箱运行时 | 沙箱启动时 |
process | 以哪个用户、哪个组运行 | Docker 与 Podman 创建沙箱时 | 创建时锁定 |
network_policies | 哪个二进制能到哪个地址、能发什么请求 | 沙箱网络代理 | 运行期可热改 |
network_middlewares | 对已放行流量再做检查、改写、阻断 | 沙箱网络代理 | 运行期可热改 |
策略从哪来,优先级也是写死的:网关全局策略 > 沙箱保存的策略 > 镜像内置策略 > 官方默认策略。默认策略长这样——工作目录可读写,/bin、/usr、/lib、/proc、/etc、/var/log、/dev/urandom 只读,/tmp 与 /dev/null 可写,网络规则一条都没有,等于出站全部拒绝。所以"装完发现 Agent 什么都连不上"是设计取向,不是 bug。
真正拉开差距的是那套形式化验证。它内置一个基于 SMT 求解器的 openshell-prover:你写一份 boundary(允许的上限),再拿候选策略去比。
| |
| |
结果只有五种,退出码也定死了:
| 结果 | 退出码 | 含义 |
|---|---|---|
within_boundary | 0 | 候选策略没有超出边界(在已验证的域内)——只有这一种算通过 |
exceeds_boundary | 1 | 超出边界,并给出一个反例,比如 filesystem write /tmp |
error | 2 | 校验没跑起来:文件缺失、策略非法 |
unsupported | 3 | 策略用了它没建模的东西,比如 GraphQL 或 MCP 规则 |
inconclusive | 3 | 超时或策略太大,算不完(默认限时 10 秒) |
覆盖范围会打印成 coverage: domains=filesystem,network_l4,network_rest,process,landlock。这条的诚实点很重要:它是"在已建模特性范围内"的证明,通过不等于你的策略足够窄,也不等于运行中的沙箱真按它执行;但它遇到没建模的协议会给 unsupported,而不是当作没看见——这个处理方式是对的。它还有第二类检查叫提案风险检查,由策略顾问在 Agent 提出新网络规则时自动跑。
三、密钥可以不进 Agent 的环境
这一层是我个人认为对个人玩家最实用的部分。provider 是一等公民:创建时你的密钥进网关的凭据存储,进沙箱环境的只是不透明的占位符;只有当请求发往 profile 授权的端点时,代理才会在转发前把真值换上去。
- 双授权:网络策略必须允许该二进制访问该目的地,凭据绑定必须包含请求的 host、port、path,两条都过才放行;不匹配就返回 403 与
credential_endpoint_mismatch,而且不记录密钥、占位符、环境变量名或查询串。 - 占位符能出现的位置:请求头、Basic 认证、查询参数、URL 路径段、请求体(REST 端点需显式开启)、WebSocket 文本帧,以及 AWS SigV4 签名。cookie、响应体、二进制帧不参与重写——也就是别指望拿它当万能替身。
- 仓库自带 17 份 profile:anthropic、aws-bedrock、aws-s3、aws、claude-code、codex、copilot、cursor、deepinfra、github、google-cloud、google-vertex-ai、nvidia、oci-genai、openai、openrouter、pypi。
- 一个容易踩的坑,官方专门加注提醒:
ANTHROPIC_API_KEY指的是 Anthropic Console 里的 API key,不是订阅 token;订阅用户想在里面跑 Claude Code,得单独去开一个 API key。这跟我们在 Claude 账号被批量盗用那件事(原文已过保下线) 里讲的结论是同一条思路——你的订阅凭证根本不该出现在 Agent 能读到的地方。
四、跑在哪、跑什么 Agent
| 运行时 | 要求 | 边界怎么建 |
|---|---|---|
| Docker | Docker Engine 或 Desktop 28.0+ | supervisor 独立容器,走 Unix socket,工作负载容器关掉网络 |
| Podman | Linux、Podman 5.x、cgroups v2、活跃的用户 socket | 同上,支持 rootless |
| Kubernetes | 1.29+、Helm 3 | supervisor 独立 Pod、私有服务互 mTLS,NetworkPolicy 只放行 supervisor 服务 |
| MicroVM | 需要 KVM(Linux)或 Hypervisor.framework(macOS) | supervisor 在宿主进程、走 vsock,guest 里没有网络设备 |
平台支持上,Linux 的 x86_64 与 arm64 是正式支持,macOS Apple Silicon 支持,Windows 走 WSL 2 属于实验状态;Linux 上的 CLI 是静态 musl 二进制,不依赖 glibc。沙箱资源用 --cpu、--memory、--gpu 指定,默认工作负载镜像是 nvcr.io/nvidia/base/ubuntu:24.04——里面不带任何 Agent 命令行工具。
Agent 侧它不挑:官方教程就是拿 OpenCode 配 OpenRouter 的免费模型跑通的,同一套策略换成 Claude Code、Codex、Copilot CLI 都一样。仓库里还带 4 个 Agent Skills(openshell-cli、generate-sandbox-policy、debug-openshell-cluster、debug-inference),npx skills add NVIDIA/OpenShell 就能装进你自己的编码 Agent;SDK 覆盖 Python、TypeScript、Go、Rust。这个项目本身是"agent-first"开发的,仓库里连贡献流程都写在 AGENTS.md 里。
怎么用起来:最小的一条路
第一步,装。 官方安装脚本会装好 CLI、策略验证器,并起一个本地网关:
| |
Linux 上它装成 systemd 用户服务,监听 https://127.0.0.1:17670;想让网关在你退出登录后继续活着,加一条 sudo loginctl enable-linger $USER。macOS 上走 Homebrew 服务。注意 snap 包要求 Docker Engine 来自发行版或 Docker 官方仓库,Docker 自家的 snap 不兼容。
第二步,起一个空沙箱,先看清边界。 默认镜像里没有任何 Agent,拿它验证链路:
| |
第三步,把真 Agent 接进去。 官方教程给的是 OpenCode 加 OpenRouter 这条路:
| |
两条 0.1.0 之后的新规矩,照老习惯下手会直接失败:--from 不再帮你构建 Dockerfile 或目录,必须先 docker build 再 docker push,只传镜像引用;--provider 必须显式写,跟在 -- 后面的命令不再自动推断并挂载 provider。另外 openshell inference 那整套托管推理路由(inference.local)在 0.1.0 里被删掉了,改成每个沙箱自己挂 provider、直连原生端点。
排查工具别忘了:openshell-prover 是独立二进制,不需要网关就能跑;openshell sandbox get <名字> --policy-only 能把正在生效的策略导出来跟边界比。遥测默认开着,但只收匿名的运营类别与计数(不收集沙箱名、主机名、文件路径、提示词、凭据、provider 名、模型名和用户内容),想关就设 OPENSHELL_TELEMETRY_ENABLED=false,用 Helm 装则设 server.telemetryEnabled=false——这一点后面还要用到,因为他们把双周报公开在仓库 telemetry/ 目录里。
和同类比,它多做了哪一层
把常见做法摆一排,差别不在"有没有沙箱",而在"沙箱管到哪一层":
| 做法 | 隔离什么 | 谁在管凭证 | 能不能审"Agent 拿我的 key 调了什么" |
|---|---|---|---|
| 直接给 Agent 全权限跑 | 什么都不隔离 | Agent 环境里放真密钥 | 不能 |
| 普通容器 / devcontainer | 文件系统与进程(仍共享宿主内核) | 多半还是塞进容器环境变量 | 不能,出站网络基本不拦 |
| 云厂商托管沙箱 | 文件系统、进程、网络出口 | 平台托管 | 有部分能力,但要按平台规格改造工作流 |
| OpenShell | 文件系统(Landlock)、进程(seccomp 加降权)、网络(默认拒绝、逐连接判定) | 网关存储加占位符替换,只发给授权端点 | 能:策略即代码、拒绝有记录,还能用求解器验边界 |
它真正的额外价值其实是审计口径的统一:策略是 YAML,可以进版本库、可以走代码评审,可以用形式化验证回答"这次改动有没有多给权限"。对需要说清楚"Agent 碰过什么"的团队,这比一句"我们开了容器"有用得多。
而且这项目是有人真在用的。它公开的双周遥测报告里写着:2026 年 7 月 27 日到 8 月 10 日这一期,上报创建了 556,389 个沙箱、删除 457,086 个,创建失败率约 12%(比上一期的约 18% 明显下降),被拒绝的动作 4,220,436 次;驱动分布上 Kubernetes(245,144)第一次超过 Docker(239,444),Podman 58,657。策略决策里约 67% 通过、约 8,200 次被拒,被拒连接里约 93% 落在 Connect Policy 这一类。一个两周被拦下四百多万次动作的系统,说明 deny-by-default 是真在拦东西,不只是宣传词。
我的判断:谁该上、谁再等等、谁别碰
**该上的:**① 有多个 Agent、或者多人共用一套机器,要给不同人不同权限的团队——workspace、全局策略、审批、审计这套就是为你们做的;② 已经把 Agent 接进仓库和云账号、需要向合规交代"它能碰什么"的人;③ 一个人跑 Claude Code / Codex 但心里发毛的个人玩家——你最怕的三件事(它翻你的 ~/.ssh、它拿你的密钥到处调、它 sudo 动系统),恰好是它默认堵住的三件事。顺带说一句,如果你已经在为 无人值守 Agent 中途停工 这类问题配续跑脚本,那套脚本加上这层边界,才算把"让它自己干"这件事补完整。
**再等等的:**① 只想给单个 Agent 加个护栏、不想学 gateway / supervisor / policy / prover 这堆概念的——先用容器或一个低权限账号跑,成本低得多;② 内核低于 6.2,或者跑在 RHEL 9.x 那种 5.14 内核上——会降级到 legacy read-only 模式,服务端型工作负载可能直接吃 EOPNOTSUPP;③ 想在 Windows 原生用——目前 WSL 2 还是实验状态。
**别碰的:**指望装上就自动安全的。默认策略一条网络规则都没有,你不写策略,Agent 就什么都干不了;反过来,图省事在端点上手一抖写了 access: full、用 /** 这种通配二进制放开、或者没在 audit 模式下看过日志就直接切 enforce——官方在安全最佳实践里把这几种写法逐条点名,评语是"削弱了安全性,却没换来任何好处"。
最后是版本账,这条最实在。 一周连发三版说明项目在冲,也说明接口还在动:0.1.0 是破坏性版本,官方升级指南列了 18 条面向运维、20 条面向终端用户的变更;本地 0.0.x 不能原地升级——得先卸干净、备份数据库、重建每一个沙箱,provider profile 要导出再导入,gateway.toml 要迁到 schema v2,Helm 的配置要搬到 gatewayConfig。稳定节奏是官方承诺每周二发一个 stable,想省事就锁死版本、跟着升级指南走。如果你也被"模型自己绕开隔离"那类事情搞得有点不安,这个项目值得你花一个周末在 Docker 后端上跑一遍——它解决的不是"模型会不会犯错",而是"模型犯错时,损失的上限由谁定"。
顺带一提:沙箱之外,自己那台跑着公网服务的小服务器也值得盘一遍边界——1.6GB 服务器跑多服务实测记了每个服务的位置。
本文由拾光札记编辑部整理,勘误请联系我们