Packer 制品供应链安全实战:用 provenance 后处理器生成 SLSA 出处证明、SBOM 与可验证签名

发布时间:2026/9/21 15:31:08
Packer 制品供应链安全实战:用 provenance 后处理器生成 SLSA 出处证明、SBOM 与可验证签名 云原生DevOps运维【免费下载链接】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 的provenance后处理器post-processor为构建产物生成符合 in-toto 规范的 SLSA Provenance v1 出处证明attestation可选附带软件物料清单SBOM及其证明并支持none/key/kms/keyless四种 DSSE 签名模式。本文以 post-processor/provenance/README.md 为主线结合仓库源码逐项拆解其配置参数、源码出处检测机制、签名与验证调用链、输出文件布局以及如何借助 CI 工作流达到 SLSA Build L2 乃至兼容 L3 的供应链安全基线。一、provenance 后处理器是什么provenance是 Packer 内置的一个后处理器核心职责是为进入后处理阶段的构建产物生成机器可读、可验证的供应链证明文件。其能力覆盖三条线SLSA 出处证明生成 SLSA Provenance v1 陈述statement并富集源码仓库与 CI 元数据如构建器 ID、调用 ID、源码提交哈希SBOM 旁车文件与证明基于内置 Syft 引擎生成 CycloneDX 或 SPDX 格式的 SBOM并生成对应的 SBOM 证明可选 DSSE 签名通过可配置的签名器signer与验证器verifier对证明做加密签名签名模式默认none即直接写出未签名的 JSON 陈述。从源码看后处理器的入口在 post-processor/provenance/post-processor.go 的PostProcess方法先由internalprovenance.DeriveSubjects计算产物的 SHA-256 摘要作为 in-toto subject再构建 SLSA predicate、用WrapInToto包装成 in-toto Statement最后按signing_mode决定是写出未签名 JSON 还是 DSSE 签名信封。整个流程会把原 artifact 原样透传源码中返回source, true, true, nil因此它可以安全地串在构建链中而不改变产物本身。二、最小配置与默认行为在 HCL 模板中给某个 build 挂上provenance后处理器即可启用post-processor provenance { build_type https://packer.io/buildtypes/hcl2/v1 template ubuntu.pkr.hcl only_builds [qemu.ubuntu] user_variables { region us-east-1 } sbom true }这段配置的含义结合 post-processor.go 中Configure的默认值逻辑build_type写入 SLSA predicate 的buildDefinition.buildType默认值常量定义在 internal/provenance/predicate.go 中https://packer.io/buildtypes/hcl2/v1template与only_builds会作为外部参数external parameters记录在证明里用于说明这个产物是由哪个模板、哪些 build 产生的user_variables记录用户变量的最终取值凡是在packer_sensitive_variables中声明过的变量其值会被替换为[sensitive value redacted]见redactSensitiveVariables对应测试 post-processor_test.gosbom true表示同时生成 SBOM 与 SBOM 证明。在Configure中设置的其余默认值包括配置项默认值build_typehttps://packer.io/buildtypes/hcl2/v1sbom_formatcyclonedx对应 internal/sbom/generator.go 的FormatCycloneDXsbom_scopesquashedsigning_modenone未签名fulcio_urlhttps://fulcio.sigstore.devrekor_urlhttps://rekor.sigstore.dev三、完整配置参数参考Config结构体定义在 post-processor.go其 HCL2 字段清单由 post-processor.hcl2spec.go 自动生成。以下是完整参数表参数类型说明provenancebool是否生成证明默认开启设为false时后处理器直接透传 artifactbuild_typestringSLSA predicate 的 buildType URI默认https://packer.io/buildtypes/hcl2/v1output_dirstring证明旁车文件的输出目录默认取 artifact 首个文件所在目录无本地文件的 artifact 默认当前目录templatestring产生该产物的 Packer 模板路径作为外部参数记录only_buildslist(string)产物来源的 build 列表作为外部参数记录user_variablesmap(string)追加记录的用户变量敏感变量值会被脱敏source_uristring覆盖自动检测到的源码仓库 URIsbombool是否同时生成 SBOM 与 SBOM 证明sbom_formatstringSBOM 格式cyclonedx默认或spdxsbom_scan_pathstringSBOM 扫描路径默认扫描 artifact 文件或其公共父目录当 artifact 文件横跨多个目录时必填sbom_scopestring扫描范围squashed默认或all-layerssbom_excludelist(string)从 SBOM 扫描中排除的 glob 路径signing_modestringnone默认未签名 JSON、key本地 PEM 私钥、kmsKMS/Vault URI、keylessSigstore Fulciosignerstring签名器引用key模式为 PEM 私钥路径kms模式为awskms://...、gcpkms://...、azurekms://...、hashivault://...等 URIkeystringsigner的别名两者同时设置时取值必须一致否则报错verifierstring验证用 PEM 路径key/kms模式下默认为签名器的派生公钥keyless模式不支持该参数fulcio_urlstringkeyless模式的 Fulcio CA 地址默认https://fulcio.sigstore.devrekor_urlstringupload_tlog开启时使用的 Rekor 透明度日志地址默认https://rekor.sigstore.devupload_tlogboolkeyless签名是否上传 Rekor 并产出携带透明度证据的 Sigstore bundletrusted_root_pathstring可选的 Sigstore trusted-root JSON 路径用于固定 keyless 验证信任根缺省时拉取公共 Sigstore 信任根keyless_identitystringkeyless模式期望的签名身份如 workflow ref必填keyless_oidc_issuerstringkeyless模式期望的 OIDC issuer如https://token.actions.githubusercontent.com必填底层对signing_mode的参数校验集中在signingBackendConfigpost-processor.go它会在Configure阶段就返回错误例如key/kms模式缺少signer或key、kms模式传入非法的 URI 前缀、keyless模式缺失身份策略、keyless模式试图覆盖 verifier 等。签名模式的常量定义在 internal/attestation/signer.go。四、源码出处检测与 source_uri 覆盖provenance 陈述会把构建的源码仓库记录为一条已解析依赖resolved dependency。检测逻辑位于 internal/provenance/gitinfo.go 的detectGitDependency优先级如下GitHub Actions 环境读取GITHUB_REPOSITORYGITHUB_SHA必要时拼接GITHUB_SERVER_URL与GITHUB_REF生成形如githttps://github.com/owner/reporefs/heads/main的 URI并以gitCommit摘要记录提交哈希GitLab CI 环境读取CI_PROJECT_URLCI_COMMIT_SHACI_COMMIT_REF_NAME本地 Git 仓库在 Packer 运行的当前工作目录执行git rev-parse HEAD取提交哈希、git config --get remote.origin.url取远端地址没有远端时回退为file://形式的本地路径 URI。sanitizeGitRemoteURL会剥离 URL 中内嵌的用户名/口令/令牌避免凭据泄漏到证明文件里。构建器 ID 与调用 ID 同样从 CI 环境自动检测DetectBuilderID依次检查GITHUB_WORKFLOW_REF、CI_JOB_URL、CI_PIPELINE_URL、BUILD_URL缺省回退为https://packer.io/local-buildDetectInvocationID依次检查GITHUB_RUN_ID、CI_PIPELINE_ID、CI_JOB_ID、BUILD_ID找不到则生成随机 UUID。source_uri的覆盖语义当构建发生在源码 checkout 之外、或远端 URL 需要归一化时设置source_uri即可覆盖检测结果——若检测成功则替换其 URI 字段若检测失败则直接以source_uri构造依赖。对应实现见resolvedDependenciespost-processor.go。五、四种签名模式详解5.1none未签名陈述默认默认模式直接以json.MarshalIndent写出结构化的 in-toto Statement见writeAttestation的SigningModeNone分支。适合先把证明流水线跑通、后续再叠加签名能力的场景。5.2keyPEM 私钥签名post-processor provenance { signing_mode key signer keys/provenance-signing.pem verifier keys/provenance-signing.pub.pem sbom true }signer指向 PEM 私钥路径verifier指定显式 PEM 公钥缺省时使用签名器派生的公钥若同时给出key与signer两者必须相等源码中不一致会报signer and key must match when both are set签名后PostProcess会立即用 verifier 调用VerifyEnvelope做签名自检签名无效时构建直接失败而不是写出无法验证的坏文件。5.3kmsKMS / Vault 托管密钥post-processor provenance { signing_mode kms signer awskms://alias/packer-provenance sbom true }支持的 URI 前缀由isRecognizedKMSSigner硬编码校验awskms://、gcpkms://、azurekms://、hashivault://。验证使用从 KMS 拉取的公钥或显式verifierPEM。KMS 提供方实现分别位于 internal/attestation/sign_kms_provider_aws.go、sign_kms_provider_gcp.go、sign_kms_provider_azure.go、sign_kms_provider_hashivault.go。hashivault://支持在 URI 中携带路径等参数参考sign_kms.go的解析实现。5.4keylessSigstore Fulcio 无钥匙签名post-processor provenance { signing_mode keyless fulcio_url https://fulcio.sigstore.dev rekor_url https://rekor.sigstore.dev upload_tlog true keyless_identity https://github.com/hashicorp/packer/.github/workflows/build.ymlrefs/heads/main keyless_oidc_issuer https://token.actions.githubusercontent.com trusted_root_path sigstore-trusted-root.json }keyless 模式使用临时密钥对 Fulcio 签发的短期证书完成签名要求存在环境 OIDC 令牌——例如SIGSTORE_ID_TOKEN或可兑换为 Sigstore 身份的 CI 提供方令牌GitHub Actions 下即ACTIONS_ID_TOKEN_REQUEST_URL/ACTIONS_ID_TOKEN_REQUEST_TOKEN前提是 workflow 声明了id-token: write权限。源码层面该模式要求必须配置keyless_identity与keyless_oidc_issuer除非显式提供 verifier否则配置阶段即报错。keyless 模式下 Packer 会在每个签名证明旁额外写一个*.sigstore.jsonbundle 旁车文件当upload_tlog true时该 bundle 携带 Rekor 透明度日志证据供packer verify-attestation -bundle ...做透明度验证。构建过程中的 keyless 验证会强制校验 Fulcio 证书链与配置的身份策略对于 Rekor 支撑的验证需要使用生成的 Sigstore bundle 运行packer verify-attestation并配合-require-rekor和/或-require-timestamp标志。六、输出文件与命名规则输出路径由outputPaths决定post-processor.go所有文件以output_dir默认 artifact 首文件所在目录为基准文件说明{stem}.provenance.jsonSLSA Provenance v1 证明未签名 JSON 或 DSSE 签名信封{stem}.sbom.cdx.json原始 CycloneDX SBOMsbom_format spdx时为{stem}.sbom.spdx.json{stem}.sbom.att.jsonSBOM 证明predicate type 为https://cyclonedx.org/bom或https://spdx.dev/Document{stem}.sigstore.jsonkeyless 模式额外写出的 Sigstore bundle 旁车文件stem的计算规则值得注意默认取 artifact 首个文件的文件名若packer_build_name存在且与之不同则前缀为{build_name}.{base}从而保证多个并行 build 写入同一输出目录时不会互相覆盖对应测试TestOutputStemDisambiguatesByBuildName。所有写入都通过atomicWriteFile完成先写临时文件、fsync后rename就位防止并行构建产生半写文件或崩溃遗留损坏的证明对应测试TestAtomicWriteFileReplacesExistingWithoutLeftovers。对于没有本地文件如云端镜像的 artifactDeriveSubjects会构造 artifact 身份记录并对其做 SHA-256生成形如{builder_id}:{artifact_id}的 subject同时把 base64 编码的cloud-artifact-identity旁车记录进证明的 byproducts。七、SBOM 集成细节开启sbom true后Packer 会重新生成SBOM 而非复用已有文件——resolveSBOM的注释明确指出复用旧 SBOM 可能在 artifact 变化后仍证明过时内容对应测试TestPostProcessorRegeneratesStaleSBOM。生成器基于内嵌 Syft SDK实现在 internal/sbom/generator.go 与 generator_syft.go。扫描路径的解析逻辑resolveSBOMScanPathartifact 只有 1 个文件扫描该文件多个文件且共享同一父目录扫描该公共父目录多个文件且横跨不同目录报错并提示必须设置sbom_scan_path无本地文件报错并提示需要本地 artifact 文件或sbom_scan_path。sbom_scope支持squashed默认与all-layers两种扫描范围sbom_exclude可传入 glob 排除清单。八、验证证明packer verify-attestation与签名能力配套Packer 提供packer verify-attestation命令command/verify_attestation.go用于验证已签名的 DSSE 证明并执行策略检查。用法packer verify-attestation [options] ATTESTATION常用选项选项说明-signing-modeMODEkey/kms/keyless可自动探测-keyPATH_OR_URIPEM 密钥路径或 KMS/Vault URI-verifierPATHPEM 验证器路径-predicate-typeTYPE期望的 predicate 类型-builder-idID期望的 SLSA builder ID-source-uriURI期望的已解析源码 URI-artifactPATH与证明 subject 匹配的产物路径-trusted-root-pathPATH可选 Sigstore 信任根 JSON-keyless-identityIDENTITY期望的 keyless 签名身份-keyless-oidc-issuerISSUER期望的 keyless OIDC issuer-bundlePATH可选 Sigstore bundle JSON用于 Rekor/时间戳验证-require-rekor要求通过 bundle 完成 Rekor 透明度日志验证-require-timestamp要求来自 Rekor 集成时间或 RFC3161 证据的可信观察者时间戳验证路径底层调用internalattestation.VerifyAttestationFileinternal/attestation/verify.go解析 DSSE 信封、核对 payloadType 为 in-toto、验证签名再按VerificationPolicy逐项检查 predicate 类型、builder ID、源码 URI、产物 subject 摘要以及在提供 bundle 时透明度日志与时间戳证据。九、SLSA Build 级别与 CI 参考工作流SLSA Build 级别大多是构建平台的属性而非构建工具的属性。Packer 作为工具其能力边界如下原文表格出自 README.md 与 examples/ci/README.mdSLSA Build 级别要求Packer 的角色Packer 提供的L1存在出处证明并被分发完全由 Packer 承担出处证明生成L2证明由托管平台签名Packer 通过 CI OIDC 身份签名CI 中的 keyless 签名L3加固平台构建步骤无法触达签名密钥平台属性Packer 兼容委托签名模式L4—SLSA v1.0 未定义—Packer 生成 SLSA Provenance v1天然达到 BuildL1在托管 CI 上启用 keyless 签名后达到L2。L3 是构建平台的属性——它要求签名密钥对构建步骤不可达Packer 本身不能单独赋予 L3但委托签名模式与 L3 平台兼容。仓库提供了两个可直接复制使用的 GitHub Actions 参考工作流均位于 examples/ci/注意它们并未接入本仓库自身 CI需拷贝到你的项目.github/workflows/下按模板与产物路径适配github-actions-l2-keyless.ymlL2 模式。workflow 声明id-token: writePacker 用 workflow 自身的 OIDC 身份完成 keyless 签名并上传 Rekor模板中通过-var把keyless_identity与keyless_oidc_issuer传入Packer 的env()函数只能出现在变量default中不能内联在块里最后遍历*.provenance.json用-bundle-require-rekor-require-timestamp完成验证- name: Verify attestation run: | for att in *.provenance.json; do packer verify-attestation \ -signing-modekeyless \ -bundle${att%.json}.sigstore.json \ -require-rekor \ -require-timestamp donegithub-actions-l3-delegated.ymlL3 兼容模式。build 任务只负责构建并输出产物摘要sha256sum后 base64证明生成与签名被委托给一个隔离的可复用 workflowSLSA GitHub generator构建步骤无法触达签名材料从而满足 L3 的隔离要求。十、安全与最佳实践要点综合 README 与源码落地 provenance 时值得遵循的实践敏感变量必须声明脱敏把口令、令牌等变量加入packer_sensitive_variablesexternalParameters会将其值替换为占位符redactedSensitiveValue避免密钥被写进证明文件PKR_VAR_*环境变量同样会被收集并受同一脱敏逻辑保护签名后自检key/kms/keyless模式在写出前都会调用VerifyEnvelope自检签名不可验证时构建失败杜绝写了签不上的假签名并行构建安全多 build 共享output_dir时输出文件名会自动带上 build 名前缀且所有写入走原子重命名避免覆盖与半写文件CI 自动溯源在 GitHub Actions / GitLab CI 中运行时源码 URI、提交哈希、builder ID、invocation ID 均自动从环境变量提取无需手工配置本地构建则依赖当前目录的 Git 仓库信息必要时用source_uri归一化keyless 固定信任根对验证要求严格的环境用trusted_root_path固定 Sigstore 信任根避免依赖公共根的分发L3 靠平台而非工具若目标是 SLSA Build L3需要把签名委托给隔离的签名器参考 L3 工作流Packer 负责生成证明、平台负责提供隔离。十一、进一步阅读后处理器实现与配置结构post-processor/provenance/post-processor.go、post-processor.hcl2spec.go单元测试覆盖脱敏、SBOM 重生成、签名自检、输出命名、原子写入等场景post-processor/provenance/post-processor_test.goSLSA predicate 与 in-toto Statement 结构internal/provenance/predicate.go、internal/provenance/statement.go、internal/provenance/subject.go源码出处检测internal/provenance/gitinfo.go签名/验证后端internal/attestation/signer.go、internal/attestation/verify.goSBOM 生成器internal/sbom/generator.go验证命令command/verify_attestation.goCI 参考工作流examples/ci/README.md赞分享云原生DevOps运维【免费下载链接】packerPacker is a tool for creating identical machine images for multiple platforms from a single source configuration.项目地址https://gitcode.com/gh_mirrors/pa/packer点击查看免费下载相关推荐Authelia 制品签名与 SLSA 供应链溯源验证指南Authelia 制品签名与 SLSA 供应链溯源验证指南 本指南基于 Authelia 官方安全文档系统讲解 Authelia 发布制品的 GPG 签名体系后端认证鉴权单点登录身份认证应用安全OpenMed 容器镜像签名与供应链验证指南Sigstore 无密钥签名、SBOM 与 SLSA 证明的端到端实践OpenMed 容器镜像签名与供应链验证指南Sigstore 无密钥签名、SBOM 与 SLSA 证明的端到端实践 OpenMed 是一个本地优先local人工智能NLP医疗健康数据脱敏本地部署大模型AI 应用MCP 服务联邦学习Cognee 供应链安全实战PEP 740、SLSA 与 SBOM 三级制品溯源与发布验证指南Cognee 供应链安全实战PEP 740、SLSA 与 SBOM 三级制品溯源与发布验证指南 本文以 supply_chain_provenance.md人工智能AI AgentRAG知识图谱后端MCP 服务上一篇js-beautify 源码中的代码度量复杂度与规模分析下一篇构建永不宕机的并行系统oneTBB高可用架构实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考