GitHub 官方说明,Artifact Attestations 本身对应 SLSA v1.0 Build Level 2;它能关联产物与构建流程,但不代表产物安全。(官方说明)
症状:流水线显示证明验证成功,你仍不知道它是不是当前要发布的 IPA。最快解法:对最终交付文件核验摘要和预期工作流,再分别验收测试、Apple 签名及发布审批。
企业 CI 负责人:需要为 iOS 构建产物建立来源核验流程。
供应链安全负责人:需要划清证明能验证什么、不能证明什么。
发布工程师:需要把来源证明与测试、签名和归档验收衔接起来。
先划清来源证明的验收边界
Artifact Attestations 用于建立构建来源证明,并支持消费端核验。证明记录可包含关联工作流、仓库、组织、环境、提交 SHA 和触发事件等信息。你要核对这些信息是否符合团队的发布策略,而不是只看证明是否存在。(GitHub 功能说明)
它不能单独证明代码安全、测试通过或发布审批完成。也不能替代 Apple 代码签名检查;Apple 的签名机制用于标识代码并检查签名及代码是否被更改。(Apple 代码签名说明)
这几项证据各自回答不同问题:
- ✅ 来源证明:哪个仓库、提交和工作流产生了这个文件?
- ✅ 测试记录:指定测试和质量门禁是否通过?
- ✅ Apple 签名:应用签名、配置文件和分发条件是否有效?
- ⚠️ 发布审批:是否由授权人员批准把这份产物交付出去?
注意:验证成功是策略判定的输入,不是“可以发布”的同义词。你的放行规则应明确列出必须同时通过的来源、测试、签名和审批检查。
先确认仓库具备生成证明的条件
在改流水线前,先核实仓库可见性和组织所用方案。GitHub 当前文档说明,Artifact Attestations 适用于当前方案的仓库;Free、Pro 和 Team 方案仅适用于公开仓库,私有或内部仓库需要 Enterprise Cloud 方案。方案资格可能随官方政策调整,投产验收时应以当前功能资格说明为准。
不要把一次公开仓库的成功运行,当成企业所有仓库都已具备生成条件。分别抽查公开、私有或内部仓库中的生成步骤、证明存取和消费端核验;对不满足资格的仓库,先确定替代流程和阻断责任人。
按身份指标核对仓库、提交与工作流
在 GitHub Actions 的构建工作流中加入生成步骤后,检查证明关联的源仓库、提交 SHA、触发事件和工作流身份。提交应与本次发布候选代码一致;工作流文件路径及所在仓库,应与团队批准的构建入口一致。GitHub 的生成指南说明了所需权限和二进制产物的证明步骤。
如果你使用可复用工作流,调用方工作流和实际执行证明签署的工作流可能不是同一个。此时要按真实架构设置验证约束;GitHub 文档提供了用 --signer-repo 和 --signer-workflow 指定签署仓库或工作流的方式。(可复用工作流验证说明)
不要只检查工作流名称。还要审查触发方式、代码变更审批、工作流文件的维护权限,以及谁可以修改发布路径。企业认可哪些仓库和工作流属于可信来源,是组织自己的验收策略,不会由证明自动替你决定。
再核对产物摘要,锁定最终交付文件
对照证明绑定的产物摘要与发布系统实际接收的文件。关键不是“同一构建产生过一个证明”,而是待发布文件本身就是证明所指向的对象。生成证明时,subject-path 应指向你计划让消费端核验的文件。
iOS 流程常有多个易混淆的对象:Xcode 归档、导出的 IPA、上传包,以及发布系统最终保存的副本。只要导出、重新压缩或其他处理改变了文件内容,就不能默认旧文件的证明仍匹配新文件。Apple 文档也将归档和导出描述为分开的分发环节。(Apple 归档与导出说明)
第一步:确定验收对象
在流水线中明确声明证明对应的是归档,还是导出的 IPA;发布门禁则以真正交付给下游的那一份文件为核验对象。把对象路径、文件名和构建提交写入流水线记录,避免同一任务中的中间文件被误当成发布文件。
第二步:在文件定型后生成证明
把证明生成步骤放到所有会改变目标文件的操作之后。若导出后的 IPA 才是发布对象,就对 IPA 生成证明;不要先证明归档,再把导出文件视为天然继承该证明。
第三步:由消费端核验同一文件
发布门禁对实际待发布文件执行 gh attestation verify,并约束预期仓库。示意命令如下;组织、仓库、工作流路径和文件路径需替换成实际值:
gh attestation verify "$IPA" \
-R ORG/REPO \
--signer-workflow ORG/REPO/.github/workflows/ios-release.yml
若证明由其他仓库中的可复用工作流生成,应按实际签署身份配置约束,不要照抄示例路径。
第四步:检查结果并设置失败路径
除命令是否成功外,还要记录验证所针对的文件、预期来源条件和结果。签名、时间戳或签署者身份没有经过有效核验时,不应把证明当作可信证据。GitHub 的 REST API 文档也特别提示,验证需要检查这些要素和签署者身份。(REST API 证明验证注意事项)
第五步:区分阻断与复核责任
来源不匹配、摘要不匹配或证明缺失时,发布流程应按团队政策阻断,而不是由执行者临时绕过。记录谁能复核、谁能批准例外,以及例外是否需要重新构建和重新验收。测试、Apple 签名和发布审批仍应各自保留独立的通过记录。
在真实发布任务中验收 GitHub Artifact Attestations iOS CI
先选团队实际使用的发布任务,而不是只拿测试用的小文件验证命令。让同一提交经过构建、测试、签名、导出和发布候选归档,随后由消费端对最终文件执行核验。GitHub 也提供了离线验证流程;若发布环境无法联网,需要把证明包、可信根信息和目标文件纳入离线验收设计。(离线验证指南)
场景案例:证明通过,但发布文件不同
假设构建任务先对归档生成证明,随后另一个任务导出 IPA。验收人员只看到来源证明通过,就放行了导出的文件。这里遗漏的是文件对应关系:证明针对的对象与交付对象可能不同。修正方式是把最终 IPA 作为核验对象,并确认生成与消费阶段使用同一文件。
验收时还要独立核对 Apple 的处理结果。Apple 的文档说明 iOS 分发涉及签名与配置文件;公证则是 macOS 软件分发相关的流程。因此,不要把 macOS 公证结果当成 iOS 发布证据,也不要把来源证明当成 Apple 签名验证。(iOS 归档与分发说明;Apple 公证流程说明)
用验收表决定是否放行
下表把“验证命令通过”和“企业认可该来源”分开。前者是工具结果;后者还要满足组织定义的仓库、提交和工作流策略。
| 验收维度 | 通过条件 | 不通过时的处理 |
|---|---|---|
| 仓库资格 | 仓库类型与当前方案符合官方资格条件 | 暂停该仓库的证明验收,先确认可用路径 |
| 来源身份 | 仓库、提交和触发信息符合发布记录 | 阻断,确认代码版本与发布候选是否一致 |
| 工作流身份 | 签署工作流在团队批准的来源清单内 | 阻断或升级安全负责人复核 |
| 文件摘要 | 待发布文件与证明关联的产物一致 | 不放行;对最终文件重新生成并核验 |
| 发布门禁 | 测试、签名和审批分别达到本团队要求 | 保留各门禁的失败状态,不用来源证明覆盖 |
| 方案选择 | 适用条件 | 主要优点 | 主要限制 |
|---|---|---|---|
| 对最终 IPA 生成并核验证明 | IPA 是明确的最终交付对象 | 来源和文件摘要直接对应交付文件 | 导出后若再改动文件,需要重新核验 |
| 只对 Xcode 归档生成证明 | 下游以该归档作为交付对象 | 证明对象与归档流程容易关联 | 若之后导出另一文件,不能据此断定新文件已验收 |
| 仅检查证明是否存在 | 仅用于早期试跑或排查流程 | 能快速发现是否执行过生成步骤 | 不能替代身份约束、摘要匹配或发布门禁 |
把 Mac 构建环境作为单独的验收对象
来源证明回答的是产物从哪里来,不回答承载构建的 Mac 节点是否符合你的权限隔离、可用性或环境管理要求。若 CI 依赖 Mac 完成 Xcode 构建、签名或导出,应把节点准入、凭证访问、工作目录清理、任务隔离和故障恢复另列检查项;不要把 attestation 当作 Mac 环境认证。
如果你还在评估团队的 Mac CI 容量,可先对照远程 Mac 算力方案与现有节点的扩容条件。需要临时构建能力或隔离测试环境时,MACCOME 提供按需租用托管 Mac 的方式,访问可通过 VNC、SSH 或网页控制台进行;你应在采购前核对实际交付信息、权限和团队合规要求。稳定、长期的重负载场景,或必须连接本地物理设备的流程,购买并自主管理 Mac 可能更合适。更多方案入口见 MACCOME。