本周先把 SBOM 生成命令、Package.resolved、目标产品和生成时点对齐,再判断清单是否对应已交付产物;生成成功不等于依赖范围准确。这适用于 Swift 6.4 的 Swift Package 项目,也适用于需要把 SwiftPM 依赖清单与 macOS 应用归档一起审查的 CI 流程。
Swift Package 维护者:要把 Swift 6.4 生成的 SBOM 纳入依赖审计或交付流程,可以从这里开始。
Apple 平台 CI 工程师:需要核验构建命令、产品范围和实际归档是否对应。
研发安全与合规负责人:需要判断现有生成、留存和追溯证据能否支持审查。
最后更新于 2026 年 10 月 26 日;已对照 Swift 6.4 发布说明、SE-0509、SwiftPM SBOM 文档及格式规范核验。Swift 6.4 发布说明确认 SwiftPM 加入 SBOM 生成功能;具体依赖图和命令边界以SE-0509 提案和SwiftPM SBOM 文档为准。
SECTION 01 Swift 6.4 SBOM 与 macOS CI 产物不一致的排查起点
先看生成命令采用了哪种图:swift package generate-sbom 使用包解析图,不会调用构建,也不使用 Swift Build 的构建依赖图;构建命令可结合 Swift Build 的构建图筛选已使用依赖。随后再核对清单对应整个 package 还是指定 product,以及它生成时的依赖解析状态是否仍与构建一致。SE-0509 明确说明,独立子命令不使用构建依赖图。
这一步很关键,因为常见的“不一致”并非 JSON 文件损坏,而是验收对象不同:文件格式有效,清单也能列出依赖,但它可能来自更宽的解析图、另一个产品,或后续重新解析出的依赖状态。再加上 SwiftPM 的清单不能单凭文件存在证明它已与某个应用归档建立可追溯关联,团队就容易把“生成成功”误当成“交付核验通过”。
先区分以下几类证据:
- 清单组件多于预期:可能使用了完整解析图,而不是该构建实际使用的依赖图。
- 关键依赖缺失:检查是否只生成了单个 product 的清单,或构建与清单使用了不同解析状态。
- 产品名称或关系不对:确认生成对象是 package 还是 product;target 级 SBOM 不能通过该命令的
--target参数指定。 - 清单无法对应归档:检查文件名、提交标识、CI 任务记录和归档文件是否在同一交付批次中保存。格式校验本身不提供这种对应关系。
SECTION 02 依赖图的范围为什么会影响组件数量?
Swift Package Manager SBOM 可能来自两种范围不同的图。只使用解析图时,清单纳入解析得到的包依赖;使用 Swift Build 构建图时,则可依据构建时计算出的依赖关系筛选实际使用的组件。比如,平台条件会在构建时评估,解析图本身并不反映这些条件,因此 macOS 构建所需组件与解析图中的完整依赖范围可能不同。
也就是说,不能把“组件更多”直接判定为清单更完整,也不能因为数量少就断定漏包。需要先问:这份清单要描述的是 package 可解析到的依赖,还是某次构建图中的使用范围?之后再用产品关系和 CI 构建记录核对。尤其是跨平台项目,不同平台条件可能改变构建图;把不同平台的清单拿来和同一份 macOS 产物对照,结论就会失真。
⚠️
swift package generate-sbom适合在不重跑构建时生成基于包解析图的清单,但它不能补出原构建的 Swift Build 依赖图。若交付验收要求清单反映构建时使用的依赖,应优先在构建命令中生成,并保留该次构建的输出与日志。
| 核对维度 | swift build 生成 |
swift package generate-sbom 生成 |
排查时要确认 |
|---|---|---|---|
| 是否执行构建 | 会执行构建;SBOM 在构建成功后生成 | 不会调用构建 | 清单是否和本次构建处于同一流程 |
| 依赖图来源 | 指定 --build-system swiftbuild 时可使用构建依赖图;否则仅使用包解析图 |
使用包解析图,不使用 Swift Build 构建依赖图 | 日志是否显示了预期构建系统 |
| 范围选择 | 可针对整个 package 或单个 product | 可针对 package 或单个 product | 目标是否与交付产品一致 |
| 解析状态风险 | 与构建时图状态核对 | 独立生成前可能重新解析依赖 | Package.resolved 是否被更新或变动 |
表中命令行为和产品范围限制以SE-0509 的命令选项与子命令说明为依据。关键参数是 --build-system swiftbuild:提案说明,不指定它时会提示 SBOM 仅使用 package graph;--sbom-spec 可与整个 package 或 --product 搭配,不能与 --target 搭配。不要把 --product 的产品级清单误称为 target 级清单。
SECTION 03 多产品项目怎样核对清单对应的产品?
先把“构建目标”和“交付物”写成同一张映射:CI 实际执行的 scheme 或 SwiftPM product、归档中预期出现的产品,以及 SBOM 声明的根对象。一个 package 可以包含多个 product;对某个 product 生成的清单,不应直接被当作整个 package 或最终应用的完整依赖清单。
在 SwiftPM 构建场景中,针对单个产品生成清单时,可以在构建命令里明确写出 product 名称:
swift build \
--build-system swiftbuild \
--product ProductName \
--sbom-spec cyclonedx \
--sbom-output-dir "$PWD/sbom"
如果同一次构建需要两种格式,可以重复指定 --sbom-spec:
swift build \
--build-system swiftbuild \
--product ProductName \
--sbom-spec cyclonedx \
--sbom-spec spdx \
--sbom-output-dir "$PWD/sbom"
这是 SwiftPM 的 product 范围,不应未经核对就等同于 Xcode scheme 最终打包出的应用。若 CI 交付的是 Xcode archive,应另外确认归档内容和构建 scheme;Apple 的应用归档与发布流程说明,archive 是依据所选 scheme 和构建目标生成的构建产物。将 SwiftPM SBOM 与 Xcode 归档并列留存,是审查时的证据关联,不代表 SwiftPM 自动将 SBOM 绑定或签署到归档上。
SECTION 04 生成时点和锁定依赖怎样造成差异?
Package.resolved 记录依赖解析结果;Swift Package Manager 文档说明,它位于 package 顶层目录,在 Apple 平台项目中也可能位于 .xcodeproj 或 .xcworkspace 内。PackageDescription 对 Package.resolved 的说明可用于确认你检查的是项目实际使用的锁定文件,而不是仓库里另一个位置的同名文件。
风险出现在“先构建、后独立生成清单”的间隔中:如果这段时间依赖解析状态变化,后生成的清单就可能描述新图,而非构建使用的图。SE-0509 提供 --disable-automatic-resolution,用于在 Package.resolved 未更新时让独立生成失败;是否启用应纳入团队验收策略,而不是假定子命令自然沿用先前构建时的状态。SwiftPM 的命令文档也列出强制仅使用 Package.resolved 版本的解析选项。
本周复测时按这个顺序走:
- 固定同一提交,记录 CI 中的提交标识,并检查工作区没有未提交的依赖清单改动。
- 找到实际用于构建的
Package.resolved,保存其内容或校验值;确认 Xcode 项目使用的锁定文件路径没有认错。 - 检查 CI 命令:是
swift build,还是swift package generate-sbom;记录是否指定--build-system swiftbuild。 - 列出交付产品,核对命令是否针对整个 package,还是用
--product ProductName指定单个产品。 - 若使用独立生成命令,启用
--disable-automatic-resolution,并检查生成过程是否出现解析失败或告警。 - 将构建日志、SBOM 文件和实际交付归档放入同一 CI 任务的归档记录;重新下载后再核对文件名、提交和产品范围。
- 对关键依赖关系进行人工抽查;只有范围、产品和来源信息都通过,才把“SBOM 验收通过”作为交付结论。
SECTION 05 格式有效仍不能证明清单属于这个产物
格式校验只回答文件结构能否被解析,不负责证明组件范围正确,也不负责证明文件来自哪次构建。这三层验收要分开:格式有效性、依赖范围正确性、产物来源可追溯性。Swift 6.4 发布资料确认 SwiftPM 可生成 CycloneDX 或 SPDX;SE-0509 描述的格式版本为 CycloneDX 1.7 与 SPDX 3.0,并说明 SwiftPM 内含基于 JSON Schema 的验证。执行后仍要检查根组件、依赖关系和产品名,而不是止步于命令返回成功。
需要独立验证格式时,可对照CycloneDX 的 SBOM 验证指南及SPDX 3 序列化与验证规则,按清单实际格式使用相应校验方式。请注意,格式版本必须以你实际 SwiftPM 工具链生成的文件为准;不要把规格版本写死在验证脚本中后,就把结构校验当作内容审计。
最后一层是关联证据:为清单文件名或同批记录保存提交标识、构建任务、产品名、工具链版本和归档位置,并确保下载后的文件仍能与原任务对应。SE-0509 将 SBOM 签名及与产物关联所需的哈希列为后续功能方向;因此,不要声称 SwiftPM 已自动对 SBOM 签名,或已把它与二进制产物绑定。
SECTION 06 用这份验收清单完成 macOS CI 复核
下面的流程不依赖虚构的性能数据,也不假定 SBOM 与二进制自动绑定。它的目标是让团队在同一提交、同一解析状态下,能够复现并检查清单与构建产物。
- [ ] 记录提交标识、Swift 工具链版本及 CI 实际执行的构建命令。
- [ ] 保存并检查项目对应的
Package.resolved,确认生成 SBOM 前后锁定依赖状态一致。 - [ ] 根据验收目标选择 package 或单个 product;不要用一个产品的 SBOM 代表整个应用。
- [ ] 若要求反映构建图,在
swift build中指定--build-system swiftbuild并生成清单。 - [ ] 若必须在构建之后运行
swift package generate-sbom,使用锁定状态保护选项,并明确记录它使用的是包解析图。 - [ ] 对照根组件、依赖关系和预期产品,分别完成格式校验与范围复核。
- [ ] 将 SBOM、构建日志、提交标识和最终归档放入同一任务记录,下载归档后再检查对应关系。
- [ ] 如果交付是 Xcode archive,单独核对 archive 中的产品;不要把 SwiftPM 清单等同于完整归档清单。
环境边界:SwiftPM 生成 SBOM 和 Swift Package 构建依赖 Swift 工具链;如果流程还要产出 Apple 平台的 Xcode archive,就需要在可运行相应 Apple 工具链的 macOS 环境中执行归档步骤。可以在其他执行环境里完成部分清单解析、JSON 检查或结果比对,但这些步骤不能替代 macOS 上的目标构建和归档核验。
如果你目前靠本地 Mac 临时跑构建,容易遇到工具链版本与 CI 不同、依赖状态未固定、任务结束后日志和归档分散等问题;若改用非 macOS 主机,也不能替代需要 Apple 工具链的归档步骤。对需要短期复现或隔离 CI 环境的团队,租赁真实 Mac 可以提供 macOS 执行环境,但并不自动解决 SBOM 范围、解析锁定或产物追溯问题。你可以先查看 VPSNIX 的 Mac 环境信息,再按团队周期评估 租赁方案;若需要长期稳定负载或依赖本地物理接口,自购设备通常更合适。