liatrio/autogov-policy-library

GitHub: liatrio/autogov-policy-library

一个基于 OPA Rego 的策略库,用于在 GitHub 软件供应链中对构建证明执行自动化治理和合规性门控验证。

Stars: 1 | Forks: 0

# GitHub AutoGov 策略库 [![构建](https://static.pigsec.cn/wp-content/uploads/repos/cas/c7/c7a1dd7fe72ebd160df6f6eacb0d5d22400ef83ed6272fa8f069517f498640f8.svg)](https://github.com/liatrio/autogov-policy-library/actions/workflows/build.yaml) [![OpenSSF 记分卡](https://api.scorecard.dev/projects/github.com/liatrio/autogov-policy-library/badge)](https://scorecard.dev/viewer/?uri=github.com/liatrio/autogov-policy-library) [![发布](https://img.shields.io/github/v/release/liatrio/autogov-policy-library?sort=semver)](https://github.com/liatrio/autogov-policy-library/releases) [![许可证:Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](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 匹配的情况下检查证明的内容 ![policy](https://static.pigsec.cn/wp-content/uploads/repos/cas/df/df9ec9d45c5acbf13f83ff1561e55d23b493c882e108bb715f4e2f3a52dbb882.png) #### 无违规则允许 例如: [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, 上游代理, 合规治理, 策略引擎, 结构化提示词, 网络安全挑战, 请求拦截, 靶场