前阵子 Cloudflare 把 Cloudflare OS 开源了。在写完上一篇关于 Cloudflare Agent 架构演进 的文章之后,我把他们的代码克隆下来研究了一圈。最触动我的地方在于一个容易被忽略的硬核痛点:Agent 读过的数据,在团队二次分享、导出或者继续对话时,到底该怎么授权?
平时咱们做 Agent,习惯拿 Model Context Protocol(MCP)或者 API 网关在前面挡一把,觉得只要 Agent 调 API 的那一瞬间校验了身份就万事大吉。但在实际的团队协作里,这种工具调用的静态关卡一旦遇到落盘的数据和生成的产物,很快就会失去控制。Cloudflare 发布说明提供了一个可借鉴的思路:借用操作系统的角色隐喻重新组织应用架构,把原本一次性的调用检查,延伸到读取登记与共享准入两个环节。需要说明的是,它目前没有覆盖所有外发出口的统一检查,webFetch、模型调用、blueprint 发布等走各自不同的控制路径。把代码翻透之后,我想从一线开发者的视角,聊聊这套设计背后的真实机制,以及咱们在自己架构里落地时到底该怎么取舍。
咱们从团队日常里一个常见的场景说起。HR 负责人 Alice 具备薪资库权限,在 Agent 工作区里调数据仓库 API 算了一张团队平均薪资看板。她觉得做得很棒,顺手把工作区链接发给了团队主管 Bob。但 Bob 在公司里并没有看薪资的权限。当 Bob 点开链接的那一秒,现有的安全防线就失去了作用。
无论是传统的 API 网关还是 MCP 协议,校验都发生在 Agent 伸手拿数据的瞬间。当时 Alice 在场,权限校验顺利通过,数据读出来生成了看板。等看板做好、工作区发给 Bob 时,工具调用早就完成了。眼前只有一份生成好的看板,系统丢掉了三样东西:记不住数据源来自哪里、跟踪不到哪些图表染了敏感数据、也无法在 Bob 进门时拿 Bob 的凭据去重测数据源。
这就是典型的读取时合法,落地后失忆。一旦数据进了工作区,光靠 API 调用的那一下拦阻,根本管不住后面的分享与二次泄露。要解决这个问题,防线必须覆盖数据读取后的整个生命周期:当数据读进工作区变成产物,需要把控的已经超出了某一次接口调用,延伸到了整个运行环境。
这正是 Cloudflare 把它叫作操作系统的原因。当 Agent 拥有了长期运行的小程序、共享工作区和外部数据连接时,它的运行环境本身就是一个微型 OS。正如他们在发布说明和内部采用说明里说明的那样,叫 Cloudflare OS 并非要搞一个替代 Linux 或 macOS 的系统,而是给共享 Agent 应用建立一套清晰的底层抽象。
翻看源码可以发现,Cloudflare OS 沿着 Agent 处理请求的物理动作推进,将传统操作系统的核心组件做出了具体的工程实现:
用户接入的 Workspace 相当于操作系统的用户 Session
和共享工作目录,承载着会话历史、上下文文件、生成的小应用以及外部资源连接。系统的前后端(workshop-frontend
和 workshop-backend)则分别扮演 Shell
与内核子系统的角色,负责接收用户输入与调度底层资源。
当 Agent 需要访问 GitHub、Notion 或 Slack
等外部服务时,它并不能直接接触底层长期凭据,而是通过 Gatekeeper
发起请求。Gatekeeper 就像设备驱动,向环境注入类似
env.PROJECT
的对象能力绑定,负责执行实际的外部读取,并在敏感写入时触发用户审批。每次外部读取完成后,Gatekeeper
都会将数据源头向内核报备。
当 Agent 在运行中动态生成带有前端、后端逻辑与数据库的交互式小应用 Gadget 时,这些小程序就像是在隔离沙箱里运行的进程。如果用户希望将应用模板分享给他人,但不带走自己的运行数据与凭据,系统会导出 Blueprint,这便相当于可执行文件的代码模板。
而在后台统筹这一切的,是运行在 Cloudflare Durable Objects 上的持久化进程 Overseer。Overseer 扮演着操作系统内核的角色,保存着工作区的完整状态、协作者关系,以及由各个驱动报备上来的历史观察集合。这么一设计,驱动按合同应当读了什么都向内核报备,内核再拿着这本账本去把控工作区的入口。需要说明的是,这套完整报备依赖每个驱动的正确实现,core 并不能强制保证分页、子 session、缓存等边缘路径上不漏记。安全防线找到了收敛的支点,但这个支点的牢固程度取决于驱动的实现质量。
在这个支点上,Cloudflare OS 解决 Alice 和 Bob 困局的思路是:不在分享瞬间去解析看板内容,而是在内核里维持一套双向不变量。
第一个动作发生在读取数据时。每当 Agent
通过驱动去外部取数据,驱动必须显式调用 authorizeObservation()
接口。内核把这次读取的数据源 ID 和所需权限存进持久化的 Observation
Set 清单里。工作区不仅记录了用户发过什么
Prompt,还记下了这个工作区吸收过哪些受控数据源。
第二个动作发生在打开与分享拦截路径上,内核实施双向把关:
有了这套机制,系统不用费劲去理解看板内容,只要发现 Bob 的权限包不住工作区历史吸纳的数据源清单,就能在入口处把风险掐断。
理解了 Cloudflare OS 的这套做法,咱们从安全理论和工程实践的角度,可以给它找个准确的位置。
重新捋一遍它的物理过程:调用前不给全局密钥给受控句柄(如
env.PROJECT);读取后在工作区追加数据源清单;分享和打开时拿清单跟接收者的身份做匹配;导出
blueprint
时只剥离数据和凭据,不做身份匹配。在安全坐标系里,这三步物理动作分别对应了对象能力代理、粗粒度观察污点标记和身份权益追溯。它没有停留在调用完就管不到的传统
API
关卡,也没有去走给每个字符做动态跟踪的高成本路线。它选在工作区这个粒度做记账,是在实现成本和实用安全之间做了一次务实的折中。
明白了这个定位,也就看清了它和当下火热的 Model Context Protocol(MCP)的关系:MCP 规范(2026-07-28)的核心在于工具调用的标准化、OAuth 授权以及调用前的 Scope 协商,管的是如何规范地去拿数据。Cloudflare OS 管的是拿完数据之后的故事,在 MCP 上层叠加了一层观察追溯和共享准入。两者在上下游各司其职,形成互补。
在处理通用的 MCP 绑定时,Cloudflare OS 在 MCP 共享策略定义 里采取了保守的态度:它不允许用户直接把带凭据的 MCP 连接分享给别人。如果你想分享 Gadget,只能分享不带凭据和数据的 Blueprint 代码模板,让新协作者用自己的账号去重新绑定。
看清这套设计的机制后,咱们搭建自己的企业级 Agent 架构时,可以顺理成章把安全治理划分为三个平面:
[ 1. 调用前平面 Pre-call Plane ]
Capability 代理 / 动态 Scope / 凭据隔离 (如 env.PROJECT)
│
▼ (数据读取)
[ 2. 读取后平面 Post-read Plane ]
Gatekeeper 显式记录 ──► Overseer 动态 Observation Set 清单
│
▼ (上下文/产物分享)
[ 3. 传播与出口平面 Pre-egress Plane ]
Workspace / 产物准入校验(Cloudflare OS 已做)
──► 统一 Egress Sink Policy(需自行补齐,Cloudflare OS 当前未做)
当然,咱们也没必要在所有项目里都搞这么重。结合实践,建议大家按场景做取舍:
| 场景类型 | 是否需要观察追溯与受众重验 | 架构建议 |
|---|---|---|
| 单用户受控终端 / 本地 CLI | 不需要 | 传统的 API Key 加本地沙箱足够,没必要加内核开销。 |
| 单人使用但具备公开 Web 导出 | 简易需要 | 重点把守出口检查,防止公开 Fetch 泄露数据。 |
| 企业多人共享 Workspace | 必须构建 | 必须建立 Observation Set 清单,并在打开与分享节点做身份重验。 |
| 跨部门数据协同分析 | 必须构建(需升级) | 在工作区记账的基础上,把标记做细到文件或产物粒度,避免过度污染。 |
从工具调用的瞬间拦截,走向工作区级的观察追溯与共享准入,是 Agent 从个人助手走向企业生产力系统绕不开的一关。Cloudflare OS 用一套贴切的操作系统隐喻帮咱们把路探了出来,它推进了授权模型,但尚未完成从资源、产物到所有出口的端到端闭环。至于如何把出口守严、把标记做细,就看咱们在实际工程里的手艺了。