2. OPA 基础概念:Policy、Rego 语言、Data 与 Input、查询与决策、OPA 的架构与工作模式

本章是 OPA 策略引擎的认知基石。你将系统性地理解 OPA 的核心概念:Policy(策略)、Rego 语言、Data 与 Input、查询与决策,以及 OPA 的整体架构与工作模式。掌握这些基础,是后续编写 IaC 门禁策略的前提。

2.1 Policy(策略)—— 什么是 OPA 策略

在 OPA 中,Policy 是一组用 Rego 语言编写的规则集合,用于描述系统应该遵循的约束条件。策略的本质是:给定一个输入(Input)和一组数据(Data),输出一个决策(Decision)。

  • 策略文件:通常以 .rego 为后缀,存储在文件系统或 Bundle 中。
  • 策略包(Package):每个 .rego 文件的第一行声明所属包,用于命名空间隔离。
  • 规则(Rule):策略的核心单元,由条件表达式和赋值组成。
关键理解:OPA 的策略是声明式的,你只需描述“允许什么”,而不需要编写“如何检查”的过程代码。

2.2 Rego 语言 —— 策略的表述方式

Rego 是 OPA 的原生查询语言,受 Datalog 启发,专为在复杂嵌套文档上执行策略而设计。它不是通用编程语言,而是策略即代码(Policy as Code)的专用 DSL。

特性 说明
声明式 你定义“是什么”,而非“怎么做”。OPA 引擎自动推导结果。
不可变 变量一旦绑定,不能重新赋值。这消除了副作用,使策略易于推理。
嵌套文档友好 原生支持 JSON/YAML 的嵌套结构,使用点号(.)和方括号([])访问。
内置函数丰富 提供字符串、正则、集合、时间、JWT 等大量内置函数。

一个简单的 Rego 规则示例:

package example.allow

# 规则:如果请求的 role 是 "admin",则允许
default allow = false

allow {
    input.role == "admin"
}

2.3 Data 与 Input —— 策略的两大输入源

OPA 的每次决策都基于两个关键输入:Input 和 Data。理解它们的区别至关重要。

维度 Input(输入) Data(数据)
来源 每次查询时由调用方(如 API 请求、Terraform 计划)动态传入 预加载到 OPA 中的持久化数据(如配置文件、外部数据库、Bundle)
生命周期 单次请求有效 持久存在,直到被更新或重新加载
典型内容 当前请求的详细信息(用户、操作、资源属性) 全局规则、白名单、黑名单、外部参考数据
访问方式 input.xxx data.xxx
实战场景:在 IaC 门禁中,input 通常是 Terraform 的 plan.json(包含即将创建的资源),而 data 可以是公司内部的合规基线(如“禁止创建公网暴露的 RDS”)。

2.4 查询与决策 —— 策略的执行结果

OPA 通过查询(Query)来获取决策(Decision)。查询可以是简单的布尔判断,也可以是复杂的数据提取。

  • 查询方式:通过 REST API(POST /v1/data/<package.path>)或命令行(opa eval)。
  • 决策结果:OPA 返回一个 JSON 对象,包含查询路径下的所有规则计算结果。
  • 决策类型:
    • 布尔决策:true / false(如 allow 规则)。
    • 结构化决策:返回对象、数组或字符串(如 violations 列表)。

查询示例:

# 查询 example.allow 包下的所有规则
POST /v1/data/example/allow

# 响应
{
  "result": {
    "allow": true
  }
}

2.5 OPA 的架构与工作模式

OPA 可以以多种模式运行,适应不同的集成场景。下图展示了 OPA 的核心架构组件及其数据流。

OPA 核心架构与数据流 外部系统 (Terraform / K8s / API) Input (JSON) OPA 策略引擎 Rego 解释器 规则求值器 内置函数库 缓存管理 Data 来源 (Bundle / 外部数据) Data (JSON) 策略存储 (.rego 文件 / Bundle) 加载策略 决策 (JSON) 决策结果 (allow / deny / 详情)

2.6 三种工作模式

OPA 支持三种主要的工作模式,以适应不同的部署场景。

模式 部署方式 适用场景 特点
Sidecar / Daemon 作为独立进程运行,提供 REST API Kubernetes 准入控制、微服务网关 低延迟、可缓存、支持热加载
Library(库模式) 作为 Go 库嵌入到应用中 需要深度集成的自定义工具 无网络开销、部署简单
CLI(命令行) 通过 opa eval 或 opa test 执行 本地开发、CI/CD 流水线、单元测试 无需服务、适合自动化
OPA 三种工作模式对比 Sidecar / Daemon 独立进程运行 提供 REST API 支持 Bundle 热加载 低延迟缓存 K8s / 微服务 Library(库模式) 嵌入 Go 应用 无网络开销 直接函数调用 部署简单 自定义工具 CLI(命令行) opa eval / test 无需启动服务 适合 CI/CD 单元测试 流水线门禁
模式选择建议:在 IaC 门禁场景中,CLI 模式最适合集成到 CI/CD 流水线(如 GitLab CI、Jenkins),因为它无需维护常驻服务,且易于在容器化环境中执行。Sidecar 模式更适合需要实时决策的 Kubernetes 准入控制器场景。

2.7 本章小结

  • Policy 是 Rego 编写的规则集合,用于描述系统约束。
  • Rego 是声明式 DSL,专为嵌套文档策略设计。
  • Input 是动态请求数据,Data 是静态参考数据。
  • 查询 触发 决策,结果可以是布尔值或结构化数据。
  • OPA 支持 Sidecar、Library、CLI 三种工作模式,按需选择。