当前位置:首页 > 文章列表 > 科技周边 > 业界新闻 > SLSA provenance 怎样描述构建来源

SLSA provenance 怎样描述构建来源

来源:17golang原创 2026-11-11 22:49:56 0浏览 收藏

SLSA provenance 怎样描述构建来源?最容易犯的错误,是只写一个 Git 仓库地址,然后把它当成“来源已经完整记录”。更准确的做法是把一次构建拆成三件事:最终产物是谁、构建输入是什么、哪个受信任的构建平台执行了这次构建。SLSA provenance 正是用这三个边界描述产物是怎样产生的。

官方地址:https://slsa.dev/spec/v1.2/build-provenance

如果只记住一个判断:源码仓库或分支属于构建接口参数,解析后的具体提交及其摘要属于已解析依赖,构建平台和调用标识则属于本次执行详情。三者不能互相替代。

先把构建来源拆成三个边界

SLSA provenance 外层使用 in-toto Statement,最重要的连接点是 subject 和 predicate。subject 指向构建产生的文件、镜像或其他软件产物,并带有摘要;predicate 里的 provenance 再说明它是怎样被构建出来的。

SLSA provenance 中构建输入、源码提交摘要、执行详情和产物 subject 的结构说明图
图1:SLSA provenance 字段分层的结构说明图,展示构建来源如何连接到产物,不是运行截图。

可以先用下面这张职责表建立口径:

字段区域描述什么典型内容
subject构建输出产物名称与 sha256 摘要
buildDefinition构建定义与输入buildType、externalParameters、resolvedDependencies
runDetails本次构建执行builder.id、调用标识、时间和副产物

因此,“构建来源”不是一个单独字段。它是构建参数、被解析的依赖和可信执行平台共同组成的可解释关系。

用 externalParameters 描述构建接口

externalParameters 表示从构建平台外部传入的顶层输入,例如仓库地址、分支引用、发布通道或构建开关。它描述的是“调用构建时传了什么”,不是把所有最终解析结果都塞进一个对象。

例如,构建平台收到一个仓库地址和分支引用,可以这样表达。这个 JSON 块保持严格有效,字段含义放在代码外解释:

{
  "buildDefinition": {
    "buildType": "https://ci.example.com/build-types/container-v1",
    "externalParameters": {
      "repository": "https://git.example.com/team/checkout.git",
      "ref": "refs/heads/main"
    },
    "resolvedDependencies": []
  }
}

buildType 是解释这些参数的模板标识。它不只是一个随手填写的字符串,应该能指向描述参数结构、依赖解释方式和构建入口的规范。这样下游才知道 repository、ref 的语义是什么。

另一个边界是内部参数。由平台自己决定的运行环境信息可以放到 internalParameters,但它不是外部调用者传入的来源声明,也不应该和 externalParameters 混用同一个字段名。只有确实有助于复现、排障或事件响应时,才需要记录这部分信息。

用 resolvedDependencies 固化实际来源

仓库 URL 和分支名可能在不同时间指向不同提交,所以只记录 refs/heads/main 不能说明这一次构建到底读到了哪份源码。构建平台解析引用后,应把实际提交作为依赖资源,至少记录可定位的 URI 和摘要。

{
  "resolvedDependencies": [
    {
      "uri": "git+https://git.example.com/team/checkout@refs/heads/main",
      "digest": {
        "gitCommit": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"
      },
      "name": "checkout-source"
    }
  ]
}

这里的分工很清楚:externalParameters.repository 和 ref 是构建接口收到的原始值,resolvedDependencies 是平台实际解析出的输入。两者都保留,才能同时回答“构建请求指向哪里”和“这次构建实际用了什么”。

如果构建脚本又下载了一个工具包、配置文件或压缩包,只要它是构建过程中获取并可能影响输出的输入,就应在可获得时作为另一个资源描述。不要把依赖摘要写成外部参数里的装饰字段,否则下游难以判断它究竟是调用者输入,还是解析后的具体资源。

用 runDetails 说明谁执行了构建

runDetails 关注“这一次执行发生在哪里”。其中最关键的是 builder.id:它标识被信任、能够正确执行构建并生成 provenance 的构建平台边界。它不是 Git 提交者,也不是某个编译器版本的别名。

{
  "runDetails": {
    "builder": {
      "id": "https://ci.example.com/builders/isolated-linux",
      "version": {
        "runner": "2026.11"
      }
    },
    "metadata": {
      "invocationId": "build-2026-11-11-0042",
      "startedOn": "2026-11-11T10:02:00Z",
      "finishedOn": "2026-11-11T10:05:12Z"
    }
  }
}

invocationId 便于把 provenance 和一次 CI 运行、审计记录或故障调查关联起来;它不能替代产物摘要,也不能替代源码提交摘要。若某些日志或完整解析配置只对排障有帮助、又不是主要构建输出,可以按实际需要作为 byproducts 引用,但不必把所有中间文件都塞进去。

把三类信息合成最小 provenance

实际写入时,可以把前面的片段合并为一个最小示例。为了让示例仍然适合复制,下面只保留结构,不伪装成某个真实 CI 产品生成的完整回执:

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "checkout-image.tar",
      "digest": {
        "sha256": "ff332109abdd"
      }
    }
  ],
  "predicateType": "https://slsa.dev/provenance/v1",
  "predicate": {
    "buildDefinition": {
      "buildType": "https://ci.example.com/build-types/container-v1",
      "externalParameters": {
        "repository": "https://git.example.com/team/checkout.git",
        "ref": "refs/heads/main"
      },
      "resolvedDependencies": [
        {
          "uri": "git+https://git.example.com/team/checkout@refs/heads/main",
          "digest": {
            "gitCommit": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"
          }
        }
      ]
    },
    "runDetails": {
      "builder": {
        "id": "https://ci.example.com/builders/isolated-linux"
      },
      "metadata": {
        "invocationId": "build-2026-11-11-0042"
      }
    }
  }
}

注意 predicateType 使用稳定的 https://slsa.dev/provenance/v1。规范页面的版本路径用于阅读具体版本,但 predicateType 会按 SLSA 的解析规则保持主版本语义;不要把页面地址栏中的版本后缀直接复制成 predicateType。

下游验证时要检查哪些关系

provenance 只有被检查才有价值。一个实用的最小顺序是:先验证证明包签名,再确认 subject 摘要等于手头产物摘要,然后确认 predicateType、可信 builder.id、buildType 和 externalParameters 都符合预期。依赖检查可以再沿 resolvedDependencies 递归展开。

SLSA provenance 下游验证边界与符合预期或拒绝结果的结构说明图
图2:SLSA provenance 验证边界的结构说明图,展示字段比较和依赖递归检查,不是运行截图。
检查项要回答的问题不匹配时的处理
签名与信任根证明是否由认可的身份签发拒绝继续使用该 provenance
subject证明是否对应当前产物摘要视为产物或证明被替换
builder.id执行平台是否在信任范围内不能只看它声称的 SLSA 等级
buildType 与外部参数构建是否来自允许的模板和源码入口拒绝未识别或不符合策略的输入

这里的“符合预期”不是看到字段存在就算通过。例如,externalParameters 中的仓库地址必须是策略允许的规范来源;builder.id 也要和验证方预先建立的信任根匹配。SLSA Build L3 能力同样建立在信任构建平台的前提上,不等于平台内部任何角色都自动可信。

几个经常混淆的字段边界

  • 仓库地址不等于源码版本:地址和分支是请求输入,具体提交摘要才是这次构建解析到的版本线索。
  • builder 不等于编译器:builder.id 表示产生并负责记录 provenance 的构建平台边界;编译器可以作为依赖、版本信息或其他适合的字段记录。
  • provenance 不等于 SBOM:provenance 重点描述产物如何被构建;SBOM 更关注产物中包含哪些组件,两者可以通过资源引用关联,但职责不同。
  • 存在字段不等于完成验证:还要检查签名、产物摘要、构建类型、外部参数和信任根之间的关系。

最后用一张速查表判断是否写对

准备生成 SLSA provenance 时,可以按以下顺序自查:第一,subject 是否真实绑定输出摘要;第二,buildType 是否能解释构建接口;第三,externalParameters 是否只放外部输入;第四,源码引用解析出的提交是否进入 resolvedDependencies;第五,builder.id 是否能对应实际信任边界;第六,验证方是否有明确的允许值和拒绝条件。

只要这六个问题能够回答,SLSA provenance 就不再是“填一份 JSON”,而是一份能把产物、实际输入和执行平台连起来的构建来源说明。

相关问题

  • externalParameters 里要不要直接放 Git 提交摘要?通常先记录构建接口收到的参数,解析后的资源摘要放入 resolvedDependencies,除非构建接口本身就直接接收摘要。
  • 所有构建中间文件都要写进 provenance 吗?不需要;优先记录会影响输出或验证判断的依赖,排障资料可按需作为 byproducts 引用。
  • 只检查 provenance 的签名就够了吗?不够,还要确认签名者、builder.id、产物 subject 和构建参数都符合验证方预期。
版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
eBPF 可观测工具怎样减少内核改动eBPF 可观测工具怎样减少内核改动
上一篇
eBPF 可观测工具怎样减少内核改动
Sidecar 容器生命周期变化解决什么部署问题
下一篇
Sidecar 容器生命周期变化解决什么部署问题
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    985次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    991次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1112次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1081次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    927次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码