liatrio/autogov-policy-library
GitHub: liatrio/autogov-policy-library
一个基于 OPA Rego 的策略库,用于在 GitHub 软件供应链中对构建证明执行自动化治理和合规性门控验证。
Stars: 1 | Forks: 0
# GitHub AutoGov 策略库
[](https://github.com/liatrio/autogov-policy-library/actions/workflows/build.yaml)
[](https://scorecard.dev/viewer/?uri=github.com/liatrio/autogov-policy-library)
[](https://github.com/liatrio/autogov-policy-library/releases)
[](LICENSE)
本仓库提供了一系列 OPA Rego 策略的集合,这些策略专门为使用 GitHub Artifact Attestations 创建的证明而设计。
## 概述
GitHub AutoGov 策略库提供了一组预定义的策略,可用于在你的 GitHub 仓库中执行针对证明的治理和合规规则。这些策略使用 OPA Rego 语言编写,允许灵活且可自定义的规则定义。
这些策略无法独立运行。[autogov](https://github.com/liatrio/autogov) CLI 会在验证过程中对它们进行评估——它加载证明包,运行本库中的 OPA/Rego 规则,并输出通过/失败的 Verification Summary Attestation (VSA) 以作为发布门控。CLI 会将本库作为已发布的策略包拉取,通常通过可重用的 [autogov-workflows](https://github.com/liatrio/autogov-workflows) 进行。
### 策略类别
本库包含两大类策略:
- **安全策略** (`policies/security/`):验证单个证明类型(SLSA provenance、SBOM、漏洞扫描等)
- **治理策略** (`policies/governance/`):用于部署门控和工作流编排的更高级别策略
`governance` 包是聚合入口:只有当以下所有安全策略均允许时,它才会允许,并为每个策略输出 `violations` 映射以便于排查问题。
#### 内置策略
每个策略默认拒绝,只有在未发现违规时才允许。标记为可覆盖的阈值和标志会在运行时通过 `--policy-data-path` 以指定键下的 JSON 对象进行设置。
| 策略 | Package | 门控条件 | 关键配置 (键 → 默认值) |
| --- | --- | --- | --- |
| Provenance | `security.provenance` | 存在 SLSA provenance,`buildType` 为 GitHub Actions 工作流类型,且构建所有者(及可选的仓库)在白名单中。 | `approved_owner_ids` → liatrio org id;`approved_repo_ids` → 空(无效) |
| SBOM | `security.sbom` | 存在 CycloneDX SBOM 证明。 | 无 |
| 元数据 | `security.metadata` | 存在包含所有必需部分的 autogov/cosign 元数据证明、使用 GitHub 托管的 runner、所有者在白名单中,以及有效的 image/blob subject。 | `approved_owner_ids` → liatrio org id;`subject_prefix` → `ghcr.io/liatrio/` |
| 证书 | `security.certificate` | 每个包都带有来自 GitHub Fulcio 的非空 Fulcio 签名证书。 | 无(仅进行字符串/格式检查;OPA 中不执行完整的 X.509 验证) |
| 依赖漏洞 | `security.dependency_vulnerability.{critical,high,medium,low}` | 存在漏洞扫描证明,且各严重程度的发现数量保持在阈值范围内。 | `vuln_thresholds.{critical,high,medium,low}` → 各自为 `0`(`-1` 表示禁用某个等级) |
| 扫描器 provenance | `security.dependency_vulnerability.scanner_provenance` | 扫描器和漏洞数据库元数据完整,且数据库是近期的(30 天内)。可选(不包含在聚合的 `governance` 允许规则中)。 | 无 |
| 测试结果 | `security.test_result` | 现有的测试结果证明报告的失败测试数量不超过允许的数量。 | `max_failed_tests` → `0`;`require_test_results` → `false` |
| 代码扫描 | `security.code_scan` | SARIF 代码扫描的发现结果保持在各严重程度和各 SARIF 级别的阈值范围内。 | `code_scan_thresholds`:`bySecuritySeverity.{critical,high}` → `0`,其他 → `-1`;`byLevel.error` → `0`,其他 → `-1`;`require_code_scan` → `false`;`fail_on_incomplete_scan` → `true` |
| 源码审查 | `security.source_review` | 经过证明的 PR 批准(source-review)符合审查标准——独立的批准、没有未解决的更改请求、可选的 codeowner 审查。 | `source_review_thresholds`:`min_approvals` → `1`;`require_source_review` → `false`;`block_on_changes_requested` → `true`;`require_codeowner_review` → `false`;`fail_on_incomplete_review` → `false` |
| 依赖漏洞绕过 | `security.bypass` | 仅当经过证明的 source-review 表明有足够的授权批准时,才授权可伪造的 `ignore_dependency_vulnerabilities` 请求。默认无效。 | `bypass_thresholds`:`allow_dep_vuln_bypass` → `false`;`bypass_min_approvals` → `2`;`authorized_associations` → `["OWNER","MEMBER"]`;`authorized_approvers` → 空 |
| VSA 验证结果 | `governance.vsa_verification_result` | Verification Summary Attestation 报告 `verificationResult: PASSED`;`FAILED`/`UNKNOWN`/缺失/无效则拒绝。 | 无 |
组织特定的默认值(`approved_owner_ids`、`subject_prefix`、`signer_org`)全部定义在 `policies/shared/access/access.rego` 中;请根据你自己的组织进行调整(参见下文的组织特定约束说明)。
#### 基于 VSA 的部署门控
`governance/vsa_verification_result` 策略启用了**基于 Verification Summary Attestation (VSA) 的部署门控**。此策略会:
- 评估由 autogov 验证工具在策略评估后生成的 VSA 包
- 仅在 `verificationResult` 为 `PASSED` 时允许部署
- 针对 `FAILED`、`UNKNOWN` 或缺失的验证结果阻止部署
- 提供清晰的拒绝消息以供故障排除
**使用案例**:仅在经过加密签名的验证确认所有安全和合规策略均已通过后,才部署应用程序。
**集成示例**:
```
# 在部署 workflow 中
- name: Evaluate VSA Against Policy
run: |
opa eval --input vsa-bundle.json \
"data.governance.vsa_verification_result.allow"
```
这实现了一个 **4 层 AutoGov 架构**:
1. **构建** → 生成证明
2. **验证** → 验证证明 + 创建 VSA
3. **门控** → 根据部署策略评估 VSA
4. **部署** → 发布到生产环境(如果获得授权)
## 在 GitHub Workflows 中使用策略包
策略包 (`bundle.tar.gz`) 作为 release 资产发布。你可以使用具有对 policy-library 仓库读取权限的 token,通过 GitHub Actions 工作流中的 `gh release download` 进行下载。
该任务需要 `contents: read` 权限以读取 release。如果你使用 [octo-sts](https://github.com/octo-sts/action) 而不是默认的 `GITHUB_TOKEN` 进行身份验证(例如读取来自不同仓库的包),请添加 `id-token: write`,以便该操作可以生成 token。
```
jobs:
download-bundle:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # only required when minting a token via octo-sts (see note below)
steps:
# The octo-sts step below is Liatrio-org-specific — the `scope` and
# `identity` values reference Liatrio's trust policies. Adapt these for
# your own org, or drop this step and use the default `GITHUB_TOKEN` /
# your own PAT instead.
- name: Generate Read Bundle Token
id: generate_token
uses: octo-sts/action@6177b4481c00308b3839969c3eca88c96a91775f # v1.0.0
with:
scope: liatrio # adapt for your org
identity: autogov-infra # liatrio/.github/chainguard/autogov-infra.sts.yaml — adapt for your org
- name: Download Policy Bundle
env:
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
run: |
gh release download \
--repo liatrio/autogov-policy-library \
--pattern "bundle.tar.gz"
```
## 快速开始
要开始使用本库中的策略,请按照以下步骤操作:
1. 将此仓库克隆到你的本地计算机。
2. 安装前置条件。
3. 查看 `policies` 目录中可用的策略文件。
4. 自定义策略以满足你特定的治理要求。
### 前置条件
```
brew install make docker
```
### Makefile 命令指南
- **`make all`**:运行格式化、lint、检查和测试。
- **`make eval-good`**:针对真实数据运行 OPA 评估。
- **`make eval-bad`**:针对伪造数据运行 OPA 评估。
- **`make fmt`**:格式化 OPA 文件以修复不合规问题。
- **`make lint`**:使用 `regal` 对策略进行 lint。
- **`make check`**:验证 OPA 策略。
- **`make test`**:运行 OPA 单元测试。
### 证明指南
#### 下载证明
要从 GitHub 下载证明,你必须[登录 ghcr.io](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-with-a-personal-access-token-classic)。
```
export CR_PAT=YOUR_TOKEN
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
```
现在你已经通过了身份验证,可以下载证明了。
例如:
```
gh attestation download oci://ghcr.io/liatrio/autogov-workflows@sha256:efa6fcc6c8059a5fcc2c2dcdcdb83a57a7bfe480bceefbeb99d86f480a8e8aae -o liatrio
```
你现在拥有了一个包含 JSON 证明对象的 `.jsonl` 文件。
#### 解析证明
下载的证明是 base64 编码的,但我们可以通过将其传递给 jq 和 base64 来使其变为人类可读的格式,如下所示:
```
cat sha256:efa6fcc6c8059a5fcc2c2dcdcdb83a57a7bfe480bceefbeb99d86f480a8e8aae.jsonl | jq -r '.dsseEnvelope.payload' | base64 -d | jq -r
```
#### 组合在一起
你也可以一次性运行所有操作:
```
gh attestation verify oci://ghcr.io/liatrio/autogov-workflows@sha256:efa6fcc6c8059a5fcc2c2dcdcdb83a57a7bfe480bceefbeb99d86f480a8e8aae \
-o liatrio \
--format json \
--jq '.[0].attestation.bundle.dsseEnvelope.payload' \
| base64 -d | jq
```
### 创建策略
使用此[示例证明](./test/attestations.json)来帮助选择要验证的对象。有关编写 Rego 策略的更多详细信息,请参阅以下资源:
- [Rego Playground - 用于快速测试 Rego](https://play.openpolicyagent.org)
- [OPA 策略编写课程](https://academy.styra.com/courses/opa-rego)
#### 标准实践
- 一个新策略应该与作业产物和证明具有一对一的关系
- 新策略应该是 `policies/security` 文件夹中的一个独立文件。
- 策略文件应该:
- 定义基于违规的规则,并且只有在评估所有规则后没有违规时,才将 `allow` 设置为 true
- 检查 payload(证明包/证明对象列表)中是否存在 predicateType
- 如果 predicateType 不是唯一的,除了 predicateType 外还需检查 subject
- 在 predicateType 匹配的情况下检查证明的内容

#### 无违规则允许
例如:
[provenance.rego 中的 allow](policies/security/provenance/provenance.rego#L24)
```
default allow := false
allow if {
count(violations) == 0
}
```
#### 检查 predicateType 是否存在
使用 Count 条件来检查 payload 中是否存在 predicate
例如:
[provenance.rego 中的 is_slsa_provenance_present](policies/security/provenance/provenance.rego#L94)
```
# 检查 SLSA Provenance 是否存在
is_slsa_provenance_present(payload) if {
count([obj | some obj in payload; utils.is_slsa_provenance(obj)]) > 0
}
```
#### 检查 predicateType 匹配处的值
使用 `some` 遍历证明并匹配 predicate 以评估 predicate 内容
例如:
[provenance.rego 中的 violation 规则](policies/security/provenance/provenance.rego#L41)
```
# 当 predicateType 为 slsa provenance 时,predicate 中应存在 buildType
violations contains msg if {
some payload in utils.decoded_payload_list
utils.is_slsa_provenance(payload)
not payload.predicate.buildDefinition.buildType
msg := "build type is missing"
}
```
#### 完整策略示例
策略文件通常如下所示:
```
package security.my_new_policy
import data.shared.access
import data.shared.utils
import rego.v1
default allow := false
allow if {
count(violations) == 0
}
violations contains msg if {
some payload in utils.decoded_payload_list
not payload.predicateType
msg := "predicate type is missing"
}
is_slsa_provenance_present(payload) if {
count([obj | some obj in payload; utils.is_slsa_provenance(obj)]) > 0
}
```
## 自我检查以避免错误
### 单元测试
当你在某个文件/包中定义了一个函数并希望在另一个文件/包中(例如用于单元测试)引用它时,你**必须**在 opa test 命令中包含托管该函数定义的文件:
`opa test -v policies/security/sbom/sbom.rego policies/security/sbom/sbom_test.rego`
`sbom.rego` 定义了函数 `is_cyclonedx_bom_present`,而 `sbom_test.rego` 调用了该函数。
### 了解输入数据
从 GitHub 下载的证明包是 `.jsonl` 格式
Rego 无法原生遍历 `.jsonl`
我们必须通过 `jq -s .` 处理 .jsonl,以便将 .json(对象列表)传递给 Rego 策略的输入
在我们将输入直接传递给规则逻辑之前,我们会解析并解码输入(对象列表)中每个对象的 `dsseEnvelope.payload` 对象:
```
parse_payload(payload) = parsed_payload if {
decoded_payload := base64.decode(payload)
parsed_payload := json.unmarshal(decoded_payload)
}
decoded_payload_list := [decoded |
some i;
obj := input[i]; # Iterate over the input list
payload := obj.dsseEnvelope.payload; # Extract the payload
base64.decode(payload, decoded_payload_raw); # Decode the base64 payload
json.unmarshal(decoded_payload_raw, decoded) # Unmarshal the decoded payload into a JSON object
]
```
#### 优化后的样本数据
我们现在得到了一个对象列表作为解析后的 payload。
```
[
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "ghcr.io/liatrio/autogov-workflows",
"digest": {
"sha256": "d379d8ef02ef446dc22e57e845ac7f3e5053b9398475541a8530d707511e6264"
}
}
],
"predicateType": "https://cyclonedx.org/bom",
"predicate": {...}
},
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "ghcr.io/liatrio/autogov-workflows",
"digest": {
"sha256": "d379d8ef02ef446dc22e57e845ac7f3e5053b9398475541a8530d707511e6264"
}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {...}
}
]
```
### 了解输出
#### allow 策略的预期输出
`allow` 规则的预期*未通过*结果
如果输出为 `{}`,则表示策略失败(条件未满足)。这是一种故意的未定义结果,以便我们可以在流水线/工作流中使用 `--fail` 标志,从而在策略失败时阻止/限制 PR 合并。
`allow` 规则的预期*通过*结果
```
{
"result": [
{
"expressions": [
{
"value": true,
"text": "data.governance.allow",
"location": {
"row": 1,
"col": 1
}
}
]
}
]
}
```
#### violations 策略的预期输出
`violation` 规则的预期*未通过*结果
```
{
"result": [
{
"expressions": [
{
"value": {
"provenance": [],
"sbom": [
"cyclonedx sbom is missing"
]
},
"text": "data.governance.violations",
"location": {
"row": 1,
"col": 1
}
}
]
}
]
}
```
`violation` 规则的预期*通过*结果
```
{
"result": [
{
"expressions": [
{
"value": {
"provenance": [],
"sbom": []
},
"text": "data.governance.violations",
"location": {
"row": 1,
"col": 1
}
}
]
}
]
}
```
标签:DevSecOps, OPA, 上游代理, 合规治理, 策略引擎, 结构化提示词, 网络安全挑战, 请求拦截, 靶场