在 OPA、Cedar 与策略引擎落地 中我们讨论了策略引擎的通用架构——sidecar vs 中心化、Rego 的声明式语义、Cedar 的 WASM 执行。但零信任对策略引擎提出了额外的要求:它需要处理的输入维度更多(身份 + 设备 + 网络 + 行为 + 时间),更新频率更高(从周级策略变更为每请求的信号变化),且决策必须在策略冲突时有明确的分辨逻辑。
前置阅读:IAM 系列的策略引擎篇。
一、零信任策略的四维输入模型
NIST SP 800-207 的信任算法接收七个类别的输入。工程上可以归纳为四个核心维度:
| 维度 | 内容 | 更新特性 |
|---|---|---|
| 主体(Who) | 用户身份、服务身份、组成员、历史行为 | 用户身份较稳定,组成员变化按天/周 |
| 资源(What) | 数据敏感级别、API 端点、操作类型 | 相对静态 |
| 环境(How safe) | 设备姿态、网络位置、时间、地理位置 | 高度动态(分钟级变化) |
| 操作(What action) | read/write/delete/admin | 每次请求携带 |
flowchart LR
subgraph "每次访问请求的输入"
Subject["主体<br/>user: zhangsan<br/>groups: [engineering]<br/>auth_method: fido2"]
Resource["资源<br/>resource: prod-db-01<br/>sensitivity: HIGH<br/>endpoint: /api/users"]
Context["环境<br/>device_tier: trusted<br/>network: corporate-wifi<br/>time: 03:14 UTC<br/>location: CN"]
Action["操作<br/>action: SELECT<br/>table: users"]
end
Subject --> PE["Policy Engine<br/>(PDP)"]
Resource --> PE
Context --> PE
Action --> PE
PE --> Decision["Allow / Deny / Step-up"]
四个维度的组合爆炸是零信任策略复杂性来源——不是”谁能访问什么”(N 个策略),而是”谁在什么设备上、从什么地方、在什么时间、能对什么做什么操作”(N×M×P×Q 个可能的组合)。
二、OPA/Rego 在零信任策略中的实践
2.1 多维输入的 Rego 建模
Rego 的多维输入在零信任场景中尤其合适——它的规则可以自然地组合多个维度的条件:
package zero_trust.authz
import rego.v1
# 默认拒绝
default allow := false
# 高敏感资源访问策略
allow if {
input.action.operation == "read"
input.resource.sensitivity == "HIGH"
input.subject.groups[_] == "engineering"
input.context.device_tier == "trusted"
input.context.mfa_completed == true
not is_outside_business_hours
not is_anomalous_location
}
# 中敏感资源访问策略(Basic 设备也可以)
allow if {
input.resource.sensitivity == "MEDIUM"
input.context.device_tier in {"trusted", "basic"}
}
# 异常检测:凌晨 1-5 点访问高敏感资源
deny_with_step_up contains msg if {
input.resource.sensitivity == "HIGH"
is_outside_business_hours
msg := "High-sensitivity access outside business hours requires step-up auth"
}
is_outside_business_hours if {
hour := time.clock(input.context.timestamp)[0]
hour < 7
}
is_outside_business_hours if {
hour := time.clock(input.context.timestamp)[0]
hour >= 20
}
is_anomalous_location if {
last_country := input.subject.last_login_country
current_country := input.context.geo.country
last_country != current_country
}
2.2 Rego 的性能限制在零信任场景中的放大
在 IAM
策略引擎篇 中讨论了 Rego
的评估模型。在零信任场景中,一个额外的挑战是策略规则的数据依赖性——环境维度的数据(设备姿态、IP、地理位置)在每个请求中都可能不同,但
Rego 的 data 文档更新频率远低于请求频率。
典型实践:OPA sidecar 的 data 文档每分钟从
Bundle Server 更新一次——但设备姿态在两次更新之间的 60
秒内可能已经变化了。解决方案是为高动态数据使用 OPA
的”外部数据查询”模式——在策略中调用外部 API
获取最新设备姿态,但这引入了网络延迟,破坏了 OPA
作为本地决策引擎的性能优势。
# 使用 OPA 的 http.send 内置函数查询实时设备姿态
device_tier := http.send({
"url": sprintf("https://device-inventory.internal/device/%s/tier",
[input.context.device_id]),
"method": "GET",
"force_cache": false,
"force_cache_duration_seconds": 30,
}).body.tier
2.3 策略冲突检测
当一个 Rego 包中有 50
条规则时,多条规则可能同时命中同一个请求——Rego
的默认行为是:allow 只要有一条规则
true 就 true,而 deny
独立于 allow。
这意味着如果编码不严谨,可能同时输出
allow: true, deny: ["policy violation X"]——这不是冲突检测,而是两个没有交叉引用的判断。
正确的做法是为 allow 和 deny
建立明确的分级关系:
# deny 优先于 allow
final_decision := "deny" if {
count(deny) > 0
}
final_decision := "allow" if {
count(deny) == 0
allow
}
final_decision := "deny" if {
not allow
}
三、Cedar 在零信任场景中的设计优势
Cedar(AWS 开源,Rust + WASM)的设计决策在零信任场景中有特定优势:
3.1 强制拒绝优先
与 Rego 的”所有 allow 规则 OR 在一起”不同,Cedar
的策略评估是强制拒绝优先——forbid
语句总是优先于 permit 语句。这意味着即使有 100
条 permit 规则命中了请求,一条匹配的
forbid 会否决全部。
// Cedar 策略示例
@id("allow-engineering-read-high-sensitivity")
permit(
principal == User::"zhangsan",
action == Action::"read",
resource
)
when {
resource.sensitivity == "HIGH" &&
principal.groups.contains("engineering") &&
context.device_tier == "trusted"
};
// 强制拒绝:中国大陆在凌晨 1-5 点禁止访问高敏感资源
@id("forbid-china-night-access")
forbid(
principal,
action,
resource
)
when {
resource.sensitivity == "HIGH" &&
context.geo.country == "CN" &&
context.time.hour >= 1 &&
context.time.hour < 5
};
Cedar 的强制 forbid 优先制消除了 Rego
中”allow 规则和 deny
规则打架”的问题,这对零信任策略的审计合规是重要的——安全团队不需要推理所有
allow 规则的逻辑来确认没有漏洞。
3.2 WASM 编译 → 进程内执行
Cedar 策略被编译成 WASM 模块,在应用的同一个进程中执行——没有网络调用延迟。在”每个请求都评估”的零信任模式下,Cedar 的进程内执行模式比 OPA 的 sidecar HTTP 调用模式少了一层网络延迟。
但 Cedar 的局限性在于:它不能像 OPA
那样从外部数据源动态拉取数据——设备姿态、威胁情报、组信息等必须在调用
Cedar 之前组装成 context 输入。这意味着调用
Cedar 的应用需要先自己解析所有外部信号,然后一并推给
Cedar——这是架构上一个有意的简化,代价是调用方需要处理多源的数据聚合。
3.3 策略分析工具
Cedar
附带了一个策略分析器(cedar-policy-validator),可以在编译时检测策略冲突和冗余。这比
Rego 的 opa test
更进一步——opa test 验证策略对特定输入的输出,而
Cedar 的分析器验证策略的逻辑一致性:
$ cedar-policy-validator validate \
--schema schema.json \
--policies policies.cedar
Policy conflict detected:
@id("allow-device-basic-high-sensitivity") permits Basic device access to HIGH sensitivity resources,
but @id("require-trusted-for-high-sensitivity") forbids it.这种预编译的策略一致性检查对于大规模零信任部署至关重要——当安全团队有 500+ 条 ZT 策略时,手动检查每条策略和其他 499 条之间的关系是不可能的。
四、策略即代码的 ZT 落地
零信任的准入策略不能用”在 UI 上点几个 checkbox”的方式管理——当你需要对 “允许 engineering 组在 Trusted 设备上、从 CN 的 IP 访问 prod 高敏感数据库的 SELECT 操作” 这样的策略做变更时,UI 形式无法正确传达它的意图和影响。
4.1 PR 审核流程
flowchart LR
Dev["安全工程师<br/>写策略"] --> PR["提交 PR<br/>.zt-policies/production.rego"]
PR --> Review["另一个安全工程师<br/>Review"]
Review --> Test["CI 跑策略测试<br/>(opa test / cedar validate)"]
Test --> Sandbox["策略沙箱<br/>(Shadow Mode)"]
Sandbox --> Deploy["合并 → 部署"]
- 策略测试:在 CI 中运行
opa test或 Cedar validator,确保新策略不会破坏现有策略集。 - Shadow Mode(策略沙箱):新策略上线后先在 shadow mode 运行——策略引擎执行新策略但不强制执行,只记录”如果强制执行的话这项请求会被允许/拒绝”。监控 1-3 天后对比新旧策略的决策差异,确认无误才启用。
- 回滚:策略存储在 Git 中,出问题时通过
git revert回滚到上一个已知正常的版本。
4.2 策略变更的 blast radius 控制
零信任策略的变更风险很大——一条规则写错可能导致全公司的工程师都无法访问生产数据库。控制 blast radius 的方法:
- 按环境分级部署:dev → staging → production 依次上线。在 dev 环境验证 1 天,在 staging 验证 1 天,再推到 production。
- 按用户群灰度:先在用户的子集(如安全团队自己)上启用新策略,确认无误后扩展到全公司。
- 紧急回滚开关:全局的”熔断”开关——当大面积拒绝事件发生时,PEP 可以降级为”仅基于身份验证的 allow/deny”,忽略设备和环境维度的策略。
五、总结
零信任对策略引擎的额外要求不是功能性——OPA 和 Cedar 都能实现多维输入的策略评估——而是工程性:
- 动态输入的整合:设备姿态、网络位置、时间和行为这四个高度动态的维度如何高效地进入策略引擎——是预聚合在 PDP 内部还是每次请求时外部查询。
- 冲突检测和优先级:当身份维度允许但设备维度拒绝时,最终结果是什么——这个答案不能是”取决于实现者”,而应该是策略引擎的明确定义。
- 策略变更的安全流程:一条策略的变更可能影响数千用户的访问——如何在不造成大面积拒绝的情况下安全上线新策略。
下一篇:微分段深度拆解。
参考资料
- Open Policy Agent. OPA Documentation. https://www.openpolicyagent.org/docs/latest/
- AWS. Cedar Policy Language Guide. https://www.cedarpolicy.com/
- NIST SP 800-207. Zero Trust Architecture, Section 3.3 (Trust Algorithm).
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【身份与访问控制工程】OPA、Cedar 与策略引擎落地
OPA 是 CNCF 的策略引擎标准答案,Rego 是它的策略语言;Cedar 是 AWS 开源的新竞争者,基于 Rust 的 WASM 编译执行、语法更接近 SQL。两者在架构模式(sidecar vs 中心化)、策略语言设计哲学和性能特征上有根本差异。本文从策略引擎的架构模式出发,拆解 OPA Rego 的核心语义与性能限制、Cedar 的设计取舍,以及策略即代码(Policy as Code)在 CI/CD 中的落地。
【零信任安全架构】NIST SP 800-207 架构深度拆解:不只是 7 条原则
NIST SP 800-207 给了零信任最权威的定义,但大多数讨论只复述了 7 条原则。本文拆解 NIST 文档的完整架构模型:PEP、PDP、Policy Engine、Policy Administrator 的分工与交互协议、信任算法的三种模型、以及 NIST 有意留白留给实现者的工程决策。
【身份与访问控制工程】IAM 全景:为什么这是高价值赛道
从 2020 年 SolarWinds 到 2024 年 Okta 支持系统泄露,身份基础设施的安全失败反复证明一件事:IAM 不是 IT 支撑系统,而是安全架构的承重墙。本文建立现代 IAM 的全景地图——从认证协议、令牌体系、权限模型到身份治理与平台选型,给出 5 个贯穿全系列的核心问题。
【身份与访问控制工程】服务身份:mTLS、SPIFFE/SPIRE 与 Workload Identity
前 9 篇讨论的都是'人'的身份——用户怎么登录、怎么验证。但微服务世界中,80% 的 API 调用是服务之间的。服务身份(Workload Identity)是整个 IAM 体系的另一半:mTLS 解决'传输层你是谁',SPIFFE/SPIRE 解决'在平台层你是谁且怎么证明',JWT Profile for OAuth 解决'我怎么拿到一个服务身份的 Token'。本文从这三条线拆解服务身份的工程实现。