本文目录导读:

生成一份软件物料清单(SBOM, Software Bill of Materials)目前主要有三种主流方式:自动生成(工具扫描)、构建时生成(集成构建系统) 和 手动生成(不推荐,仅用于极简场景)。
最常用且推荐的做法是使用自动化工具,以下是具体的步骤和主流工具的选择:
核心思路
SBOM 的核心是列出软件中包含的所有组件(开源库、第三方包)及其版本、依赖关系 和 许可证 信息。
生成 SBOM 通常遵循以下流程:
- 识别代码库:确定你要扫描的项目或制品(如 Docker 镜像、二进制文件、源代码目录)。
- 选择工具:选择一个与你的技术栈匹配的 SBOM 生成工具。
- 执行分析:工具会解析包管理文件(如
package.json,pom.xml,requirements.txt)、二进制文件或容器镜像,并建立依赖树。 - 输出标准化格式:将结果输出为行业标准格式(如 SPDX, CycloneDX)。
使用工具自动生成(最推荐)
这是目前最主流、最准确的方式,根据你的开发环境,可以选择以下工具:
方式 A:使用开源扫描工具
推荐工具:Syft (Anchore)
-
特点:支持多种语言(Go, Java, Python, JS, Rust, .NET 等)和多种输出格式(CycloneDX, SPDX, JSON)。
-
适用场景:直接在代码仓库或 Docker 镜像上运行。
-
示例命令:
# 扫描当前项目目录,生成 CycloneDX 格式的 SBOM syft dir:. -o cyclonedx-json > sbom.json # 扫描 Docker 镜像 syft your-docker-image:tag -o spdx-json > sbom.spdx.json
推荐工具:Trivy (Aqua Security)
-
特点:虽然以漏洞扫描闻名,但也内置了强大的 SBOM 生成能力。
-
适用场景:希望同时生成 SBOM 和发现漏洞。
-
示例命令:
# 扫描文件系统并生成 CycloneDX 格式的 SBOM trivy filesystem --format cyclonedx --output sbom.json . # 扫描容器镜像 trivy image --format spdx-json your-image:tag
推荐工具:Microsoft SBOM Tool
-
特点:由微软开发,官方出品,支持 SPDX 2.2/3.0 标准,深度集成于 .NET 和 Windows 生态。
-
示例命令:
sbom-tool generate -b ./ -bc ./src -pn "MyProject" -pv 1.0.0 -ps "MyCompany"
方式 B:集成到 CI/CD 流水线
对于企业级应用,建议将 SBOM 生成集成到 GitHub Actions、GitLab CI、Jenkins 等流水线中。
-
GitHub Actions 示例(使用 Anchore SBOM Action):
- name: Generate SBOM uses: anchore/sbom-action@v0 with: path: "." format: "cyclonedx-json" output-file: "sbom.json"
方式 C:针对特定语言的包管理器
- Go:
go-jsonnet+bom工具,或者使用syft直接扫描go.sum。 - Node.js:
npm sbom(npm 9.7.0+) 或cyclonedx-npm。 - Python:
pip-licenses或cyclonedx-python。 - Java/Maven:
cyclonedx-maven-plugin(直接在构建时生成)。 - Java/Gradle:
org.cyclonedx.gradle.plugin。
手动生成(仅用于极简/学习场景)
不推荐在生产环境中使用,因为手动容易遗漏、出错,且无法处理复杂的传递依赖。
步骤:
- 列出所有直接依赖(查看
package.json,requirements.txt,pom.xml)。 - 追踪所有间接依赖(传递依赖)。
- 手动编写一个符合 ISO 标准的 JSON/XML 文件(如 SPDX 或 CycloneDX 格式)。
示例(极简 CycloneDX 格式片段):
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"components": [
{
"type": "library",
"name": "lodash",
"version": "4.17.21",
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"purl": "pkg:npm/lodash@4.17.21"
}
]
}
必须包含的关键字段
无论使用哪种方式,一份合格的 SBOM 应至少包含:
- 组件名称(
name):如requests,express,log4j。 - 版本号(
version):准确(如31.0),避免使用latest。 - 依赖关系(
dependsOn):A 依赖 B 和 C,B 依赖 D。 - 许可证信息(
license):如 MIT、Apache 2.0、GPL-3.0。 - 组件来源信息(
supplier或purl):包名 + 版本 + 类型(如pkg:npm/left-pad@1.3.0)。
如何验证生成的 SBOM 是否正确?
- 使用验证工具:
cyclonedx-cli validate sbom.json。 - 检查完整性:确保没有缺失主要依赖。
- 格式化匹配:确认文件符合 SPDX 或 CycloneDX 的 JSON Schema。
- 交叉比对:用另一个工具扫描同一项目,对比结果是否一致(Syft 生成的 SBOM 与 Trivy 生成的对比)。
总结建议
| 你的场景 | 推荐工具 | 命令/配置示例 |
|---|---|---|
| 扫描代码目录 | Syft | syft dir:. -o cyclonedx-json > sbom.json |
| 扫描 Docker 镜像 | Syft 或 Trivy | syft your-image -o spdx-json |
| 在 CI/CD 中自动生成 | Anchore SBOM Action (GitHub) | 如上 YAML 配置 |
| 简单验证 / 手动场景 | CycloneDX CLI | 下载并运行 cyclonedx validate |
| 需要同时发现漏洞 | Trivy | trivy image --format cyclonedx --output trivy.json |
最后一点建议:不要只生成一次 SBOM,建议的做法是:
- 每次构建(每次 CI/CD 运行)都生成一份新的 SBOM,并归档到制品仓库或 SBOM 管理平台。
- 将 SBOM 上传到中央仓库,用于后续的漏洞扫描和许可证合规性审计。