概述
容器镜像通常有签名与来源证明,因为镜像仓库原生支持;而发布用的 tar 包往往从对象存储下载,仅凭文件名就被信任。这种信任并不可靠:任何能写入桶的人都可以替换压缩包,部署脚本仍会照常解压。attestation 把摘要与工作流身份、产生它的 commit 绑定在一起,部署任务可以在解压前同时校验两者。
步骤
- 在构建任务中生成压缩包并为其创建证明:
permissions:
contents: read
id-token: write
attestations: write
steps:
- uses: actions/checkout@v4
- run: tar -czf dist/payments-1.5.0.tar.gz -C build .
- uses: actions/attest-build-provenance@v2
with:
subject-path: dist/payments-1.5.0.tar.gz
- 下载后按仓库与来源分支校验:
gh attestation verify dist/payments-1.5.0.tar.gz \
--repo acme/payments --source-ref refs/heads/main
- 记录摘要,并让部署引用摘要而不是文件名:
sha256sum dist/payments-1.5.0.tar.gz
- 在预发流水线做一次篡改测试,确认门禁会拒绝:
printf 'x' >> dist/payments-1.5.0.tar.gz
gh attestation verify dist/payments-1.5.0.tar.gz --repo acme/payments
验证
正常压缩包的校验应输出签名工作流、commit 与来源分支,退出码为 0;篡改后的文件必须返回非零并提示未找到匹配的证明。部署日志中应同时出现校验结果与摘要,二者与构建日志一致。若提示找不到证明,先确认校验时使用的仓库和文件字节与构建时完全一致,而不是仅文件名相同。
注意事项
- 证明只能说明来源与完整性,不能证明产物没有漏洞,仍需配合镜像或依赖扫描。
- 私有仓库读取证明需要已认证的
gh会话或 token。 - 校验必须 fail closed,任何缺失或仓库不匹配都应阻断部署。
- 不要只校验文件名或 tag,摘要才是唯一不可复用的标识。
- 构建任务必须拥有
id-token: write,否则无法签发证明。