SLSA provenance 怎样描述构建来源
SLSA provenance 怎样描述构建来源?最容易犯的错误,是只写一个 Git 仓库地址,然后把它当成“来源已经完整记录”。更准确的做法是把一次构建拆成三件事:最终产物是谁、构建输入是什么、哪个受信任的构建平台执行了这次构建。SLSA provenance 正是用这三个边界描述产物是怎样产生的。
官方地址:https://slsa.dev/spec/v1.2/build-provenance
如果只记住一个判断:源码仓库或分支属于构建接口参数,解析后的具体提交及其摘要属于已解析依赖,构建平台和调用标识则属于本次执行详情。三者不能互相替代。
先把构建来源拆成三个边界
SLSA provenance 外层使用 in-toto Statement,最重要的连接点是 subject 和 predicate。subject 指向构建产生的文件、镜像或其他软件产物,并带有摘要;predicate 里的 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 递归展开。

| 检查项 | 要回答的问题 | 不匹配时的处理 |
|---|---|---|
| 签名与信任根 | 证明是否由认可的身份签发 | 拒绝继续使用该 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和构建参数都符合验证方预期。
eBPF 可观测工具怎样减少内核改动
- 上一篇
- eBPF 可观测工具怎样减少内核改动
- 下一篇
- Sidecar 容器生命周期变化解决什么部署问题
-
- 科技周边 · 业界新闻 | 14分钟前 | github · kubernetes · Kubernetes 开源协作 SIG Docs kubernetes/website 文档贡献
- Kubernetes SIG 文档怎样参与贡献
- 357浏览 收藏
-
- 科技周边 · 业界新闻 | 17分钟前 | gitHub actions · 供应链安全 OpenSSF Scorecard 仓库治理 Branch-Protection Code-Review Token-Permissions
- Scorecard 检查项怎样辅助仓库治理
- 281浏览 收藏
-
- 科技周边 · 业界新闻 | 24分钟前 | 云原生 · 容器 · kubernetes · 业界新闻 · Kubernetes Job restartPolicy initContainers Pod生命周期 Sidecar容器
- Sidecar 容器生命周期变化解决什么部署问题
- 310浏览 收藏
-
- 科技周边 · 业界新闻 | 28分钟前 |
- eBPF 可观测工具怎样减少内核改动
- 356浏览 收藏
-
- 科技周边 · 业界新闻 | 31分钟前 | 云原生 · 供应链安全 ·
- 云原生供应链安全项目如何分工
- 255浏览 收藏
-
- 科技周边 · 业界新闻 | 33分钟前 | 云原生 · WebAssembly WASI WIT Wasm Component Model 组件组合
- Wasm Component Model 解决了什么接口复用问题
- 236浏览 收藏
-
- 科技周边 · 业界新闻 | 35分钟前 | Collector SpanID TraceID OpenTelemetry Logs 可观测性关联
- OpenTelemetry Logs 信号怎样与 traces 关联
- 446浏览 收藏
-
- 科技周边 · 业界新闻 | 37分钟前 |
- Gateway API 如何补足传统 Ingress 的路由表达
- 269浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 985次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 991次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1112次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1081次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 927次使用
-
- Docker Buildx 怎么给镜像同时生成 SBOM 和来源证明
- 2026-10-06 335浏览
-
- AI 应用如何隔离租户知识库:检索权限、缓存键与引用验收
- 2026-08-25 369浏览
-
- Google ADK 零信任代理怎么落地:签名写入、gVisor 沙箱与语义网关的边界
- 2026-08-25 377浏览
-
- GitHub Actions artifact attestations 如何落地:从构建产物到验证链的工程边界
- 2026-08-28 298浏览
-
- Python Packaging Council 2026 候选人名单公布:项目维护者如何核对投票信息与时间
- 2026-08-30 142浏览

