土法炼钢兴趣小组的算法知识备份

【零信任安全架构】零信任策略引擎:OPA/Rego 与 Cedar 在 ZT 中的落地

文章导航

分类入口
architecturesecurity
标签入口
#policy-engine#opa#rego#cedar#open-policy-agent#zero-trust#pdp#pep

目录

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 只要有一条规则 truetrue,而 deny 独立于 allow 这意味着如果编码不严谨,可能同时输出 allow: true, deny: ["policy violation X"]——这不是冲突检测,而是两个没有交叉引用的判断。

正确的做法是为 allowdeny 建立明确的分级关系:

# 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["合并 → 部署"]

4.2 策略变更的 blast radius 控制

零信任策略的变更风险很大——一条规则写错可能导致全公司的工程师都无法访问生产数据库。控制 blast radius 的方法:

五、总结

零信任对策略引擎的额外要求不是功能性——OPA 和 Cedar 都能实现多维输入的策略评估——而是工程性

  1. 动态输入的整合:设备姿态、网络位置、时间和行为这四个高度动态的维度如何高效地进入策略引擎——是预聚合在 PDP 内部还是每次请求时外部查询。
  2. 冲突检测和优先级:当身份维度允许但设备维度拒绝时,最终结果是什么——这个答案不能是”取决于实现者”,而应该是策略引擎的明确定义。
  3. 策略变更的安全流程:一条策略的变更可能影响数千用户的访问——如何在不造成大面积拒绝的情况下安全上线新策略。

下一篇:微分段深度拆解

参考资料

  1. Open Policy Agent. OPA Documentation. https://www.openpolicyagent.org/docs/latest/
  2. AWS. Cedar Policy Language Guide. https://www.cedarpolicy.com/
  3. NIST SP 800-207. Zero Trust Architecture, Section 3.3 (Trust Algorithm).

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-06-18 · architecture / security

【身份与访问控制工程】OPA、Cedar 与策略引擎落地

OPA 是 CNCF 的策略引擎标准答案,Rego 是它的策略语言;Cedar 是 AWS 开源的新竞争者,基于 Rust 的 WASM 编译执行、语法更接近 SQL。两者在架构模式(sidecar vs 中心化)、策略语言设计哲学和性能特征上有根本差异。本文从策略引擎的架构模式出发,拆解 OPA Rego 的核心语义与性能限制、Cedar 的设计取舍,以及策略即代码(Policy as Code)在 CI/CD 中的落地。

2026-06-12 · architecture / security

【零信任安全架构】NIST SP 800-207 架构深度拆解:不只是 7 条原则

NIST SP 800-207 给了零信任最权威的定义,但大多数讨论只复述了 7 条原则。本文拆解 NIST 文档的完整架构模型:PEP、PDP、Policy Engine、Policy Administrator 的分工与交互协议、信任算法的三种模型、以及 NIST 有意留白留给实现者的工程决策。

2026-06-13 · architecture / security

【身份与访问控制工程】IAM 全景:为什么这是高价值赛道

从 2020 年 SolarWinds 到 2024 年 Okta 支持系统泄露,身份基础设施的安全失败反复证明一件事:IAM 不是 IT 支撑系统,而是安全架构的承重墙。本文建立现代 IAM 的全景地图——从认证协议、令牌体系、权限模型到身份治理与平台选型,给出 5 个贯穿全系列的核心问题。

2026-06-17 · architecture / security

【身份与访问控制工程】服务身份:mTLS、SPIFFE/SPIRE 与 Workload Identity

前 9 篇讨论的都是'人'的身份——用户怎么登录、怎么验证。但微服务世界中,80% 的 API 调用是服务之间的。服务身份(Workload Identity)是整个 IAM 体系的另一半:mTLS 解决'传输层你是谁',SPIFFE/SPIRE 解决'在平台层你是谁且怎么证明',JWT Profile for OAuth 解决'我怎么拿到一个服务身份的 Token'。本文从这三条线拆解服务身份的工程实现。


By .