在现代软件供应链安全体系中,验证工件来源的可信度已成为 DevSecOps 的核心诉求。Frizbee 作为 Stacklok 推出的命令行工具,专注于为 GitHub Actions 和容器镜像提供基于标签的校验和(checksum)解析能力。当这一能力与 in-toto 证明框架结合时,能够为 CI/CD Pipeline 构建一套完整的可验证工件 attestation 流程,同时满足 SLSA(Supply-chain Levels for Software Artifacts)供应链安全级别要求。本文将深入解析这一集成路径,提供可直接落地的工程化参数与配置清单。
Frizbee 的核心定位与能力边界
Frizbee 的设计目标极为明确:在 CI/CD 构建阶段,自动将工作流文件中引用的 GitHub Action 和容器镜像标签替换为对应的摘要值(digest)。这一机制直接解决了供应链攻击中常见的标签劫持(tag hijacking)问题 —— 攻击者通过篡改标签指向的容器镜像或 Action 内容,即可将恶意代码注入下游构建流程。
从功能层面来看,Frizbee 提供两类核心操作:针对 GitHub Actions 的 frizbee actions 命令,以及针对容器镜像的 frizbee image 命令。两者的使用模式高度一致,均支持单文件解析、目录批量处理和干运行(dry-run)模式。以 GitHub Actions 为例,执行 frizbee actions path/to/workflows/ 会扫描指定目录下的所有工作流 YAML 文件,将所有 uses: 字段中的标签引用替换为对应的 git object 摘要。默认情况下,工具仅处理非 main 和 master 分支的引用,以避免对开发分支造成不必要的修改。
值得注意的是,Frizbee 本身并不直接生成 in-toto attestation,但通过确保工件引用的不可变性,为后续的 attestation 验证提供了可信的输入基础。当所有外部依赖均通过摘要而非标签被锁定后, attestation 所记录构建步骤与实际执行环境之间的一致性得到了根本保障。
in-toto Attestation 框架与 SLSA 的协同逻辑
in-toto 是 Linux 基金会旗下的软件供应链安全项目,它定义了一种灵活且可加密验证的元数据格式,用于记录软件构建过程中的每一步操作。in-toto layout(布局)描述了预期的构建步骤序列,而 attestation(证明)则记录了实际执行时每一步的输入、输出和执行者身份。两者的密码学绑定使得构建产物的来源可以独立验证,即使构建环境本身不可信。
SLSA 则是 Google 提出的供应链安全级别框架,它定义了从 L0 到 L4 四个递进的安全等级,其中 L3 以上要求构建过程具备完整的可验证性和防篡改能力。SLSA 的 Provenance(来源证明)规范正是基于 in-toto 的 predicate 格式来描述构建元数据 —— 包括构建所用源码_commit、构建触发者、构建环境、输入工件和输出产物等关键信息。
Frizbee 在这一体系中的角色可以概括为「构建前依赖锁定」:它确保 CI/CD Pipeline 中所有外部引用的摘要值在构建开始前已被固定,从而使得后续生成的 in-toto attestation 所记录的依赖信息与实际运行时使用的依赖完全一致。如果跳过 Frizbee 而直接使用标签引用,attestation 中记录的镜像标签可能在构建与验证之间发生解析变化,导致验证失败或安全缺口。
CI/CD Pipeline 中的集成架构设计
将 Frizbee 集成到 CI/CD Pipeline 并生成可验证的 in-toto attestation,需要在构建流程中嵌入四个关键阶段:依赖解析与锁定、Provenance 生成、Attestation 签发与存储、运行时验证。以下是每个阶段的核心参数与配置建议。
第一阶段为依赖解析与锁定。在 CI Pipeline 的初始化步骤中,添加 Frizbee 对工作流文件的扫描与替换操作。以 GitHub Actions 为例,配置如下:
- name: Lock dependency references with Frizbee
uses: stacklok/frizbee-action@v0.1.2
with:
mode: actions
directory: .github/workflows/
dry-run: false
fail-on-replacement: true
其中 fail-on-replacement: true 参数确保当工具检测到可更新的引用时,CI 流程立即失败并退出,这对于强制实施依赖锁定策略至关重要。容器镜像的锁定操作类似,使用 mode: images 即可。
第二阶段为 SLSA Provenance 生成。在构建完成后、产物发布前,需要使用符合 SLSA 规范的 Provenance 生成工具。GitHub 官方提供的 slsa-github-generator 是目前最广泛使用的方案,它能够为构建产物生成符合 SLSA L2+ 规范的 Provenance 记录,并将结果以 in-toto predicate 格式输出。关键配置参数包括:
- name: Generate SLSA Provenance
uses: slsa-framework/slsa-github-generator/generator@v2.0.0
with:
category: build
builder-id: "https://github.com/${{ github.repository }}/.github/workflows/build.yml@refs/heads/main"
provenance-name: ${{ github.run_id }}.intoto.jsonl
此处 builder-id 必须唯一标识当前构建流程,它将作为 in-toto attestation 中 step 的关键标识符。
第三阶段为 Attestation 签发与存储。生成的 Provenance 需要经过加密签名后才能作为有效的 in-toto attestation 使用。cosign 工具是 OCI 镜像签名的行业标准,它原生支持 in-toto attestation 的签发与存储。通过以下命令可以将 Provenance 转换为 attestation 并附加到产物上:
cosign attest --key cosign.key --type slsaprovenance1 $IMAGE_URI
签名密钥的管理是此环节的安全核心。建议使用硬件安全模块(HSM)或云 KMS 服务存储签名密钥,并确保 CI/CD Runner 具有最小权限的密钥访问能力。
第四阶段为运行时验证。在部署阶段,验证工具(如 cosign、slsa-verifier)会检查产物上附加的 attestation 是否满足预期的 in-toto layout 和 SLSA 级别要求。验证失败时,部署流程应立即中止并输出详细的错误信息:
slsa-verifier verify-image \
--image-uri $IMAGE_URI \
--provenance-path provenance.intoto.jsonl \
--source-uri github.com/${{ github.repository }} \
--source-tag v1.0.0
SLSA 合规参数配置清单
针对不同安全等级的目标,以下参数配置可作为工程实践的参考基准。对于 SLSA L2 级别(构建级可信),核心要求包括:Provenance 必须存在且包含构建步骤、输入和输出信息;构建流程必须通过 CI/CD 系统自动触发;Provenance 必须经过签名验证。Frizbee 在此级别中的作用是确保输入依赖的可验证性。
对于 SLSA L3 级别(构建级防篡改),除了 L2 要求外,还需满足:构建必须在隔离环境中执行;构建过程必须可重现;Attestation 必须通过安全通道传输。Frizbee 配合 in-toto layout 的加密签名机制,能够有效满足这些防篡改要求。
具体的配置文件中,可通过 .frizbee.yml 对特定 Action 和镜像进行排除或白名单管理:
ghactions:
exclude:
- slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml
exclude_branches:
- main
- master
images:
exclude_images:
- scratch
exclude_tags:
- latest
- devel
上述配置排除了 SLSA 官方生成器本身(避免循环依赖),同时对 scratch 镜像和 latest、devel 标签进行了默认排除,这些都是供应链攻击的高风险目标。
监控与回滚策略
在生产环境中,attestation 验证不应仅停留在部署阶段,还应纳入持续的安全监控体系。关键监控指标包括:验证失败率(反映依赖或签名问题)、签名密钥轮换周期(建议 90 天)、SLSA 级别达标率(反映供应链成熟度)。
当检测到 attestation 验证失败时,应立即触发告警并禁止部署。同时保留最近 30 个构建版本的可验证 attestation 记录,以便在供应链安全事件发生时进行溯源分析。若发现已部署产物存在签名密钥泄露或依赖篡改问题,应立即执行回滚并撤销对应版本的签名证书。
小结
Frizbee 与 in-toto 证明框架的集成,本质上是在 CI/CD Pipeline 中建立了一条可信的依赖锁定链路。它通过在构建前将所有外部引用的标签替换为不可变的摘要值,确保后续生成的 in-toto attestation 所记录的环境状态与实际运行状态高度一致。结合 SLSA Provenance 规范和 cosign 签名机制,这一方案能够为软件供应链提供从依赖解析到运行时验证的完整可追溯性。对于追求 SLSA L3 及以上合规目标的企业团队,建议将 Frizbee 集成作为 CI/CD 安全加固的标准环节,并通过自动化验证确保每次部署均通过 attestation 检查。
资料来源:Frizbee 项目 GitHub 仓库(https://github.com/stacklok/frizbee)