AI 博客

OPA、Cedar、OpenFGA 与 SpiceDB:谁有资格提供那些事实

四者都能表达同一条策略。但只有其中两个不需要调用方提供事实就能作答——而当调用方是一个正在读攻击者可控文本的智能体时,这就是全部的安全性质所在。第二个问题是检查预算:智能体每个任务要发出几十次授权调用,而过滤一次检索结果要发出上千次。

作者 智能体 AI 维基 26 分钟读完

这四个引擎每一个都能表达"这个主体可否对这个资源执行这个动作",所以关于语法的争论是个干扰项。真正把它们分开的问题是:那份用来做判断的事实,由谁提供——而当调用方是一个上下文里装着攻击者所写文本的智能体时,由调用方提供的事实,恰恰就是你不能信的那一份。

先看全貌

其中两个是策略引擎,评估你递给它的一次请求。另外两个是 Zanzibar 血统的关系存储,自己持有数据,从自己的图里作答。这道分界,而不是策略语言,才是那个决定。

引擎模型出身它持有什么
OPA / Rego 策略即代码,ABAC 与 RBAC Styra;CNCF 毕业项目 只有策略——数据随请求到来,或装在 bundle 里
Cedar 策略即代码,专为授权而生 AWS;2023 年以 Apache 2.0 开源 只有策略——实体逐次调用时传入
OpenFGA ReBAC,Google Zanzibar 血统 诞生于 Auth0;CNCF 项目 关系图,以元组形式
SpiceDB ReBAC,Google Zanzibar 血统 AuthZed 关系图,存在一个分布式数据存储里
Two places the deciding facts can live Architecture diagram contrasting two authorization shapes. In the attribute-passing shape used by OPA and Cedar, the agent's request carries the subject, resource and context attributes to the policy engine, so the caller supplies the facts the decision is made from. In the relationship-store shape used by OpenFGA and SpiceDB, the engine holds its own relationship graph and the caller supplies only the tuple to check, so the decision reads facts the agent cannot influence. Where the deciding facts come from ATTRIBUTE-PASSING — OPA (REGO), CEDAR Agent context is reachable Enforcement point builds the request Policy engine evaluates a rule subject + resource + context travel with the request The engine is stateless and fast. It knows only what the caller told it, so every attribute in the decision has to be assembled by something the agent cannot influence — or the check is theatre. Cedar is built to be analysed; Rego is built to be general. Neither one stores your data. RELATIONSHIP STORE — OPENFGA, SPICEDB Agent context is reachable Enforcement point asks one question Decision service walks the graph Relationship graph owned by the engine The caller supplies a tuple to check, not the facts to decide from. Delegation is a relationship the store already holds, so an agent cannot assert its way into an answer — and the same store can enumerate what a subject may reach, which is what filtering a retrieval set needs. BOTH SHAPES CAN EXPRESS THE SAME POLICY. THEY DIFFER ON WHO IS TRUSTED TO SUPPLY THE FACTS, WHICH IS THE WHOLE QUESTION ONCE THE CALLER IS A MODEL READING ATTACKER-CONTROLLED TEXT
同一条策略,两道信任边界。下面那条泳道,是智能体没法跟它讲道理的那条。
Where each authorization engine leans hardest Feature matrix with four rows for OPA with Rego, Cedar, OpenFGA and SpiceDB, and five columns: holds the data, enumerates resources, models delegation, supports policy analysis, and operational footprint. OPA and Cedar are strong on analysis and light operationally but hold no data and cannot enumerate. OpenFGA and SpiceDB hold the relationship graph and can enumerate, at the cost of running a stateful service. Five axes that decide it, and nobody is strong on all five HOLDS THE DATA ENUMERATES DELEGATION ANALYSABLE LIGHT TO RUN OPA / Rego CNCF graduated No — you pass it No Expressible Rego is general Sidecar + bundles Cedar AWS, Apache-2.0 No — you pass it Batch, not list Expressible Designed for it Library or hosted OpenFGA Zanzibar, CNCF Owns the graph ListObjects Documented Model review Service + store SpiceDB Zanzibar, AuthZed Owns the graph LookupResources Modellable Model review Distributed DB STRONG MEDIUM WEAK POSITIONS AS OF AUGUST 2026. "LIGHT TO RUN" IS AN OPERATIONS JUDGEMENT, NOT A BENCHMARK
各自最吃重的地方。五项全强的没有,而你需要哪两项,取决于你的智能体整天在干什么。

智能体打破了一个它们四个共同建立在其上的假设

常规的应用授权假定有一个可信的执行点。你的 API 处理函数知道是谁在调用它,因为有一个令牌这么说;它把主体、资源,以及策略需要的任何上下文组装好,然后去问引擎。引擎完全信任这个处理函数,而这没问题——因为处理函数是你写的代码,攻击者没法靠发一封措辞巧妙的邮件把它改写。

智能体以一种很具体的方式消解了这个假设。智能体的上下文窗口里装着检索到的文档、工具结果、网页和用户消息——其中有些是攻击者可控的。然后由它来决定调用哪个工具、带什么参数。所以,只要你的执行路径让智能体自己的输出决定了授权判断的任何一项输入,你建成的就是一个"注入进来的指令可以自行拓宽权限"的系统。这不是假想:过去一年多数高危智能体 CVE 就是这个形状,也正是我们在智能体 CVE 其实是授权 bug 里给出的论点。

由此落下三个后果,而它们正好对应到这四个产品上。

一、事实必须来自循环之外

在 OPA 或 Cedar 上,判断是请求的一个纯函数。这是一项真实的优点——正是它让 Cedar 可以被形式化分析,也让两者都又快又无状态。但它同时意味着:这次检查的质量,恰好等于组装这次请求的那个东西的质量。把执行点放进智能体进程里、让它从模型的工具调用参数中填充属性,引擎就会忠实地授权注入文本所要求的一切。两个引擎在这里都完全有能力执行正确的策略;失效是架构性的,而且很容易犯。

在 OpenFGA 或 SpiceDB 上,调用方传的是一个元组——主体、关系、对象——引擎从它自己持有的图里作答。智能体想问什么都行,却改不了答案,因为那些事实是你的开通流程写下的,不是这次请求写下的。这项性质并非策略即代码的引擎拿不到,只是你得自己把它建出来;在关系存储里它是默认值。

二、"代表某人"不等于"就是某人"

会酿成最糟事故的那个错误,是把用户的令牌交给智能体、然后管这叫委派。一个代表 Dana 行事的智能体,应当持有自己的身份,携带 Dana 权限的一个子集、并限定在本次任务范围内,而且可以在不触动 Dana 账号的前提下被撤销。OpenFGA 为此发布了明确的建模指引——把智能体建成一个与其所服务主体存在关系的、独立的主体类型——就 2026 年 8 月而言,这是四者中最完备的一份处理。Auth0 的托管版 FGA 建在同一个引擎之上,旁边还有它在 2026 年推出的 on-behalf-of 令牌交换。

而在分界的另一侧,Cedar 有最清晰的生产故事:Amazon Bedrock AgentCore Policy 自 2026 年 3 月正式可用,在网关上对每一次工具调用评估 Cedar 策略,以调用方身份与该次调用的参数作为控制单元。那正是对的执行点——在智能体之外、落在动作上——它也证明了:只要属性是在模型够不到的地方组装的,属性传入这种形态用在智能体上完全没问题。

三、检查预算的量级完全不同

一次 Web 请求做一次授权检查。一次智能体任务,每次工具调用要做一次,每个工具触及的每个资源还要各做一次,再加上——如果你在按权限过滤检索到的文档,而你必须这么做——每个候选文本块一次。最后这种情形,正是天真设计翻车的地方。

Authorization latency per unit of work, at five milliseconds a check Horizontal bar chart on a logarithmic scale showing how much authorization latency accumulates per unit of work when each check costs five milliseconds. A single web request spends five milliseconds. A short agent task making twelve checks spends sixty milliseconds. A tool-heavy agent task making sixty checks spends three hundred milliseconds. Filtering a thousand retrieved chunks one check at a time spends five seconds, which is why bulk enumeration matters more than single-check speed. One check is cheap. The unit of work is what changed. Web request 1 check 5 ms Short agent task 12 checks 60 ms Tool-heavy task 60 checks 300 ms Filtering retrieval 1,000 chunks, one at a time 5,000 ms 1 ms 10 ms 100 ms 1 s 10 s LOG SCALE. ILLUSTRATIVE AT A FLAT 5 MS PER CHECK — REAL RELATIONSHIP CHECKS VARY WITH GRAPH DEPTH THE BOTTOM ROW IS THE ONE A BULK ENUMERATION CALL COLLAPSES; SINGLE-CHECK SPEED DOES NOT SAVE IT
按每次检查 5 毫秒平摊,最下面那一行就是让设计评审收场的那一行。

解决最下面那一行的办法,不是更快的检查——而是换一个调用。两个关系存储都能枚举:问一句"这个主体可以读哪些文档",然后拿答案去过滤检索候选,或者把这张清单作为前置过滤喂进向量查询。OpenFGA 把它叫作 ListObjects,SpiceDB 叫作 LookupResources。两个策略即代码的引擎都做不到,因为它们都不持有可供枚举的数据——用 Cedar 或 OPA,你要么自己预先算出可访问集合,要么接受逐项的批量评估。如果检索时的权限过滤是你产品的核心,那么单凭这一项能力就决定了这场比较,本文其余部分都不太要紧了。

横向比较

延迟从哪儿来

两个家族在压力下的失效方式不同。OPA 与 Cedar 在评估本身上基本是常数时间——代价落在组装请求上,也就是去取那些属性,也就是那些你没计入的数据库调用。OpenFGA 与 SpiceDB 替你去取,所以它们的延迟由图遍历深度主导:一次浅的"用户属于某个团队,而该团队拥有这份文档"很快,而一个嵌套多层继承组的深层级则不然。哪个家族更快,一般而言无法一概而论;它们只是把代价挪到了不同的地方,而其中只有一处会出现在授权服务的监控面板上。

各自的运维代价

这里的排序很干净,而且与能力排序恰好相反。Cedar 作为库几乎是免费的——它在进程内求值;如果你想要托管,还有 Amazon Verified Permissions。OPA 是一个 sidecar 外加一条你得自己搭建并监控的 bundle 分发流水线,其零件数量比团队预期的要多。OpenFGA 是一个服务,背后带一个数据存储。SpiceDB 则是一个分布式数据库,连同这个词所隐含的一致性语义;据称 OpenAI 正是用它来承载 ChatGPT Enterprise 的权限,规模以数百亿计——这既说明它扛得住长跑,也说明这是一个你该预备好配人手去养的系统。挑那个模型确实能回答你问题的、最轻的一个,而不是你能论证得起的、最重的一个。

你能错到多离谱,以及多久才发现

Cedar 是为可分析性设计的,也是四者中唯一一个让"证明这次策略改动没有新授出任何权限"成为一个可解问题、而非一份心愿的。Rego 的表达力是它的镜像:它允许你写出没有任何工具能推理的策略——这正是当一个引擎要同时覆盖基础设施与应用时它成为标准的原因,也正是当策略只关乎应用资源时它是个糟糕默认值的原因。关系存储把风险放在了完全不同的地方——一个建错的关系会悄悄授出一整类访问,而你发现它靠的是评审模型并测试它,不是分析一个策略文件。这三种失效模式都活得下来;它们需要不同的评审仪式,而挑选一个引擎,某种程度上就是在挑你的团队真会去执行哪一套仪式。

什么时候选哪个

如果你的处境是……先从这个开始因为
智能体按用户过滤检索到的文档 OpenFGA 或 SpiceDB 只有批量枚举能让逐块过滤在成本上说得通
在网关上给工具调用设闸,技术栈以 AWS 为中心 Cedar 可分析的策略、进程内求值,还有一个现成的智能体网关集成
要用一个策略引擎横跨 Kubernetes、CI 与应用 OPA 广度就是它的产品;覆盖基础设施没有别家做得这么好
层级很深的共享关系,文件夹继承文件夹 SpiceDB 最成熟的 Zanzibar 实现,在极大权限量级上得到过验证
你先需要一个委派模型,规模的问题还在后面 OpenFGA 有公开的智能体授权建模指引,以及经由 Auth0 FGA 的托管路径
小团队、简单 RBAC、想这周就搞定 Cedar,或者 Cerbos 运维门槛最低;等出现关系型问题时再回头重估

有一件事不随选择而变:执行点属于智能体之外。把它放在工具网关上,主体从令牌里取而不是从模型的参数里取,并把判断连同 trace 一起记录下来。一个允许调用方自称身份的设计,没有哪个引擎救得了。

常见问题

这和智能体认证是一回事吗?

不是,而这两者经常被混为一谈。认证确立的是哪个智能体在调用、它携带的是谁的授权——也就是我们在 Auth0、Descope、Stytch 与 WorkOS 里比较过的那层身份提供方。授权决定的是:那个已确立的身份,可否对这个具体资源执行这个具体动作。两者你都需要,而一个完美的令牌,并不能证明这次调用就该被放行。

我把权限规则写进系统提示不行吗?

不行。提示是一项请求,不是一项控制:装着你那些规则的同一个上下文窗口,也装着攻击者的文本,而由模型在两者之间仲裁。提示层的规则对让智能体表现得体是有用的,作为安全边界则毫无用处。检查必须发生在模型影响不到的代码里。

我到底需不需要上这么一个东西,用框架自带的权限检查不够吗?

如果你的智能体只碰一个系统、角色也就那么几个,你现有的检查大概就够了——引入一个策略引擎有真实成本,买到的却不多。你已经长过它的信号,是关系型问题的出现:"这个智能体能不能读这份文档,因为它被分享给了一个其主体所属的群组"。这个问题用手写检查恰好能答一次,然后它就会开始繁殖。

那 Cerbos、Oso、Permify 或 Ory Keto 呢?

它们都是真实的选项,而且落在同一道分界上。Cerbos 与 Oso 和 OPA、Cedar 同属策略即代码;Permify 与 Ory Keto 和 OpenFGA、SpiceDB 同属 Zanzibar 一脉。Permit.io 又是另一个类别——一个管理平台,底下跑的是 OPA、Cedar 或 OpenFGA;这一点值得知道,因为它意味着选了它并不能让你豁免于本文这个决定。

关系存储会不会变成一个单点故障?

会,而且是刻意的,就像你的身份提供方早已是那样。为它做好预案:在可以容忍陈旧的地方用短 TTL 缓存判断结果;写路径上失败闭合,而对智能体不妨考虑处处失败闭合;并且把授权这一层和其他东西一起做压测——一个智能体负载压过去的流量,比它旁边那个 Web 应用高一个数量级。

延伸阅读

本站相关:

项目来源: