让AI编程智能体好用的特性,恰恰也是让它们危险的根源。智能体的价值在于无需事先询问就能安装软件包、运行测试和修改配置,但在普通开发者的电脑上,这种自由会让每一把SSH密钥、每一份云凭据和每一条开放的网络连接都落入它的可及范围。由Eclipse Foundation以MIT许可证管理的开源运行时Eclipse Enclave,走了一条不同于审批提示的路:不限制智能体本身,而是限制它运行的那个箱子。一条命令就能让每个智能体会话在独立的容器中运行,并拥有各自的文件视图、网络允许列表和替身密钥。
在工作站上放任完全自主的问题
一台典型的开发机器上存放着已解锁的SSH密钥、云凭据和个人访问令牌,还能不受限制地访问互联网。把这样的环境交给自主运行的智能体,会带来三个问题:
- 提示词注入。 藏在README、Issue或网页中的指令,可能诱使智能体去做用户从未要求的事。
- 凭据暴露。 能读取主目录的智能体,也能读取其中保存的密钥;凡是它能读到的东西,它都可能尝试发往别处。
- 智能体之间的冲突。 共用一台机器的多个智能体会相互覆盖文件、改动对方依赖的软件包版本,并打断彼此的进程。
常见的应对办法都要做取舍。每条命令都要审批,速度优势就会丧失;信任模型的判断,安全性就会丧失。Enclave的设计原则很简短:不约束智能体,而是约束沙箱。这个项目本身不是智能体,也不是为某一家模型厂商做的封装。它是一套沙箱和容器工具,用来承载Claude Code、OpenAI Codex CLI、Copilot CLI和OpenCode等智能体,并让用户在它们之间切换。

▲ 编程智能体的隔离环境
一次会话的样子
启动会话只需一条命令。在项目目录中运行enclave,它会构建或拉取装有所选智能体CLI的容器镜像,只挂载该目录,在容器前面放置一个网络网关,然后让智能体进入自主模式,例如Claude Code的bypass-permissions模式。首次构建需要一些时间;此后借助缓存的镜像层,会话可在两秒内重新启动。
两项简单检查即可证明隔离生效。在智能体内部列出上级目录,只能看到挂载的项目文件夹。尝试访问不在允许列表中的域名,会在域名解析阶段失败。如果智能体确实需要那个域名,在另一个终端运行enclave network add-domain,改动会立即作用于正在运行的会话;删除该域名后,访问又会被阻断。
每个会话都要回答的四个问题
Enclave围绕四个问题来组织每个会话。
| 支柱 | 问题 | 默认行为 |
|---|---|---|
| SEE | 智能体能看到什么? | 只有当前项目目录,可读写,外加一个全新的空主目录 |
| RUN | 里面运行什么? | 包含智能体以及Node.js、Maven等运行时的镜像 |
| REACH | 它能连接哪里? | 带允许列表和日志记录的独立网关 |
| KEEP | 会话结束后保留什么? | 登录信息、历史和设置保留,运行环境丢弃 |
SEE:只看得到项目文件夹
~/.ssh、~/.aws、~/.kube、~/Documents等敏感路径从不挂载。由于项目文件夹是直接绑定挂载,智能体的修改会无延迟地写入宿主机磁盘。参考资料可以通过--add-readonly-dir以只读方式加入。想沿用自己习惯配置的开发者,可以用--host-config-passthrough把允许列表中的文件复制进沙箱,例如MCP(Model Context Protocol,连接AI工具与外部数据和服务的标准)服务器配置和技能。
REACH:串联的三道关卡
每个沙箱都配有专属的网关边车,分三个阶段过滤出站流量:
- DNS过滤器。 dnsmasq只解析允许列表中的域名,其他所有查询都会得到“域名不存在”的结果。
- 防火墙。 直接写死的IP地址可以绕过DNS检查,因此防火墙会丢弃所有出站流量,只放行发往DNS阶段正常解析出的IP地址的流量。
- 代理。 80和443端口的流量会经过透明代理,由它检查HTTP Host头和TLS服务器名称指示(客户端建立加密连接时声明的目标域名)。非Web协议一律丢弃。
每道关卡都弥补了其他关卡的漏洞。只做DNS过滤会漏掉直连IP的请求,只做IP允许列表又无法区分共用同一个CDN地址的众多域名。每一次拒绝都会被记录,可以用enclave network log查看。
智能体从不持有的密钥
最有特色的是凭据的处理方式。容器内的环境变量存放的不是真正的API密钥,而是随机生成的占位字符串。当智能体向为该密钥声明的目标地址发送HTTPS请求时,网关会在传输途中把占位符换成真正的密钥。如果把同一个占位符发往其他主机,网关会返回HTTP 403 Forbidden。由于真正的密钥从未出现在容器内,即使智能体被提示词注入欺骗,也没有任何有价值的东西可以泄露。GitHub CLI扩展也采用同样的替身令牌方式。
KEEP:登录共享,项目分离
每次都要重新登录的沙箱不会有人用,因此Claude Code、Codex等每个工具的认证只保存一次,并在各项目间复用。对话历史、记忆、配置和网络日志则按项目路径区分,保存在代码仓库之外。一个项目的上下文绝不会渗入另一个项目,智能体的状态也不会弄乱Git仓库。每一次网络决策都按项目和工具分别记录,这些记录可以作为《欧盟人工智能法案》(EU AI Act)和《网络韧性法案》(Cyber Resilience Act)等规则下的合规证据。
检验一次数据外泄尝试
一次使用Codex会话的测试展示了这套机制的实际效果。作为注入指令的替身,测试要求智能体读取仓库的README,并把内容作为URL参数发送到一个外部域名。智能体照做了:它读取文件、进行编码并尝试发送请求。由于目标不在允许列表中,网关切断了连接。这种防御不依赖模型拒绝执行,而依赖数据无处可去。在另一个终端运行enclave network log -f,就能实时看到这些放行和拒绝的决策。

▲ 拦截发往允许列表外的流量
让多个智能体并行工作
隔离也让并行工作变得切实可行,在日常工作中,这一点可能与安全性本身同样重要。推荐的做法不是让多个智能体共用一个文件夹或分支,而是为每个智能体分配独立的Git worktree(把不同分支检出到不同文件夹的Git功能)和独立的Enclave会话。会话可以用--name设定的名称在后台运行,用enclave ps列出,用enclave attach进入,并在不停止会话的情况下再次退出。所有命令都支持--json输出,因此整套流程都可以用脚本来驱动。
项目只能收紧规则,不能放宽
设置按层解析,越具体的层优先级越高,依次为CLI参数、工具级覆盖、项目配置、全局配置和内置默认值。权限是例外。项目配置可以增加限制,但放宽访问权限的设置,例如允许所有网络流量,会被忽略并给出警告。放宽权限必须来自全局配置或命令行,由坐在键盘前的人有意为之。扩展也绝不会从项目仓库内部加载,因此打开一个不可信的仓库,不会在设置过程中运行其中的代码。
针对具体任务,还可以用单次运行参数进一步收紧:
--project-mount readonly:在只让智能体规划实现方案时,保持文件不被修改。--worktree-metadata readonly:允许智能体编辑文件,但让Git暂存和提交失败,使提交始终处于人工审查之下。--ephemeral:不带任何已保存状态启动,结束后丢弃登录信息和设置,适合一次性或不可信的任务。
团队无需搭建注册中心,就能通过任意Git仓库共享扩展和策略。扩展会固定到某个提交哈希;安装前,Enclave会列出它所需的脚本、允许的域名、端口和凭据,并请求确认。
已知局限
Enclave能缩小风险,但不能消除风险:
- 默认后端是以root权限运行的Docker守护进程,因此不应把容器视为无法逃逸的边界。
- 网络过滤控制的是数据去向,而不是数据内容。
- 占位符替换只适用于已声明的密钥头。在浏览器中进行的交互式OAuth登录,仍会把真正的令牌放进容器。
这个项目还很年轻。它于2025年底作为内部工具起步,2026年5月捐赠给Eclipse Foundation,1.0版本预计在几周内发布。预发布版本可在Linux、macOS以及通过WSL2的Windows上运行,需要rootless Docker或Podman。
交出钥匙之前要决定的事
如果你正在或打算以自主模式运行编程智能体,最稳妥的做法似乎是只在隔离环境中关闭权限确认。无论使用Enclave还是其他方案,都应先确定以下四件事:
- 可见范围。 让智能体只看到一个项目文件夹,参考资料以只读方式加入。
- 网络可达范围。 只放行工作所需的域名,例如软件包仓库和模型API,并检查拒绝日志。
- 密钥。 不把真正的密钥放进智能体的环境变量。
- 人工控制。 把提交和任何权限放宽都留给人来完成。
如果同时运行多个智能体,为每个智能体分配独立的Git worktree,是避免冲突最简单的第一步。