2. OPA 基础概念:Policy、Rego 语言、Data、Input、Output、OPA 架构概述
在将 OPA 集成到自动化流水线之前,必须理解其核心概念与运行机制。OPA 的核心思想是将策略决策与策略执行解耦。它本身不执行任何操作(如拒绝请求、删除文件),而是根据你提供的策略(Policy)和数据(Data),对给定的输入(Input)做出决策,并输出决策结果(Output)。
2.1 核心概念速览
| 概念 | 定义 | 流水线场景类比 |
|---|---|---|
| Policy(策略) | 用 Rego 语言编写的规则集合,定义了“允许”或“拒绝”的逻辑。 | “构建产物中不得包含高危漏洞”、“镜像必须来自私有仓库”。 |
| Rego 语言 | OPA 专用的声明式查询语言,专为定义策略而设计。 | 编写策略的“语法”和“表达方式”。 |
| Data(数据) | OPA 加载的全局上下文信息,通常是 JSON 或 YAML 格式。 | “允许的镜像仓库列表”、“已知的 CVE 数据库”、“项目元数据”。 |
| Input(输入) | 每次策略评估时,由外部系统(如 CI/CD 工具)传入的临时请求。 | “本次构建产物的 SBOM 清单”、“镜像的 Dockerfile 内容”。 |
| Output(输出) | OPA 执行策略后返回的决策结果,通常包含 allow 或 deny。 |
“允许通过”或“阻断流水线并返回失败原因”。 |
2.2 Policy 与 Rego 语言
Policy 是 OPA 的灵魂,而 Rego 是定义灵魂的语言。Rego 是一种声明式语言,你只需描述“想要什么状态”,而不是“如何实现”。
- 声明式 vs 命令式:在 Rego 中,你写
result := 1 + 2而不是result = 1; result = result + 2。 - 规则(Rules):Rego 文件由规则组成。规则可以是完整规则(返回单个值)或部分规则(返回一组值)。
- 默认值:使用
default allow = false来设置安全基线,确保未匹配到的请求默认被拒绝。
示例:一个简单的 Rego 策略片段
package pipeline.policy
# 默认拒绝所有请求
default allow = false
# 规则:如果构建产物来自允许的仓库,则允许通过
allow {
input.repository == data.allowed_repositories[_]
}
# 规则:如果构建产物通过了安全扫描,也允许通过
allow {
input.scan_result == "pass"
}
2.3 Data 与 Input 的区别
理解 Data 和 Input 的区别是正确使用 OPA 的关键。两者都是 JSON 数据,但生命周期和作用域完全不同。
| 特性 | Data(数据) | Input(输入) |
|---|---|---|
| 来源 | 通过 OPA 启动参数、API 或 Bundle 加载 | 每次策略查询时由调用方(如 Jenkins)传入 |
| 生命周期 | 持久化,直到被更新或重载 | 瞬态,仅针对单次请求有效 |
| 典型内容 | 白名单、黑名单、配置基线、全局规则 | 本次构建的产物哈希、漏洞列表、镜像标签 |
| 访问方式 | data.<package>.<key> |
input.<field> |
最佳实践: 将频繁变更或与环境强相关的配置(如“允许的镜像仓库”)放在 Data 中;将每次构建独有的信息(如“本次构建的产物 ID”)放在 Input 中。
2.4 Output 的结构
OPA 的 Output 通常是一个 JSON 对象,包含决策结果和可选的详细原因。在流水线集成中,我们通常关注以下字段:
- allow:布尔值,
true表示通过,false表示阻断。 - deny:数组,列出所有违反的策略描述,用于向开发者展示失败原因。
- warnings:数组,列出非阻断性的建议。
{
"allow": false,
"deny": [
"构建产物包含高危漏洞 CVE-2024-1234",
"镜像标签 'latest' 不允许用于生产环境"
],
"warnings": [
"建议使用多阶段构建以减小镜像体积"
]
}
2.5 OPA 架构概述
OPA 采用客户端-服务器或嵌入式库两种架构模式。在 CI/CD 流水线中,通常以独立服务或Sidecar 容器的形式运行。
2.6 策略评估生命周期
一次完整的策略评估遵循以下步骤:
- 加载:OPA 启动时加载所有
.rego策略文件和 Data 文件。 - 查询:CI/CD 工具通过 REST API 或 Go 库向 OPA 发送查询请求,并附带 Input。
- 匹配:OPA 引擎根据 Input 和 Data,在 Policy 中查找匹配的规则。
- 聚合:将所有匹配的规则结果进行聚合(例如,只要有一条
deny规则匹配,最终结果即为拒绝)。 - 返回:OPA 将决策结果(Output)返回给调用方。
注意: OPA 的默认行为是“静默忽略未匹配的规则”。因此,务必在策略中显式声明
default allow = false,否则未覆盖到的请求可能会被意外放行。