4. 策略即代码基础:OPA 与 Rego 语言简介
在云原生运维剧本中,安全策略不应是静态的文档或人工检查项,而应作为可执行代码嵌入 CI/CD 与运行时环境。策略即代码(Policy as Code, PaC) 将策略决策从应用逻辑中解耦,实现自动化、版本化与可审计的策略执行。本章聚焦 OPA(Open Policy Agent) 与 Rego 语言,它们是构建回滚护栏的核心决策引擎。
4.1 策略引擎工作原理
OPA 是一个通用的、轻量级的策略引擎,其核心思想是 将决策与执行分离。OPA 本身不管理资源,而是通过 查询(Query) 接收输入(如部署清单、镜像签名、运行时事件),结合 策略(Policy) 与 数据(Data),输出 决策结果(Decision)。
4.2 Rego 语言基础
Rego 是 OPA 的原生声明式查询语言,灵感来源于 Datalog。它专注于 定义策略规则,而非描述执行步骤。Rego 策略文件通常以 .rego 结尾,核心结构包括 包(package)、规则(rule) 与 表达式(expression)。
4.2.1 核心语法要素
| 语法要素 | 说明 | 示例 |
|---|---|---|
| 包声明 | 定义策略命名空间,避免冲突 | package sigstore.trivy.policy |
| 规则 | 定义决策逻辑,返回布尔值或对象 | allow { input.signed == true } |
| 迭代 | 遍历数组或集合,使用 some 关键字 |
some i; input.images[i].tag == "latest" |
| 默认值 | 为规则设置默认结果,防止未定义 | default allow = false |
| 内置函数 | 提供字符串、时间、加密等操作 | startswith(input.image, "prod/") |
4.2.2 策略即代码示例:镜像准入控制
以下 Rego 策略演示如何结合 Sigstore 签名验证与 Trivy 漏洞扫描结果,决定是否允许部署。该策略是回滚护栏的核心逻辑。
package sigstore.trivy.rollback
import future.keywords.if
import future.keywords.in
# 默认拒绝所有部署
default allow := false
# 规则1:必须通过 Sigstore 签名验证
allow if {
input.sigstore.verified == true
}
# 规则2:Trivy 扫描结果中不得存在 CRITICAL 级别漏洞
allow if {
not any_critical_vuln
}
# 辅助规则:检查是否存在 CRITICAL 漏洞
any_critical_vuln if {
some vuln in input.trivy.vulnerabilities
vuln.severity == "CRITICAL"
}
# 规则3:若为回滚操作(rollback=true),放宽至仅检查签名
allow if {
input.rollback == true
input.sigstore.verified == true
}
# 审计日志:记录拒绝原因
deny_reason := msg {
not allow
msg := "部署被拒绝:"
msg := concat("", [msg, "签名验证失败或存在 CRITICAL 漏洞"])
}
input.rollback == true 实现了回滚护栏的差异化逻辑——正常部署需同时满足签名与漏洞条件,回滚时仅验证签名,确保快速恢复。
4.3 策略引擎与 Trivy、Sigstore 的集成模式
在《Sigstore-Trivy 协同运维剧本》中,OPA 作为 策略决策点(PDP),接收来自 CI/CD 管道或 Kubernetes 准入控制器的请求。请求负载包含 Trivy 扫描报告与 Sigstore 验证结果,OPA 根据预定义 Rego 策略输出决策。
4.4 策略即代码的版本控制与测试
策略即代码应像应用代码一样纳入 Git 仓库管理。OPA 提供 opa test 命令支持单元测试,确保策略变更不会破坏现有规则。
4.4.1 策略测试示例
package sigstore.trivy.rollback.test
import data.sigstore.trivy.rollback
# 测试用例:签名通过且无漏洞,应允许
test_allow_signed_no_vuln {
input := {
"sigstore": {"verified": true},
"trivy": {"vulnerabilities": []},
"rollback": false
}
rollback.allow with input as input
}
# 测试用例:存在 CRITICAL 漏洞,应拒绝
test_deny_critical_vuln {
input := {
"sigstore": {"verified": true},
"trivy": {"vulnerabilities": [{"severity": "CRITICAL"}]},
"rollback": false
}
not rollback.allow with input as input
}
# 测试用例:回滚模式下仅检查签名
test_allow_rollback_signed {
input := {
"sigstore": {"verified": true},
"trivy": {"vulnerabilities": [{"severity": "CRITICAL"}]},
"rollback": true
}
rollback.allow with input as input
}
with input as 语法允许模拟不同输入场景,是保障策略可靠性的关键。
4.5 策略即代码在回滚护栏中的角色
在运维剧本中,OPA 策略即代码承担以下职责:
- 准入控制: 在部署前拦截不符合安全基线的镜像。
- 回滚差异化: 根据回滚标志位动态调整策略严格度。
- 审计日志: 记录每次决策的输入、输出与拒绝原因,满足合规要求。
- 热更新: 策略变更无需重启服务,OPA 支持动态加载策略包。
通过将策略编码为 Rego 规则,运维团队能够以声明式、可测试的方式构建回滚护栏,确保每一次部署变更都经过一致的安全评估。