Packer SLSA 溯源 CI 参考工作流:provenance 后处理器与 GitHub Actions 无密钥签名实战
Packer SLSA 溯源 CI 参考工作流provenance 后处理器与 GitHub Actions 无密钥签名实战【免费下载链接】packerPacker is a tool for creating identical machine images for multiple platforms from a single source configuration.项目地址: https://gitcode.com/gh_mirrors/pa/packer本文围绕 Packer 仓库 examples/ci/README.md 中提供的两份可直接复制使用的 CI 参考工作流展开系统讲解如何用 Packer 的provenance后处理器在 GitHub Actions 中生成 SLSA Provenance v1 溯源声明并分别以「L2 无密钥keyless签名」和「L3 兼容的委托签名」两种模式落地。读完本文你将掌握SLSA 构建等级中 Packer 的职责边界、provenance后处理器的完整配置参数、packer verify-attestation的策略校验用法以及两份可直接迁移到自建项目.github/workflows/的完整 CI 工作流。文档定位参考工作流而非仓库自用 CIexamples/ci/目录下的工作流是复制粘贴型参考模板用于配合 Packer 的provenance后处理器产出 SLSA 溯源声明。需要特别强调的是这些工作流并未接入当前仓库自身的 CI而是面向所有使用 Packer 构建镜像的第三方项目。使用时需要将它们复制到你自己项目的.github/workflows/目录并适配模板路径、构建产物路径等具体内容。目录包含三份文件examples/ci/README.md本文讲解的主文档说明 SLSA 等级定位与两份工作流的分工examples/ci/github-actions-l2-keyless.ymlL2 模式Packer 使用工作流的 OIDC 身份无密钥签名溯源声明、上传 Rekor 透明日志并用packer verify-attestation验证签名声明examples/ci/github-actions-l3-delegated.ymlL3 兼容模式构建 job 只负责构建并发布摘要digest溯源生成与签名委托给隔离的可复用工作流使构建步骤无法触达签名材料。SLSA 构建等级与 Packer 的职责边界主文档给出了一张关键表格明确了 SLSA Build 等级大多属于构建平台的属性而非构建工具的属性。Packer 是工具因此它的作用范围是SLSA 构建等级要求Packer 的角色Packer 提供的能力L1溯源存在且被分发完全由 Packer 承担溯源生成L2溯源由托管平台签名Packer 通过 CI OIDC 身份签名CI 中的无密钥签名L3加固平台构建步骤无法触达签名密钥平台属性Packer 与之兼容委托签名模式L4—SLSA v1.0 中未定义—结论很清晰Packer 生成 SLSA Provenance v1自身即可达到构建 L1当运行在托管 CI 且启用无密钥签名时达到 L2。L3 是构建平台的属性要求签名密钥对构建步骤不可达。Packer 单独无法赋予 L3但文档提供的委托签名模式与 L3 平台兼容。这一点在源码中也能印证provenance 后处理器输出的是 SLSA v1 谓词predicate其谓词类型常量SLSAProvenanceV1PredicateType https://slsa.dev/provenance/v1定义在 internal/provenance/predicate.go默认构建类型为https://packer.io/buildtypes/hcl2/v1默认本地 builder ID 为https://packer.io/local-build。工作流一L2 无密钥签名github-actions-l2-keyless.yml这份工作流对应 SLSA 构建 L2Packer 以 GitHub Actions 工作流自身的 OIDC 身份Fulcio对溯源声明进行无密钥签名并把签名记录进 Rekor 透明日志从而产出由托管平台生成的、已签名且可透明审计的溯源。值得注意文档明确警告该模式本身不赋予 L3——构建 job 仍可触达临时的签名材料L3 兼容模式请看第二份工作流。工作流骨架与权限声明name: build-and-sign-provenance on: push: tags: - v* permissions: contents: read # Required so Packers keyless signing can request an OIDC token from GitHub # and exchange it with Fulcio for a short-lived signing certificate. id-token: writeid-token: write是启用无密钥签名的关键它允许 Packer 向 GitHub 请求 OIDC token再与 Fulcio 交换短时签名证书。如果省略该权限Packer 将无法获取环境 OIDC 身份。关键环境变量验证时用于固定身份env: # Must match the workflows OIDC identity so verification can pin it. KEYLESS_IDENTITY: https://github.com/${{ github.repository }}/.github/workflows/build-and-sign-provenance.yml${{ github.ref }} KEYLESS_OIDC_ISSUER: https://token.actions.githubusercontent.comKEYLESS_IDENTITY必须与工作流自身的 OIDC 身份精确匹配验证时才能将签名证书锁定到该身份KEYLESS_OIDC_ISSUER是 GitHub Actions 的 OIDC 颁发者。构建与签名步骤steps: - name: Checkout uses: actions/checkoutv4 - name: Install Packer uses: hashicorp/setup-packermain with: version: latest - name: Initialize plugins run: packer init . - name: Build and sign run: | packer build \ -var keyless_identity${KEYLESS_IDENTITY} \ -var keyless_oidc_issuer${KEYLESS_OIDC_ISSUER} \ .工作流注释里特别解释了一个重要的 HCL 限制Packer 的env()函数只能出现在变量的default中绝不能内联写在 block 里因此这里用-var把身份信息传入而不是在模板中直接调用env()。对应的模板需要声明两个输入变量与一个无密钥 provenance 后处理器variable keyless_identity { type string } variable keyless_oidc_issuer { type string } post-processor provenance { signing_mode keyless upload_tlog true keyless_identity var.keyless_identity keyless_oidc_issuer var.keyless_oidc_issuer }Packer 会自动从 GitHub Actions 的ACTIONS_ID_TOKEN_REQUEST_URL/ACTIONS_ID_TOKEN_REQUEST_TOKEN环境变量中拾取环境 OIDC token前提是授予了上面的id-token: write权限。这一点在 internal/attestation/sign_keyless.go 的resolveAmbientIDToken中有完整实现它依次尝试SIGSTORE_ID_TOKEN、CI_JOB_JWT_V2、CI_JOB_JWT最后通过resolveGitHubActionsIDToken从ACTIONS_ID_TOKEN_REQUEST_URL请求 tokenaudience 缺省为sigstore。验证签名声明- name: Verify attestation run: | for att in *.provenance.json; do packer verify-attestation \ -signing-modekeyless \ -bundle${att%.json}.sigstore.json \ -require-rekor \ -require-timestamp \ -keyless-identity${KEYLESS_IDENTITY} \ -keyless-oidc-issuer${KEYLESS_OIDC_ISSUER} \ -predicate-typehttps://slsa.dev/provenance/v1 \ ${att} done这里循环遍历所有*.provenance.json声明文件配合*.sigstore.json侧车文件Sigstore bundle做 Rekor 支撑的透明性校验。各参数含义与 command/verify_attestation.go 中packer verify-attestation的帮助文本一致-signing-modekeyless指定无密钥验证模式支持key、kms、keyless可自动探测-bundle*.sigstore.json提供 Sigstore bundle用于 Rekor 或时间戳验证-require-rekor要求基于 bundle 完成 Rekor 透明日志验证-require-timestamp要求可信观察者时间戳Rekor 集成时间或 RFC3161 时间戳证据-keyless-identity/-keyless-oidc-issuer期望的无密钥签名身份与 OIDC 颁发者-predicate-type期望的谓词类型这里固定为 SLSA Provenance v1。上传溯源产物- name: Upload provenance artifacts uses: actions/upload-artifactv4 with: name: provenance path: | *.provenance.json *.sigstore.json*.provenance.json是溯源声明本体*.sigstore.json是签名 bundle 侧车。当upload_tlog true时bundle 中会携带 Rekor 透明性证据供上述-require-rekor校验使用见 post-processor/provenance/post-processor.go 中侧车路径的生成逻辑以.json结尾的声明文件其 bundle 路径为去掉.json后缀后追加.sigstore.json。工作流二L3 兼容的委托签名github-actions-l3-delegated.yml这份工作流对应 SLSA 构建 L3 兼容模式构建 job 只负责构建产物并发布其摘要溯源生成与签名被委托给一个隔离的、可复用的工作流SLSA GitHub generator在构建步骤无法影响或触达的独立 job 中运行。这种隔离正是 L3 的要求——签名材料对构建不可达。文档再次强调Packer 本身不赋予 L3它只负责产出产物L3 属性由平台隔离签名方提供。name: build-and-delegate-provenance on: push: tags: - v* permissions: contents: read jobs: build: runs-on: ubuntu-latest outputs: digest: ${{ steps.hash.outputs.digest }} steps: - name: Checkout uses: actions/checkoutv4 - name: Install Packer uses: hashicorp/setup-packermain with: version: latest - name: Initialize plugins run: packer init . # Build only. Do NOT sign here: signing in the build job would defeat the # isolation that the delegated signer provides. - name: Build artifact run: packer build . # Emit a base64-encoded subject digest for the delegated generator. - name: Compute artifact digest id: hash run: | # Adjust the artifact path to match your build output. echo digest$(sha256sum output/image.qcow2 | base64 -w0) ${GITHUB_OUTPUT}构建 job 中明确不做签名——在构建 job 内签名会破坏委托签名方提供的隔离性。它只计算产物摘要并以 base64 编码输出注意output/image.qcow2需要替换为你实际的构建产物路径。委托 job 则使用 SLSA GitHub generatorprovenance: needs: [build] permissions: actions: read id-token: write contents: write uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.ymlv2.0.0 with: base64-subjects: ${{ needs.build.outputs.digest }}该 job 在构建步骤无法触达的独立 job 中生成并签名 SLSA 溯源——这是 L3 属性的来源。文档注释提醒实际使用中应将可复用工作流固定到已发布 tag示例中为v2.0.0。provenance 后处理器源码级解读两份工作流都依赖provenance后处理器其实现位于 post-processor/provenance/post-processor.go配套文档为 post-processor/provenance/README.md。它支持三类能力富集了源码控制与 CI 元数据的 SLSA 溯源声明SBOM 侧车文件与 SBOM 溯源声明可配置签名方与验证方的可选 DSSE 签名默认signing_mode none输出未签名 JSON 声明。核心配置参数源码中Config结构体post-processor.go完整定义了以下参数与工作流直接相关的有参数含义默认值signing_mode签名模式none默认未签名 JSON、key本地 PEM 密钥、kmsKMS/Vault URI、keylessSigstore Fulciononekeyless_identity期望的签名身份如工作流 refkeyless 模式必填—keyless_oidc_issuer期望的 OIDC 颁发者如https://token.actions.githubusercontent.comkeyless 模式必填—upload_tlog是否将 keyless 签名上传 Rekor 透明日志并产出携带透明性证据的 Sigstore bundlefalsefulcio_urlkeyless 签名使用的 Fulcio CA 地址https://fulcio.sigstore.devrekor_urlupload_tlog启用时的 Rekor 透明日志地址https://rekor.sigstore.devtrusted_root_path用于固定 keyless 验证的 Sigstore trusted-root JSON不设置则拉取公共 Sigstore 根—build_type溯源谓词中记录的 SLSAbuildTypeURIhttps://packer.io/buildtypes/hcl2/v1template产出产物的 Packer 模板路径记为外部参数—only_builds产物来源的构建列表记为外部参数—user_variables额外的用户变量记为外部参数敏感变量会被脱敏—source_uri覆盖自动探测的源码仓库 URI自动探测sbom/sbom_format/sbom_scan_path/sbom_scope/sbom_exclude是否同时生成 SBOM 及相应配置关 /cyclonedx/ 自动 /squashed/ 无这些默认值在Configure方法中于解码之后统一应用post-processor.go。keyless 模式还要求keyless_identity与keyless_oidc_issuer非空、不允许设置verifier覆盖验证严格绑定身份与颁发者策略详见signingBackendConfigpost-processor.go。输出文件与签名流程writeAttestationpost-processor.go展示了完整流程未签名模式none直接输出格式化 JSON 声明文件*.provenance.json签名模式先构造签名后端对 in-toto 负载进行规范化MarshalPayload后签名keyless 模式走buildSigstoreBundleForSigner产出 DSSE envelope 与 Sigstore bundle*.sigstore.jsonupload_tlogtrue时 bundle 携带 Rekor 证据签名后立即用验证方做VerifyEnvelope自检再原子写入文件atomicWriteFile先写临时文件再 rename防止并行构建时输出交错或崩溃留下损坏声明。DSSE envelope 的结构payloadType/payload/signatures其中 keyless 签名在signatures[0].cert携带 Fulcio 证书定义于 internal/attestation/dsse.go。谓词内容SLSA 谓词由 internal/provenance/predicate.go 的BuildSLSAPredicate构造buildDefinition记录buildType、外部参数模板、onlyBuilds、用户变量、内部参数Packer 版本、构建名、构建器类型与已解析依赖源码仓库 URI 摘要runDetails记录 builder ID默认https://packer.io/local-build与 Packer 版本、调用 ID 及起止时间。源码仓库由 Git 信息或 CI 环境变量自动探测可用source_uri覆盖post-processor.go。从零接入的完整步骤将上述参考工作流落到自己的项目可以按以下步骤操作复制工作流把 github-actions-l2-keyless.yml或 github-actions-l3-delegated.yml复制到你项目的.github/workflows/目录准备模板在 Packer 模板中声明keyless_identity、keyless_oidc_issuer两个变量并添加post-processor provenance块L2 模式L3 模式无需签名后处理器但需要调整sha256sum中的产物路径打 tag 触发两个工作流都监听v*格式的 tag 推送检查权限L2 模式必须保留id-token: writeL3 模式的委托 job 需要actions: read、id-token: write、contents: write消费产物从 workflow 的provenanceartifact 中取回*.provenance.json与*.sigstore.json离线可用packer verify-attestation -signing-modekeyless -bundle... -require-rekor -require-timestamp -keyless-identity... -keyless-oidc-issuer... -predicate-typehttps://slsa.dev/provenance/v1 声明文件重复验证。常见问题与注意事项env()的位置限制env()只能写在变量default中不能内联在 block 里因此工作流统一用-var传值L2 不等于 L3L2 模式下构建 job 仍能触达临时签名材料只有将签名委托给隔离平台如 L3 工作流才满足 L3 要求固定可复用工作流版本L3 委托的slsa-github-generator应固定到已发布 tag而非长期跟随分支身份字符串必须精确匹配keyless_identity与工作流 OIDC 身份不一致会导致验证失败验证命令中的期望值与签名时的实际值必须一致产物路径按需调整两份工作流中的产物路径如output/image.qcow2都需要替换为真实构建输出敏感变量脱敏provenance 谓词中记录的用户变量会依据packer_sensitive_variables自动脱敏为[sensitive value redacted]见 post-processor.go避免密钥泄露进溯源声明。这两份参考工作流为 Packer 用户提供了一条从「生成溯源」到「无密钥签名、透明审计、平台级隔离」的渐进路径先用 L2 模式快速获得已签名的可验证溯源再在需要更高供应链保证时切换到 L3 委托模式把签名材料彻底隔离在加固平台之内。【免费下载链接】packerPacker is a tool for creating identical machine images for multiple platforms from a single source configuration.项目地址: https://gitcode.com/gh_mirrors/pa/packer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

微信零钱免费转到卡里性能优化入门到精通

微信零钱免费转到卡里性能优化入门到精通

微信零钱免费转到卡里性能优化入门到精通 官方文档关于接口限流和并发处理的描述往往篇幅冗长,导致开发者在排查“微信零钱免费转到卡里”延迟高时抓不住重点。想要从入门到精通地解决这一性能瓶颈,不能只盯着业务逻辑,更要深挖底层 I/O…

2026/9/21 18:35:31 阅读更多 →
3步搞定软交所环境,实战项目避坑指南

3步搞定软交所环境,实战项目避坑指南

3步搞定软交所环境,实战项目避坑指南 配置环境就卡半天?别急,这不是你的错。 很多兄弟在搭建软交所相关工具链时,总被依赖冲突和版本不匹配搞得头秃。 今天咱们不讲虚的,直接上硬菜,用一个完整的实战项目带你从零跑通全流程。…

2026/9/21 18:35:31 阅读更多 →
一文搞懂如何解散微信群:3种技术路径深度对比与避坑指南

一文搞懂如何解散微信群:3种技术路径深度对比与避坑指南

一文搞懂如何解散微信群:3种技术路径深度对比与避坑指南 复制来的代码跑不通,报错信息满屏飞,是不是让你抓狂?别急,很多老手当年也在这栽过跟头。今天咱们不聊虚的,直接 一文搞懂 “如何解散微信群”背后的技术实现逻辑。…

2026/9/21 18:35:31 阅读更多 →

最新新闻

伽卡他卡学生端卸载保姆级教程:3步彻底清除避坑指南

伽卡他卡学生端卸载保姆级教程:3步彻底清除避坑指南

伽卡他卡学生端卸载保姆级教程:3步彻底清除避坑指南 配置环境就卡半天,装完软件想卸个干净却越弄越乱,这绝对是无数开发者和技术爱好者的噩梦。你是不是也遇到过这种情况:明明在控制面板里点了卸载,重启后桌面图标没了,但注册表里还留着几百个垃圾键值…

2026/9/21 20:08:18 阅读更多 →
搞懂双摄融合算法:面试必问的源码级拆解,告别配置卡壳

搞懂双摄融合算法:面试必问的源码级拆解,告别配置卡壳

搞懂双摄融合算法:面试必问的源码级拆解,告别配置卡壳 配置环境就卡半天?别急,这不是你的错。很多开发者在调试多摄像头系统时,光是在驱动层和 HAL 层之间反复横跳就耗光了耐心。 双摄技术是计算机视觉里的硬骨头,也是 面试必问…

2026/9/21 20:08:18 阅读更多 →
用户侧储能系统优化配置与经济性分析

用户侧储能系统优化配置与经济性分析

1. 用户侧储能系统概述与核心价值用户侧储能系统正在成为现代电力体系中不可或缺的组成部分,特别是在工商业用电场景中展现出显著的经济和技术价值。这类系统通常部署在工厂、园区、商业综合体等终端用电场所,通过与电网的智能互动实现多重收益。从技术角…

2026/9/21 20:08:18 阅读更多 →
3天搞懂添加字体到电脑,保姆级教程避坑指南

3天搞懂添加字体到电脑,保姆级教程避坑指南

3天搞懂添加字体到电脑,保姆级教程避坑指南 刚接项目就卡在字体加载上?看了一堆教程还是不会写项目,这太正常了。前端字体加载的坑,文档里从来不会细说,全是实战里踩出来的血泪。这篇保姆级教程,不整虚的,直接讲怎么把字体稳稳加进项目里,还让你彻底…

2026/9/21 20:08:18 阅读更多 →
5个坑点搞定h3c模拟器命令附完整示例

5个坑点搞定h3c模拟器命令附完整示例

5个坑点搞定h3c模拟器命令附完整示例 复制来的 h3c模拟器命令 跑不通,报错信息还看不懂?别慌,这是90%初学者的通病。很多教程只给最终结果,却不讲底层逻辑,导致你换个场景就抓瞎。今天这篇文章不整虚的,直接给你一套能落地的 完整示例…

2026/9/21 20:08:18 阅读更多 →
react-admin 的 `<Confirm>` 组件:基于 Material UI Dialog 的确认弹窗完整指南

react-admin 的 `<Confirm>` 组件:基于 Material UI Dialog 的确认弹窗完整指南

前端UI组件 【免费下载链接】react-admin A frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design 项目地址&#xff1a; https://gitcode.com/gh_mirrors/re/react-admin 点击查看 免费下载 <Conf…

2026/9/21 20:07:18 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析&#xff1a;从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南&#xff1a;src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin &#x1f680;ViteVue3Gin拥有AI辅助的基础开发平台&#xff0c;企业级业务AI开发解决方案&#xff0c;内置mcp辅助服务&#xff0c;内置skills管理&#xff0c;…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址&#xff1a; https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件&#xff08;Full-featured Plugin&#xff09;是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事&#xff1a;用Flutter给OpenHarmony做一款游戏集合类的App&#xff0c;说白了就是把若干小游戏塞进一个壳里&#xff0c;用统一入口分发。这个方向本身不算新鲜&#xff0c;真正让我花了不少心思的&#xff0c;是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档&#xff0c;最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事&#xff1a;今天在表后面多加了两个空白行&#xff0c;明天给客户交稿前发现整个章节的编号全部错位&#xff0c;光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年&#xff0c;说实话&#xff0c;第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年&#xff0c;流量惨淡、功能臃肿、代码自己都懒得看第二遍之后&#xff0c;我才慢慢琢磨明白一个道理&#xff1a;第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践&#xff1a;原型怎样变成可用功能分类&#xff1a;[AI/大模型]细分主题&#xff1a;AI 增强型 CI/CD 流水线自动化与 GitOps 实践&#xff1a;Agent 工作流、工具调用与任务拆解&#xff1a;从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战&#xff1a;复盘记录怎样真正派上用场分类&#xff1a;[工程技术]细分主题&#xff1a;Kubernetes 生产环境运维与排障实战&#xff1a;可复制的项目复盘模板与决策记录大部分团队的事故复盘报告&#xff0c;最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理&#xff1a;核心链路应该先拆哪一步分类&#xff1a;[工程技术]细分主题&#xff1a;Docker 容器化技术与镜像安全管理&#xff1a;核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用&#xff08;包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →