2. OPA 与 Rego 基础回顾:OPA 架构、Rego 策略语言核心概念、数据文档与规则文档

在深入缓存与延迟故障排查之前,必须重新校准对 OPA 与 Rego 的基础认知。本章从架构、语言核心、数据与规则三个维度建立统一的术语体系,确保后续章节的案例分析与调试手段有共同的知识底座。

2.1 OPA 整体架构

OPA(Open Policy Agent)是一个轻量级的、与平台无关的策略引擎。其核心职责是将策略决策与策略执行解耦。OPA 本身不执行任何业务逻辑,只回答一个问题:“这个请求是否被允许?”

架构要点:OPA 通过 REST API 接收查询(Query),结合加载的策略(Policy)与外部数据(Data),输出决策结果(Decision)。所有输入数据均视为不可信的 JSON 文档,策略规则通过 Rego 语言编写。
OPA 核心架构 外部系统 (API Gateway / K8s / App) 输入数据 (input JSON) OPA 策略引擎 Rego 解释器 + 缓存层 决策日志 / 指标 策略库 (Rego 模块) 数据文档 (data JSON) 决策输出 (allow / deny / 自定义) 关键原则 策略与执行分离 无状态决策引擎

2.2 Rego 策略语言核心概念

Rego 是一种声明式查询语言,灵感来源于 Datalog。它不描述“如何做”,而是描述“数据应该是什么样子”。理解以下核心概念是编写高效策略的基础。

概念 说明 示例
规则(Rule) 策略的基本单元,定义一组条件与结果 allow { input.role == "admin" }
查询(Query) 向 OPA 发起的决策请求,包含 input 数据 POST /v1/data/example/allow
迭代(Iteration) 通过集合推导式遍历数组或对象 some user in input.users
默认规则(Default) 为规则提供兜底值,避免未定义 default allow = false
内置函数(Built-in) 预置的字符串、时间、加密等函数 http.send(...)
常见误区:Rego 中的变量一旦绑定即不可变。不要尝试在规则体内对同一变量多次赋值,这会导致编译错误或非预期结果。

2.3 数据文档(Data Document)与规则文档(Rule Document)

OPA 将一切视为文档。理解数据文档与规则文档的区别,是诊断策略行为异常的关键。

2.3.1 数据文档

数据文档是外部注入的静态 JSON 数据,通过 data 命名空间访问。典型来源包括:

  • Bundle 加载:通过 OPA 的 Bundle API 推送的 JSON 文件。
  • REST API 推送:通过 PUT /v1/data 接口写入。
  • 外部数据源:通过 http.send 在运行时拉取。
// 数据文档示例:data.roles
{
  "roles": {
    "admin": ["read", "write", "delete"],
    "viewer": ["read"]
  }
}

2.3.2 规则文档

规则文档是由 Rego 规则计算得出的虚拟文档。规则一旦被定义,其名称就成为 data 下的一个路径。规则文档是动态的,每次查询时重新计算。

// 规则文档示例:data.example.allow
package example

default allow = false

allow {
  input.user == "alice"
}

allow {
  data.roles[input.role][_] == "write"
}
性能陷阱:规则文档的递归引用可能导致无限循环。例如规则 A 引用规则 B,规则 B 又引用规则 A,且没有终止条件。OPA 在检测到循环时会返回错误,但复杂的间接循环可能难以定位。
数据文档 vs 规则文档 数据文档 (Data Document) 静态 JSON 数据 通过 Bundle / API 注入 访问方式:data.<path> 例如:data.roles.admin 缓存友好:可预加载 规则文档 (Rule Document) 动态计算的结果 由 Rego 规则推导得出 访问方式:data.<path> 例如:data.example.allow 每次查询重新计算 规则可引用数据 两者均通过 data 命名空间访问,但生命周期与计算方式完全不同

2.4 关键对比:数据文档 vs 规则文档

维度 数据文档 规则文档
来源 外部注入(Bundle / API) Rego 规则定义
生命周期 持久化存储,直到被覆盖 每次查询时重新计算
缓存行为 可被 OPA 缓存层缓存 通常不缓存(除非显式优化)
变更方式 通过 API 或 Bundle 更新 通过重新加载策略模块
典型用途 角色列表、黑名单、配置参数 访问控制、校验逻辑、聚合计算
故障排查启示:当策略行为与预期不符时,首先确认目标路径是数据文档还是规则文档。如果是数据文档,检查数据是否已正确加载;如果是规则文档,检查规则依赖链中是否存在未定义或循环引用。