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 容器的形式运行。

OPA 架构与策略评估流程 CI/CD 工具 (Jenkins / GitLab CI) Input OPA 引擎 策略评估 (Rego 解释器) Output 流水线执行器 (阻断/放行) Data 源 (配置文件 / Bundle) 加载 Data Policy 源 (.rego 文件) 加载 Policy 说明 Input + Data + Policy → Output

2.6 策略评估生命周期

一次完整的策略评估遵循以下步骤:

  1. 加载:OPA 启动时加载所有 .rego 策略文件和 Data 文件。
  2. 查询:CI/CD 工具通过 REST API 或 Go 库向 OPA 发送查询请求,并附带 Input。
  3. 匹配:OPA 引擎根据 Input 和 Data,在 Policy 中查找匹配的规则。
  4. 聚合:将所有匹配的规则结果进行聚合(例如,只要有一条 deny 规则匹配,最终结果即为拒绝)。
  5. 返回:OPA 将决策结果(Output)返回给调用方。
注意: OPA 的默认行为是“静默忽略未匹配的规则”。因此,务必在策略中显式声明 default allow = false,否则未覆盖到的请求可能会被意外放行。

2.7 本章小结