Zero Trust 与对抗性完整(Adversarial Completeness)共享一个几乎相同的出发点:都拒绝把"这个主体应该是可信的"当成系统的默认前提。也正因为出发点相似,后者很容易被误读为"更严格一些的零信任",两者真正的分歧反而被掩盖了。

要说清这个分歧,首先必须准确陈述 Zero Trust 究竟解决了什么。NIST SP 800-207 把零信任描述为一组将防御重心从静态网络边界转移到用户、资产与资源上的原则:不再因为网络位置或资产归属授予隐式信任,认证与授权围绕每一次资源访问建立,并按请求做出决策。CISA 的 Zero Trust Maturity Model 进一步把身份、设备、网络、应用与工作负载、数据组织为若干支柱,并以可见性与分析、自动化与编排、治理作为横向能力,强调持续验证、上下文感知与最小权限。这是一个远比"登录时多验证一次身份"完整得多的体系。一个成熟的零信任架构完全可以结合设备姿态、实时风险评分、行为基线与资源敏感度做出高度动态的细粒度授权,并在条件变化时收回已经授予的访问。

问题不在于这套体系做得不够细,而在于它反复细化的始终是同一类判断:当前主体,在当前上下文中,是否有资格接近某项资源或能力。这类判断的产物,是主体与能力之间的一种关系。它并不天然回答另一个问题——一个已经合法获得该能力的主体,究竟握有多大的权力,可以让一个受保护的现实动作真正发生。对抗性完整要处理的,正是后面这个问题。

一、Zero Trust 判断访问关系是否成立,对抗性完整判断执行因果是否成立

零信任的核心安全关系可以抽象为:

主体(Subject)→ 策略决策(Policy Decision)→ 资源(Resource)

真实系统当然比这条链复杂。策略决策可能综合身份、设备、时间、位置、风险评分、行为特征与资源敏感度,也可能在会话生命周期内持续重新评估并撤销。但无论评估得多频繁、输入维度多丰富,它最终收敛到的都是同一个判断:当前主体是否可以访问、调用或使用某项受保护资源。这里的资源可以是数据、应用、服务、工作负载,甚至一个完整的业务流程——NIST 明确强调零信任保护的对象是资源本身,而不是传统意义上的网络分段。

对抗性完整关注的是另一条关系链:

行为主体(Actor)→ 动作(Action)→ 对象(Target)→ 状态(State)→ 证据(Evidence)→ 边界(Boundary)→ 执行(Execution)

它首先要回答的不是"你能不能调用这项能力",而是"这一次具体的动作,为什么在此刻有资格成为现实"。

在纯信息访问的场景里,这两条链的差异往往并不明显。如果一个 Agent 被允许查询某个数据库,那么在身份、设备、上下文与访问策略都满足要求之后,允许它读取该资源,基本上就是这次安全决策需要产出的全部结果。访问关系成立,安全语义也就完成了。

但如果这项资源背后暴露的是支付、资产转移、生产部署、集群变更或设备控制能力,情况就不同了。假设一个 Agent 已经合法获得 payment.execute,零信任可以继续对这项能力做非常细的访问控制,包括限制主体、设备状态、时间窗口、来源环境乃至更多属性。而在现实动作真正发生之前,还有另一组问题需要有人回答:这次执行的金额是多少,最终对象是谁,这个对象是不是原始任务所指向的那个对象,审批所针对的是否仍然是同一个对象,用于判断的业务状态是否仍然新鲜,从审批到执行之间参数有没有被重新构造,累计执行是否已经越过某个不可接受的边界。

这些问题并不是在否定 Authorization,而是在指出一个可以被独立建模的安全对象:访问决策与执行资格不必是同一个决策

Zero Trust 控制主体与能力之间的访问关系;对抗性完整控制能力与现实结果之间的因果关系。

二、Zero Trust 消除默认信任,对抗性完整消除默认执行权

零信任最重要的贡献之一,是系统性地削弱了隐式信任(Implicit Trust)。请求来自内网不代表它天然可信,设备属于公司不代表它可以永久获得信任,主体刚刚完成认证也不意味着后续所有访问都应当自动通过。零信任因此不断地重新建立访问资格,把"信任"从一次性授予改造成持续评估。

但在真实的执行系统中,还存在另一类通常没有被单独命名的默认关系,可以称为隐式执行权(Implicit Execution Authority)。它有几种常见形态:一个 Agent 持有合法的 API 凭据,于是架构默认它可以自行构造最终执行参数;一个策略引擎返回 ALLOW,于是下游默认这个判断本身足以触发现实执行;一个管理域能够同时修改策略、签发凭据并控制执行组件,于是整个系统事实上把最终权力重新集中回了一处。

这些设计未必违反零信任的任何一条原则。它们完全可以建立在强身份、最小权限、持续授权与受保护资源之上,在访问层面无懈可击。真正需要追问的是另一个维度:从执行因果关系看,某一个主体是否已经积累了足够多的权力,使它能够在其他安全条件失效之后,仍然独立推动最终动作发生。

回答这个问题,需要把系统中的权力显式拆开,逐项落到具体主体上:谁能够提出 Action,谁能够决定 Target,谁能够修改执行参数,谁能够声明某项条件已经满足,谁能够提供 Approval,谁实际持有最终凭据,谁能够真正调用外部执行接口,以及谁能够修改上述规则本身。

这里被分析的对象已经不是 Identity,而是 Authority。本系列中,Authority 指的是能够影响一个受保护动作是否发生、以及以何种语义发生的因果能力。它未必对应某个身份,也未必对应某个部署单元;它对应的是"改变最终执行结果的能力"这件事在系统中的实际分布。

因此,对抗性完整并不是在零信任之上"多验证几次",而是更换了架构审计的基本单位。零信任问的是:这个主体现在是否应该获得访问资格。对抗性完整继续问:这个主体当前掌握的权力,是否已经足以独立造成一个受保护的现实结果。

Zero Trust 消除的是默认信任;对抗性完整进一步消除的是默认执行权。

三、Zero Trust 在不可信环境中仍要做对访问决策,对抗性完整把失陷直接写进执行结构

有一种常见的误读,是说零信任假设环境可信、而对抗性完整假设环境已经失陷。这不成立。NIST 的零信任模型本身就建立在"网络中可能已经存在攻击者"的前提之上,不因网络位置或资产归属赋予隐式信任,正是这一前提的直接推论。假设失陷,从来不是对抗性完整的独有特征。

真正的区别在于,失陷假设在两种模型中被用来回答不同的问题。零信任面对不可信环境时,主要目标仍然是把逐请求的访问决策做准确:主体是谁、设备状态如何、上下文是否异常、当前是否应当获得这次资源访问。失陷假设在这里是决策输入,用来提高判断的准确度和及时性。

对抗性完整则把失陷用作对执行架构本身的测试条件。它不问"我们能不能及时识别这个组件已经坏了",而是先设定它已经坏了、并且暂时没有被发现,然后检查执行路径上是否仍然存在一个它无法单独满足的条件。这种分析通常以失陷矩阵(Compromise Matrix)的形式展开:

假设失陷的 Authority攻击者由此获得的能力执行路径上是否仍存在其无法单独满足的条件
Agent构造任意 Intent、任意参数与任意调用序列针对该 Target 的独立 Approval,以及最终执行凭据
Policy Engine对任意请求输出 ALLOWIntent 与 Target 之间的绑定证明——ALLOW 不能替代绑定
编排层 / 控制面修改配置、替换下游组件、重放请求取决于执行不变量是否锚定在该控制域之外
Agent + Policy Engine一条自证合规的完整上游链路执行侧对绑定关系与 Boundary 的独立校验
全部 Authority 同时失陷完整控制超出威胁模型,不做任何安全声明

最后一行必须存在。对抗性完整不主张"所有组件、所有密钥、所有独立权力全部失陷之后系统依然安全"——这既不现实,也无法构成可验证的工程目标。它主张的是一个受威胁模型限定的性质:在预先定义的攻击模型中,对于允许发生的单一 Authority 失陷或特定 Authority 组合失陷,系统仍然不能绕过固定的执行不变量使受保护动作发生。威胁模型的边界在哪里,必须被写下来;写不下来的部分,就不属于这个性质覆盖的范围。

这个转变的工程意义在于,系统安全性开始从检测能力向结构约束迁移。前者依赖"我们必须及时发现这个组件已经坏了",后者要求"即使暂时没有发现它已经坏了,它仍然缺少独立完成受保护执行所需的全部权力"。检测依然重要,但它不再是唯一的兜底。

Zero Trust 尽量避免继续信任一个已经失陷的主体;对抗性完整假设它没有被及时发现,并要求它此时仍然凑不齐执行所需的全部权力。

四、Zero Trust 的基本抽象是访问策略,对抗性完整要求 Authority 被显式且完整地建模

零信任架构中的策略决策点与策略执行点是一组成熟设计:系统依据主体、资源与环境信息形成判断,再由相应的执行点落实这次访问决定。这个结构本身没有问题。需要补充追问的是:在策略决策之外,谁还掌握着能够改变最终结果的因果能力。

设想一个由四个组件构成的系统:

Agent → Policy Engine → Execution Gateway → Executor

从软件架构上看,这已经是四层。但如果它们全部处在同一个管理域之下,而这个管理域可以修改策略、签发凭据、替换执行组件配置,并直接调用外部执行接口,那么它们在权力结构上并不独立。攻击者不需要逐层突破四道安全边界,只需要控制那个能够重新定义这四层行为的根权力。两个独立部署的微服务可以属于同一个 Authority;反过来,同一台物理设备内的两个安全域,也可能因为独立密钥、独立策略与互不可覆盖的约束而构成两个 Authority。层数与独立权力数量是两个不同的变量,这一点在本系列讨论 Defense in Depth 时还会被专门展开。

因此,对抗性完整要求建立的不是组件清单,而是一张权力地图(Authority Map),逐项回答每个主体在执行因果链上到底能改变什么:

架构对象需要回答的问题
Agent能提出哪些动作?能决定哪些参数?
Policy Engine能判断什么?能否修改那些本应不可关闭的底线条件?
Approval Authority批准的到底是主体、动作类别,还是这一次的具体执行对象?
Gateway / Arbiter能组合哪些条件?能否独自形成一次 ALLOW?
Credential Holder谁实际掌握改变外部系统状态的能力?
Executor接受什么形式的证明?能否绕过上游建立的绑定关系?
Administrator能修改哪些 Authority?能否把多种权力重新集中到自己手中?

"完整"这个词首先落在这里,即 Authority Completeness:所有能够影响最终受保护动作的权力,都必须进入安全模型。如果某个主体实际上可以替换 Target、更换凭据或绕开某项约束,而威胁模型压根没有把它列为 Authority,那么后续所有安全论证都建立在一个不完整的模型之上,其结论的可靠性不会高于这个模型的完整性。

没有被建模的 Authority,不会因为没有被建模就失去改变现实的能力。

五、Zero Trust 阻止不该成立的访问关系,对抗性完整阻止合法路径上的错误现实结果

区分两者最直接的方法,是观察它们各自试图阻止的失败模式。

零信任非常擅长处理这样一类问题:一个不应访问生产数据库的主体试图取得访问;一份被盗用的凭据从异常设备发起请求;一个普通员工身份的主体试图触达超出其职责范围的资源。这些问题的共同结构是——主体与资源之间的访问关系本来就不应该成立。识别这种不该成立的关系并加以阻断,正是零信任被设计出来要做的事,而且它做得很好。

而在具备执行能力的系统中,会出现另一种失败模式:主体是合法的,凭据是合法的,设备满足要求,权限完全允许调用当前接口,策略决策也被正确地计算了出来。错误不在于关系是否成立,而在于动作本身。原始意图是"向对象 A 执行金额 X 的操作",而最终到达执行器的却是"向对象 B 执行金额 Y 的操作"。如果安全体系证明的命题只是"该主体有资格调用执行接口",那么这条命题可以从头到尾为真,现实结果依然是错的。

这里必须避免一个不诚实的论证。现代授权体系完全有能力检查 Action、Target、Amount 与交易上下文——成熟的 ABAC、PBAC 与细粒度授权可以表达大量这类条件,这不是它们表达能力的缺陷。真正的分歧在两个架构性问题上。

第一个问题是条件的地位:这些条件只是某个可变策略的输入,还是已经成为最终执行能力无法绕过的不变量。可以被同一个失陷主体重写的条件,在该主体失陷的场景下不提供任何保证。

第二个问题是权力的重叠:做出授权决策的 Authority,是否同时拥有修改条件与完成最终执行的能力。如果同一个主体既能定义"什么是允许的",又能决定"这一次实际发生了什么",还持有最终执行凭据,那么无论策略写得多细,执行路径上仍然存在一个足以独立成事的单点权力。

还有一个更容易被忽略的结构性缝隙:授权决策的对象是一次请求的描述,而执行的对象是一组最终参数。只要在决策与执行之间还存在任何可以重新构造参数的环节,授权决策的语义就不会自动传递到执行结果。策略执行点通常拦截的是"是否放行这次请求",而不是"被放行的这次请求,与被批准的那次意图是不是同一件事"。对抗性完整关心的这一类失败——Authorized but Undesirable Execution——大多恰好落在这道缝隙里。

Zero Trust 阻止不该成立的访问关系;对抗性完整阻止一条完全合法的访问路径产生不应发生的现实结果。

六、对抗性完整的强度来自执行不变量,而不是审批环节的数量

如果对抗性完整只是要求"多几个系统共同批准",它最终会退化为一种普通的纵深防御——增加攻击成本,但不改变权力结构。让它成为一种可分析的架构属性的,是执行不变量(Execution Invariants):无论上层主体是谁、无论某些策略如何变化、无论威胁模型中允许失陷的某个 Authority 是否已经被控制,受保护执行仍然存在一组不能被单方面关闭的条件。

一个系统可能采用的不变量,例如:

最终 Action 必须与原始 Intent 保持绑定 → 最终 Target 必须与被批准的对象一致 → Approval 必须针对同一个 Action 与 Target → 用于判断的状态证据必须仍在有效期内 → 执行必须落在预先声明的 Boundary 之内 → 缺失、过期或相互冲突的必要证据不得被解释为条件已满足

具体采用哪几条并不是重点,不同业务的不可逆性与恢复成本差别很大,条件集合本就应该不同。重点是这组条件在权力结构中的位置:在给定威胁模型下,是否任何一个被允许失陷的单一 Authority,都不能同时做到自己定义条件、自己证明条件成立、再自己完成最终执行。

据此,本文使用的定义可以收紧为:

对抗性完整是一种受保护执行架构属性:所有能够影响受保护动作的权力主体都必须被显式建模;在预先定义的攻击模型下,任何允许发生的单一主体失陷或主体组合失陷,都不能绕过系统固定的执行不变量,使受保护动作发生。

它至少由四个部分组成。Authority Completeness 要求所有关键权力进入模型;Explicit Threat Model 要求明确哪些 Authority 可以失陷、允许哪些组合失陷;Execution Invariants 要求存在不能被允许失陷主体单方面关闭的执行条件;Compromise Resistance 要求在上述失陷情形下,攻击者仍然无法独立构造一条完整的执行路径。

这四项合在一起,把对抗性完整从一句"不要信任任何组件"的口号,变成了一个可以被具体分析、也可以被具体证伪的问题:给定威胁模型与权力地图,是否存在一条从允许失陷的 Authority 集合直接到达受保护执行的可行路径。如果存在,就说明这个架构在该威胁模型下存在对抗性完整缺口;如果不存在,且所有可行执行路径都必须经过系统定义的不变量,才可以说这个架构在这个威胁模型下具备对抗性完整。换个威胁模型,结论需要重新计算——这个属性从来不是绝对的,它总是相对于一个写得出来的攻击假设而成立。

结语:Trust 决定关系,Authority 决定后果

把这两个概念并置为 "Zero Trust vs Adversarial Completeness",容易让人以为必须在两套安全体系之间做选择。实际关系恰好相反。一个高风险的 Agent 执行系统首先应当拥有成熟的零信任:强身份、设备状态、最小权限、持续授权、资源保护、风险分析与细粒度策略,一项都不能少。缺少这些,对抗性完整所依赖的权力划分本身就没有可靠的落脚点——你无法在无法辨认主体的系统里讨论主体之间的权力分配。

两者真正的分界,不在"旧安全"与"新安全"之间,也不在"身份安全"与"AI 安全"之间,而在两个不同的控制对象上。Trust 决定主体与资源之间的关系;Authority 决定主体对现实结果拥有多大的因果能力。当软件主要用于读取和生成信息时,这两个问题往往可以在同一套访问控制体系中一并处理,因为"能访问"与"能造成后果"之间的距离很短。而当机器主体开始自主操作资金、基础设施、生产系统与物理设备,这段距离会迅速拉开:一个主体完全可以在零信任意义上通过全部必要验证,同时仍然握有过大的现实执行能力。

于是下一个问题自然出现。既然风险的来源是 Authority 而不仅仅是 Permission,那么"最小权限"这个已经被广泛接受的原则,是否仍然足以描述一个执行主体应当拥有的最小能力?把接口权限压缩到最小,与把现实执行能力压缩到最小,是不是同一件事?这正是下一篇要处理的问题:Least Privilege vs Least Execution Authority

零信任已经教会安全系统不要默认相信任何主体。进入真实执行之后,还需要继续追问一句:既然并不相信它,为什么仍然让它保有这么大的执行权。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐