OPA策略在流水线中的构建产物签名验证与合规阻断 - 第2节
2.1 OPA 整体架构
Open Policy Agent (OPA) 是一个开源的、通用策略引擎,它将策略决策与策略执行解耦。在 DevSecOps 流水线中,OPA 作为“策略决策点”(Policy Decision Point, PDP)独立运行,通过标准的 API 接口接收查询并返回决策结果。
核心架构原则:OPA 不负责执行策略(如阻断流水线),而是负责回答“是否允许”的问题。执行动作由调用方(如 CI/CD 工具、API 网关)根据 OPA 的决策结果自行实施。
2.1.1 架构组件说明
| 组件 | 角色 | 说明 |
|---|---|---|
| 策略执行点 (PEP) | 调用方 | CI/CD 工具、API 网关、Kubernetes Admission Controller 等,向 OPA 发起查询并执行决策结果 |
| 策略决策点 (PDP) | OPA 引擎 | 接收查询请求,结合策略规则与数据文档,返回决策结果(allow/deny) |
| 数据文档 | 外部数据 | JSON/YAML 格式的上下文数据,如构建产物元数据、签名信息、环境标签等 |
| 策略规则库 | Rego 策略 | 用 Rego 语言编写的策略规则集合,定义合规条件与阻断逻辑 |
2.2 Rego 语言核心概念
Rego 是 OPA 专用的声明式策略语言,灵感来源于 Datalog。与通用编程语言不同,Rego 专注于“数据查询”和“规则定义”,而非“流程控制”。
2.2.1 基本语法结构
package pipeline.verify
# 规则定义:签名验证通过
default allow = false
allow {
input.signature.valid == true
input.signature.algorithm == "SHA256-RSA"
input.signature.expiry > time.now_ns()
}
# 规则定义:产物来源可信
allow {
input.provenance.builder == "trusted-builder"
input.provenance.slsa_level >= 2
}
关键理解:Rego 规则由
package(包声明)、default(默认值)、规则头 和 规则体 组成。规则体中的多个条件之间是逻辑“与”(AND)关系;多个同名规则之间是逻辑“或”(OR)关系。
2.2.2 数据模型:input 与 data
| 命名空间 | 来源 | 示例 |
|---|---|---|
input |
查询请求时传入的临时数据 | input.signature.hash、input.artifact.name |
data |
OPA 启动时加载的持久化数据 | data.trusted_signers、data.allowed_registries |
2.3 规则模型与决策逻辑
2.3.1 规则类型
| 类型 | 语法 | 用途 |
|---|---|---|
| 完整规则 | r = v { ... } |
返回一个确定的值,如 allow = true |
| 部分规则 | r[x] { ... } |
生成一组结果集合,如 violations[msg] |
| 默认规则 | default r = v |
为规则设置默认值,防止未定义 |
2.3.2 决策组合模式
在流水线签名验证场景中,通常采用“允许列表 + 阻断列表”的组合决策模式:
package pipeline.verify
# 默认拒绝
default allow = false
# 允许条件:签名有效且签名者受信任
allow {
input.signature.valid == true
data.trusted_signers[input.signature.signer]
}
# 阻断条件:签名者被明确列入黑名单
deny[reason] {
input.signature.valid == true
data.blocked_signers[input.signature.signer]
reason := sprintf("签名者 %v 已被列入黑名单", [input.signature.signer])
}
# 阻断条件:签名已过期
deny[reason] {
input.signature.expiry < time.now_ns()
reason := "签名已过期,请重新签名"
}
重要实践:在流水线合规阻断中,建议始终使用
default allow = false(默认拒绝)模式。任何未明确允许的请求都应被阻断,这符合安全最小权限原则。同时使用 deny 规则提供详细的阻断原因,便于流水线输出可读的错误信息。
2.4 数据与规则的加载方式
2.4.1 数据加载
- 启动时加载:通过
--data参数加载 JSON/YAML 文件,作为data命名空间的持久数据 - API 推送:通过 OPA REST API
PUT /v1/data动态更新数据文档 - Bundle 服务:从 Bundle 服务器拉取打包的策略与数据,支持版本管理和热更新
2.4.2 策略加载
- 文件加载:通过
--policy参数加载.rego策略文件 - Bundle 打包:将多个
.rego文件打包为.tar.gz,通过 Bundle API 分发 - 内联策略:在查询请求中直接携带策略(适用于测试和轻量场景)
流水线集成建议:在生产环境中,推荐使用 Bundle 服务管理策略与数据。将签名验证策略、受信任签名者列表、黑名单等打包为 Bundle,CI/CD 流水线中的 OPA 客户端定期拉取最新版本,确保策略的实时更新与一致性。