CycloneDX/sbom-utility
GitHub: CycloneDX/sbom-utility
一款支持 CycloneDX 和 SPDX 两种主流格式的 SBOM 验证、查询与精细化管理命令行工具,帮助组织在软件供应链安全流程中确保物料清单的合规性与一致性。
Stars: 136 | Forks: 19
[](https://opensource.org/licenses/Apache-2.0)
[](https://github.com/CycloneDX/specification)
[](https://github.com/spdx/spdx-spec)
[](https://goreportcard.com/badge/github.com/CycloneDX/sbom-utility)

# sbom-utility
**`sbom-utility`** 被设计为一个 API 平台,用于验证、分析和编辑**物料清单 (BOMs)**。最初,创建它是为了根据各自标准社区发布的官方版本化 JSON schema,对 CycloneDX *或* SPDX 格式的 BOM 进行**验证**。
- *组织也可以设计并提供**“自定义 JSON schema”**变体给 validate 命令,这可能是为了强制执行额外的数据合规要求。*
该实用程序还提供支持分析和编辑 BOM 文档数据的命令,包括 **trim**、**patch** (IETF RFC 6902) 和 **diff** *(实验性)*。
此外,该实用程序具有“报告”命令,可以使用该实用程序强大的、类似 SQL 的查询命令,轻松地*提取*、*过滤*、*列出*和*汇总***组件**、**服务**、**许可证**、**资源**、**漏洞**和其他 BOM 信息。**query** 命令允许**从** BOM 文档中的任何位置**选择**特定数据,**条件 (where)** 是数据值与指定的(正则表达式)模式匹配。
- *报告输出可以生成多种格式(例如,`txt`、`csv`、`md` (markdown) 和 `json`),以适应进一步的处理。*
**自定义 JSON 验证**不想创建自定义的 CycloneDX 和 SPDX schema 来强制执行对结构、字段、值等方面的 BOM 要求?好消息!现在您可以使用 `validate` 命令上新的 `--custom` 标志来添加您自己的 BOM 内容自定义验证!
- 通过阅读[自定义验证示例](docs/custom-examples.md)页面,了解如何使用这个期待已久的**实验性**功能。
### 命令概述
该实用程序提供了以下针对输入 BOM 及其数据进行操作的命令:
| 命令 *[`子命令`]* | 描述 |
| :-- | :-- |
| **[validate](#validate)** | 允许使用其 JSON schema,根据 SBOM 声明的格式(例如,SPDX,CycloneDX)和版本(例如,“2.3”,“1.6”等)对其进行验证。|
| **[patch](#patch)** | 将 [IETF RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/) 定义的 JSON 补丁文件应用于输入的 JSON BOM 文件。 |
| **[trim](#trim)** | 从输入的 JSON BOM 文档中删除指定的 JSON 信息,并生成具有缩减或针对性信息集的输出 BOM。*一组“类 SQL”参数允许细粒度地指定应从哪些文档路径中修剪哪些字段。* |
| **[diff](#diff)** | **实验性**[1](#experimental-commands):以 JSON (diff) 补丁格式显示两个相似 BOM 版本之间的差异,如 [IETF RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/) 所定义。*运行前请阅读“建议”。* |
| **[query](#query)** | 使用 SQL 风格的查询语句(即 `--select --from --where `)从 BOM 中检索 JSON 数据。JSON 数据可用于创建自定义列表或报告。 |
| **[component](#component)** **[`list`](#component-list-command)** | 生成 BOM 中声明的硬件或软件组件的可过滤列表。 |
| **[license](#license)** **[`list`](#license-list-subcommand)** | 生成 BOM 中声明的许可证数据以及相关组件或服务的可过滤列表。包含 `license.json` 配置文件中声明的*“使用策略”*决定。 |
| **[license](#license)** **[`policy`](#license-policy-subcommand)** | 生成软件和数据许可证信息以及由 `license.json` 配置文件定义的相关许可证使用策略的可过滤列表。 |
| **[resource `list`](#resource)** | 生成 BOM 中声明的资源(即组件和服务)的可过滤列表。 |
| **[schema `list`](#schema)** | 生成 `validation` 命令支持的 schema 格式、版本和变体的可过滤列表。 **注意**:自定义 JSON schema 也可以作为命名的 schema“变体”永久配置在实用程序的配置文件中(参见 `schema` 命令的[添加 schema](#adding-schemas) 部分)。 |
| **[vulnerability `list`](#vulnerability)** | 生成 BOM 中声明的漏洞(即 CycloneDX 漏洞可利用性交换 (**VEX**))数据或独立存储的 CycloneDX 漏洞披露报告 (**VDR**) 数据(以 BOM 格式存储)的可过滤列表。 |
### 项目索引
- [安装](#installation)
- [运行](#running)
- [命令](#commands)
- [贡献](#contributing)
- [设计考量](#design-considerations)
- [开发](#development)
- [测试](#testing)
- [发布](#releasing)
- [BOM 参考](#bom-references)
- [CycloneDX](#cyclonedx),[SPDX](#spdx)
### 安装
从本仓库的发布页面下载并解压适用于您目标系统架构和操作系统的正确存档文件(即 Unix/Linux 系统的 `.tar` 文件和 Windows 的 `.zip` 文件)。
- [https://github.com/CycloneDX/sbom-utility/releases](https://github.com/CycloneDX/sbom-utility/releases)
源代码存档将在根目录下包含以下文件:
- `sbom-utility` - 二进制可执行文件。对于非自定义配置,这已满足大多数需求。
- `LICENSE` - 实用程序的软件许可证(即 Apache 2)
- `sbom-utility-.sbom.json` - 实用程序的简单软件物料清单 (SBOM)
以及示例配置文件:
- `config.json` *(可选)* - 用于可选自定义的默认 schema 配置文件副本(将在命令行上传递)
- `license.json` *(可选)* - 用于可选自定义的默认许可证策略配置文件副本(将在命令行上传递)
- `custom.json` *(实验性,未使用)* - 自定义验证配置文件
## 运行
为方便起见,默认的 `config.json` 和可选的 `license.json` 配置文件已嵌入到可执行文件中并直接使用。*您可以使用 `--config-schema` 或 `--config-license` 标志在命令行上提供这些文件的自定义版本。*
- **注意**:*使用命令行标志提供配置文件时,可执行文件会尝试从运行该可执行文件的相同路径加载它们。如果您选择将它们保留在不同的目录中,则必须提供它们相对于可执行文件的位置以及文件名。*
##### MacOS - 授予可执行权限
在 MacOS 上,该实用程序不是注册的 Apple 应用程序,可能会在首次打开时警告您无法打开它。如果是这样,您将需要明确允许该可执行文件在您的系统上被“打开”,并确认它是受信任的。此过程是从 Finder 应用程序中开始的,方法是在可执行文件上使用 `ctrl-click` 并同意使用“打开”按钮。
- 参见如何[“打开来自身份不明开发者的 Mac 应用程序”](https://support.apple.com/guide/mac-help/open-a-mac-app-from-an-unidentified-developer-mh40616/mac)
## 命令
本节提供了所有命令、支持的标志和输出格式以及使用示例的详细说明。
所有命令生成一致的[退出代码](#exit-codes),并共享一些[持久标志](#persistent-flags),如下所述:
- [退出代码](#exit-codes):包括:*`0`:无错误,`1`:应用程序错误,`2`:验证错误等。*
- [持久标志](#persistent-flags) 包括:*`--input`、`--output`、`--format`、`--quiet`、`--where` 等。*
每个命令的便捷链接:
- [validate](#validate):根据声明或所需的 JSON schema 验证 BOM 数据。
- [trim](#trim):从 BOM 中移除不感兴趣或必要的字段和数据。
- [patch](#patch):使用 IETF RFC 6902 记录修补 BOM。
- [diff](#diff):*(实验性)*:显示两个相似 BOM 之间的差异。*执行前请阅读建议。*
- [query](#query):使用类似 SQL 的查询从 BOM 中提取 JSON 对象和字段。
- [component list](#component):列出在 BOM 中找到的所有组件信息。
- [license](#license)
- [list](#license-list-subcommand):列出在 BOM 中找到的所有许可证信息。
- [policy](#license-policy-subcommand):列出在 `license.json` 文件中找到的可配置许可证使用策略。
- [resource list](#resource):按类型(例如,组件、服务)列出所有资源信息。
- [schema list](#schema):按 BOM 格式、版本和变体列出支持的 JSON schema。
- [vulnerability list](#vulnerability):列出 BOM 中包含的或独立 `VDR` BOM 中的漏洞(即 `VEX`)信息。
- [completion](#completion):为此实用程序生成命令行补全脚本。
- [help](#help):显示此实用程序或当前指定命令的帮助和使用信息。
### 退出代码
所有命令都会返回一个数字退出代码(即 POSIX 退出代码),用于自动化处理,其中 `0` 表示成功,非零值表示由数字指定的某种失败。
SBOM Utility 始终返回以下 3 个代码之一,以适应 BASH (shell) 脚本中的逻辑:
- `0`= 无错误(有效)
- `1`= 应用程序错误
- `2`= 验证错误
##### 示例:退出代码
此示例使用 `schema` list 命令验证其退出代码:
```
./sbom-utility schema list
```
验证退出代码:
```
echo $?
```
返回 `0`(零)或“无错误”:
```
0
```
### 持久标志
本节描述适用于该实用程序大多数命令的一些重要命令行标志。
- [格式标志](#format-flag):使用 `--format`
- [缩进标志](#indent-flag):使用 `--indent`
- [输入标志](#input-flag):使用 `--input` 或 `-i`
- [输出标志](#output-flag):使用 `--output` 或 `-o`
- [静默标志](#quiet-flag):使用 `--quiet` 或 `-q`
- [Where 标志](#where-flag-output-filtering):使用 `--where`
#### 格式标志
所有 `list` 子命令都支持带有以下值的 `--format` 标志:
- `txt`:文本(制表符分隔的表格)
- `csv`:逗号分隔值 (CSV),例如,用于电子表格
- `md`:Markdown(兼容 GitHub 的表格)
一些可以输出 JSON 对象列表的命令也支持使用 `json` 值的 JSON 格式。
##### 示例:`--format` 标志
此示例在 `schema` 命令上使用 `--format` 标志以 markdown 格式输出:
```
./sbom-utility schema --format md -q
```
```
|name|format|version|variant|file (local)|url (remote)|
|:--|:--|:--|:--|:--|:--|
|CycloneDX v1.5|CycloneDX|1.5|(latest)|schema/cyclonedx/1.5/bom-1.5.schema.json|https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.5.schema.json|
|CycloneDX v1.4|CycloneDX|1.4|(latest)|schema/cyclonedx/1.4/bom-1.4.schema.json|https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.4.schema.json|
|CycloneDX/specification/master/schema/bom-1.3-strict.schema.json|
|CycloneDX v1.3|CycloneDX|1.3|(latest)|schema/cyclonedx/1.3/bom-1.3.schema.json|https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.3.schema.json|
|CycloneDX/specification/master/schema/bom-1.2-strict.schema.json|
|CycloneDX v1.2|CycloneDX|1.2|(latest)|schema/cyclonedx/1.2/bom-1.2.schema.json|https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.2.schema.json|
|SPDX v2.3.1 (development)|SPDX|SPDX-2.3|development|schema/spdx/2.3.1/spdx-schema.json|https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3.1/schemas/spdx-schema.json|
|SPDX v2.3|SPDX|SPDX-2.3|(latest)|schema/spdx/2.3/spdx-schema.json|https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3/schemas/spdx-schema.json|
|SPDX v2.2.2|SPDX|SPDX-2.2|(latest)|schema/spdx/2.2.2/spdx-schema.json|https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.2/schemas/spdx-schema.json|
|SPDX v2.2.1|SPDX|SPDX-2.2|2.2.1|schema/spdx/2.2.1/spdx-schema.json|https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json|
```
#### 缩进标志
此标志为任何编码 JSON 输出的命令提供一个整数,以确定嵌套 JSON 元素的缩进空格数。如果未指定,默认缩进为 `4`(个空格)。
##### 示例:query 命令上的缩进标志
```
./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 2 -q
```
缩进为 `2` 的输出:
```
{
"name": "juice-shop",
"version": "11.1.2"
}
```
```
./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 6 -q
```
缩进为 `6` 的输出:
```
{
"name": "juice-shop",
"version": "11.1.2"
}
```
#### 输入标志
所有 `list` 子命令和 `validate` 命令都支持 `--input-file ` 标(或其简写形式 `-i `)来声明命令将读取和操作的文件内容(即 BOM 数据)。
#### 标准输入 (stdin)
所有支持输入标志的命令也可以通过使用 `-`(破折号)字符作为值而不是文件名,来接受来自标准输入或 `stdin` 的数据。
##### 使用管道的 stdin 示例
```
cat examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json | ./sbom-utility resource list -i -
```
##### 使用重定向的 stdin 示例
```
./sbom-utility validate -i - < examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json
```
#### 输出标志
所有 `list` 子命令和 `validate` 命令都支持 `--output-file ` 标志(或其简写形式 `-o `)将格式化输出发送到文件。
##### 示例:`--output-file` 标志
此示例使用 `schema` 命令输出到名为 `output.txt` 的文件,格式设置为 `csv`:
```
./sbom-utility schema --format csv -o output.csv
```
验证 `output.csv` 的内容是否包含 CSV 格式的输出:
```
cat output.csv
```
```
Name,Format,Version,Variant,File (local),URL (remote)
CycloneDX v1.5 (development),CycloneDX,1.5,development,schema/cyclonedx/1.5/bom-1.5-dev.schema.json,https://raw.githubusercontent.com/CycloneDX/specification/v1.5-dev/schema/bom-1.5.schema.json
CycloneDX v1.4,CycloneDX,1.4,(latest),schema/cyclonedx/1.4/bom-1.4.schema.json,https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.4.schema.json
CycloneDX v1.3,CycloneDX,1.3,(latest),schema/cyclonedx/1.3/bom-1.3.schema.json,https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.3.schema.json
CycloneDX v1.2,CycloneDX,1.2,(latest),schema/cyclonedx/1.2/bom-1.2.schema.json,https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.2.schema.json
SPDX v2.3.1 (development),SPDX,SPDX-2.3,development,schema/spdx/2.3.1/spdx-schema.json,https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3.1/schemas/spdx-schema.json
SPDX v2.3,SPDX,SPDX-2.3,(latest),schema/spdx/2.3/spdx-schema.json,https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3/schemas/spdx-schema.json
SPDX v2.2.2,SPDX,SPDX-2.2,(latest),schema/spdx/2.2.2/spdx-schema.json,https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.2/schemas/spdx-schema.json
SPDX v2.2.1,SPDX,SPDX-2.2,2.2.1,schema/spdx/2.2.1/spdx-schema.json,https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json
```
- **注意**:您可以验证 `output.csv` 是否能在 MS Excel 等电子表格应用程序中加载。
#### 静默标志
所有命令都支持 `--quiet` 标志。默认情况下,该实用程序将信息性 (INFO)、警告 (WARNING) 和错误 (ERROR) 文本与实际命令结果一起输出到 `stdout`。如果您只想查看命令结果 (JSON) 或报告(表格),您可以通过简单地提供 `--quiet` 或其简写形式 `-q` 标志以“静默模式”运行任何命令。
##### 示例:`--quiet` 标志
此示例显示在 `schema` 命令上使用 `--quiet` 标志来关闭或“静默”任何信息性输出,以便仅显示结果表。
```
./sbom-utility schema list --quiet
```
```
name format version variant file (local) url (remote)
---- ------ ------- ------- ------------ ------------
CycloneDX v1.5 CycloneDX 1.5 (latest) schema/cyclonedx/1.5/bom-1.5.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.5.schema.json
CycloneDX v1.4 CycloneDX 1.4 (latest) schema/cyclonedx/1.4/bom-1.4.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.4.schema.json
CycloneDX v1.3 CycloneDX 1.3 (latest) schema/cyclonedx/1.3/bom-1.3.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.3.schema.json
CycloneDX v1.2 CycloneDX 1.2 (latest) schema/cyclonedx/1.2/bom-1.2.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.2.schema.json
SPDX v2.3.1 (development) SPDX SPDX-2.3 development schema/spdx/2.3.1/spdx-schema.json https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3.1/schemas/spdx-schema.json
...
```
#### Where 标志(输出过滤)
所有 `list` 子命令都支持 `--where` 标志。它可用于通过使用输出列表的列标题作为键,基于正则表达式的匹配来过滤输出结果。
可以在同一个 `--where` 过滤标志上提供多个键值(即 column-title=regex)对,并用逗号分隔。
**语法**:`[--where key=regex[,...]]`
有关 `--where` 标志过滤用法的上下文示例,请参见每个命令的部分。
### 验证
此命令将解析标准化的 SBOM,并根据其声明的格式和版本(例如,SPDX 2.3,CycloneDX 1.7)对其进行验证。
- 可以通过提供 `--variant` 名称作为标志,使用标准 JSON schema 的自定义变体进行验证。
- 可以使用 `--force` 标志指定明确的 JSON schema。
#### 使用支持的 schema 进行验证
使用 [schema](#schema) 命令列出支持的 schema 格式、版本和变体。
- “支持的” schema 已与它导入的任何依赖 schema 一起**“内置于”**该实用程序资源中。
- 这意味着**在没有网络连接**从远程位置加载 schema 的情况下,BOM 文件**也可以被验证**(也称为*“离线”*模式)。
#### 使用“自定义” schema 进行验证
自定义 JSON schema 也可以作为命名的 schema“变体”永久配置在该实用程序的配置文件中。参见[添加 schema](#adding-schemas)。
- **覆盖默认 schema**
- 使用 [`--force` 标志](#--force-flag)并传入一个替代 JSON schema 的 URI。
- **“自定义”** schema 变体,也许是从标准 BOM schema 派生而来的,可以使用 `--variant` 标志进行验证(例如,行业或公司特定的 schema)。
- **注意**:*这些变体需要作为资源内置于实用程序二进制文件中。*
#### 验证标志
以下标志可用于改善格式化错误输出结果时的性能:
##### `--force` 标志
您可以通过使用 `--force` 标志提供不同的 schema,来覆盖用于验证的 schema *(默认为与输入 BOM 文件中找到的声明格式和版本匹配的 schema)*。这对于根据较新的规范版本验证 BOM 内容或提供自定义 schema 可能很有用。
- **注意**:*`--force` 标志适用于具有有效 URI 的 schema 文件,包括 URL(例如,'https://')和文件(例如,'file://')。*
##### `--custom ` 标志 *`(实验性)`*
除了使用标准 CycloneDX schema 验证 BOM 输入文件外,您现在还可以提供一个自定义 JSON 文件,该文件将对 BOM 文档的选定部分应用一组内置的验证函数,可以验证 JSON 元素、属性键和值。
- 通过阅读[自定义验证示例](docs/custom-examples.md)页面,了解如何使用这个期待已久的**实验性**功能。
当前可以实现此功能的函数集包括:
- `isUnique` - 检查以给定属性名作为键的数组项的唯一性
- `hasProperties` - 可以验证选定元素上是否存在命名属性,并且还可以使用正则表达式强制相应的属性具有预期的值。
**注意**:*如果发现用例,计划在未来的版本中提供更多功能。*
##### `--error-limit` 标志
使用 `--error-limit x`(默认:`10`)标志将格式化的错误结果输出减少到前 `x` 个错误。默认情况下,仅输出前 10 个错误,并带有指示显示了 `x/y` 个错误的信息性消息。
##### `--error-value` 标志
使用 `--error-value=true|false`(默认:`true`)标志通过不显示 `value` 字段来减少格式化的错误结果输出,该字段显示了有关 BOM 中失败数据的详细信息。
##### `--colorize` 标志
使用 `--colorize=true|false`(默认:`false`)标志为错误结果的 `txt` 格式输出添加/移除颜色格式。默认情况下,`txt` 格式的错误输出是彩色的,以帮助人类阅读;对于自动化使用,可以将其关闭。
#### 验证示例
##### 示例:使用推断的格式和 schema 进行验证
验证本仓库中提供的“juice shop”SBOM (CycloneDX 1.2) 示例。
```
./sbom-utility validate -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json
```
```
[INFO] Attempting to load and unmarshal data from: 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json'...
[INFO] Successfully unmarshalled data from: 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json'
[INFO] Determining file's BOM format and version...
[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.2' (latest)
[INFO] Matching BOM schema (for validation): schema/cyclonedx/1.2/bom-1.2.schema.json
[INFO] Loading schema 'schema/cyclonedx/1.2/bom-1.2.schema.json'...
[INFO] Schema 'schema/cyclonedx/1.2/bom-1.2.schema.json' loaded.
[INFO] Validating 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json'...
[INFO] BOM valid against JSON schema: 'true'
```
您还可以从 validate 命令验证[退出代码](#exit-codes):
```
echo $?
```
```
0 // no error (valid)
```
##### 示例:使用 '--force' 标志通过远程 JSON schema 文件进行验证
```
./sbom-utility validate -i test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json --force https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json
```
```
[INFO] Attempting to load and unmarshal data from: 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json'...
[INFO] Successfully unmarshalled data from: 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json'
[INFO] Determining file's BOM format and version...
[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.6' (latest)
[INFO] Matching BOM schema (for validation): schema/cyclonedx/1.6/bom-1.6.schema.json
[INFO] Loading schema from '--force' flag: 'https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json'...
[INFO] Validating document using forced schema (i.e., '--force https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json')
[INFO] Schema 'schema/cyclonedx/1.6/bom-1.6.schema.json' loaded.
[INFO] Validating 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json'...
[INFO] BOM valid against JSON schema: 'true'
```
您还可以从 validate 命令验证[退出代码](#exit-codes):
```
echo $?
```
```
0 // no error (valid)
```
##### 示例:使用“自定义” schema 变体进行验证
验证命令将使用 SBOM JSON 文件本身中找到的声明格式和版本来查找默认(最新)匹配的 schema 版本(如 `config.json` 中所声明);但是,如果声明了相同 schema(相同格式和版本)的变体,则可以通过 `--variant` 命令行标志请求它们:
```
./sbom-utility validate -i test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json --variant custom
```
如果您运行上面的示例命令,您会看到几个“自定义” schema 错误,导致 SBOM 被判定为无效(即 `exit status 2`):
```
[INFO] Attempting to load and unmarshal data from: 'test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json'...
[INFO] Successfully unmarshalled data from: 'test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json'
[INFO] Determining file's BOM format and version...
[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.4' custom
[INFO] Matching BOM schema (for validation): schema/test/bom-1.4-custom.schema.json
[INFO] Loading schema 'schema/test/bom-1.4-custom.schema.json'...
[INFO] Schema 'schema/test/bom-1.4-custom.schema.json' loaded.
[INFO] Validating 'test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json'...
[INFO] BOM valid against JSON schema: 'false'
[INFO] (3) schema errors detected.
[INFO] Formatting error results ('txt' format)...
1. {
"type": "contains",
"field": "metadata.properties",
"context": "(root).metadata.properties",
"description": "At least one of the items must match",
"value": [
{
"name": "urn:example.com:disclaimer",
"value": "This SBOM is current as of the date it was generated."
},
{
"name": "urn:example.com:classification",
"value": "This SBOM is Confidential Information. Do not distribute."
}
]
}
2. {
"type": "const",
"field": "metadata.properties.0.value",
"context": "(root).metadata.properties.0.value",
"description": "metadata.properties.0.value does not match: \"This SBOM is current as of the date it was generated and is subject to change.\"",
"value": "This SBOM is current as of the date it was generated."
}
3. {
"type": "number_all_of",
"field": "metadata.properties",
"context": "(root).metadata.properties",
"description": "Must validate all the schemas (allOf)",
"value": [
{
"name": "urn:example.com:disclaimer",
"value": "This SBOM is current as of the date it was generated."
},
{
"name": "urn:example.com:classification",
"value": "This SBOM is Confidential Information. Do not distribute."
}
]
}
[ERROR] invalid SBOM: schema errors found (test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json)
[INFO] document 'test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json': valid=[false]
```
确认退出代码:
```
echo $?
```
```
2 // SBOM error
```
###### 为什么验证失败
输出显示了指示失败 JSON 对象的第一个 schema 错误;在这种情况下,
- CycloneDX `metadata.properties` 字段,它是一个 `property` 对象列表。
- 发现具有值为 `"urn:example.com:disclaimer"` 的 `name` 字段的属性具有不正确的 `value`。
- `value` 字段本应具有常量值 `"This SBOM is current as of the date it was generated and is subject to change."`(如自定义 schema 的正则表达式所要求)。
- 然而,发现它只有 `"This SBOM is current as of the date it was generated."` 的部分匹配。
###### schema 错误的详细信息
使用 `--debug` 或 `-d` 标志查看所有 schema 错误详细信息:
```
./sbom-utility validate -i test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json --variant custom -d
```
详细信息包括失败的 `metadata.properties` 对象的完整上下文,其中还包括一个 `"urn:example.com:classification"` 属性:
```
3. {
"type": "number_all_of",
"field": "metadata.properties",
"context": "(root).metadata.properties",
"description": "Must validate all the schemas (allOf)",
"value": [
{
"name": "urn:example.com:disclaimer",
"value": "This SBOM is current as of the date it was generated."
},
{
"name": "urn:example.com:classification",
"value": "This SBOM is Confidential Information. Do not distribute."
}
]
}
```
###### 示例:使用“JSON”输出格式进行验证
JSON 格式将提供一个模式错误结果的 `array`,可以作为验证工具链的一部分进行后处理。
```
./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json -q
```
```
[
{
"type": "unique",
"field": "components",
"context": "(root).components",
"description": "array items[1,2] must be unique",
"value": {
"type": "array",
"index": 1,
"item": {
"bom-ref": "pkg:npm/body-parser@1.19.0",
"description": "Node.js body parsing middleware",
"hashes": [
{
"alg": "SHA-1",
"content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
}
],
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"name": "body-parser",
"purl": "pkg:npm/body-parser@1.19.0",
"type": "library",
"version": "1.19.0"
}
}
},
{
"type": "unique",
"field": "components",
"context": "(root).components",
"description": "array items[2,4] must be unique",
"value": {
"type": "array",
"index": 2,
"item": {
"bom-ref": "pkg:npm/body-parser@1.19.0",
"description": "Node.js body parsing middleware",
"hashes": [
{
"alg": "SHA-1",
"content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
}
],
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"name": "body-parser",
"purl": "pkg:npm/body-parser@1.19.0",
"type": "library",
"version": "1.19.0"
}
}
}
]
```
###### 使用 `error-value=false` 标志减少输出大小
在许多情况下,BOM 可能存在许多错误,包含 `value` 信息的详细信息可能过于冗长并导致要检查的输出文件过大。在这些情况下,只需将 `error-value` 标志设置为 `false`。
在将该标志设置为 false 的情况下重新运行相同的命令会产生缩减的信息集。
```
./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json --error-value=false -q
```
```
[
{
"type": "unique",
"field": "components",
"context": "(root).components",
"description": "array items[1,2] must be unique"
},
{
"type": "unique",
"field": "components",
"context": "(root).components",
"description": "array items[2,4] must be unique"
}
]
```
### 修剪
此命令能够从指定的 JSON BOM 文档中“修剪”一个或多个 JSON 键(字段),从而有效地“精简” JSON 文档。此功能可帮助需要分析大型 BOM 中特定类型数据的大型 BOM 消费者,将 BOM 数据缩减至其用例或需求所需的内容。
#### 修剪支持的输出格式
此命令用于使用 [`--output-file` 标志](#output-flag)输出 JSON 格式的“修剪后”BOM。
- `json` (默认)
#### 修剪标志
修剪作用于 JSON BOM 输入文件(参见 [`--input-file` 标志](#input-flag)),并使用以下标志生成修剪后的 JSON BOM 输出文件:
##### 修剪 `--keys` 标志
逗号分隔的 JSON map 键列表。类似于 [query 命令的 `--select` 标志](#query---select-flag)语法。
##### 修剪 `--from` 标志
逗号分隔的 JSON 文档路径列表,使用与 [query 命令的 `--from` 标志](#query---from-flag)相同的语法。
##### 修剪 `--normalize` 标志
一个在修剪后和输出前规范化 BOM 数据的标志。
此标志调用自定义代码,使用自定义比较器对所有组件、服务、许可证、漏洞、属性、外部引用、哈希和*大多数*其他 BOM 数据进行排序。
每个比较器使用 `required` 字段和其他标识字段为每个唯一数据结构创建*“复合键”*。
#### 修剪示例
这些示例中使用的原始 BOM 可在此处找到:
- [test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json](test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json)
##### 示例:从整个 JSON BOM 中修剪 `properties`
验证本仓库中提供的“juice shop”SBOM (CycloneDX 1.2) 示例。
```
./sbom-utility trim -i ./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=properties
```
带有 `properties` 的原始 BOM:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9",
"components": [
{
"type": "library",
"bom-ref": "pkg:npm/sample@2.0.0",
"purl": "pkg:npm/sample@2.0.0",
"name": "sample",
"version": "2.0.0",
"description": "Node.js Sampler package",
"properties": [
{
"name": "foo",
"value": "bar"
}
]
},
{
"type": "library",
"bom-ref": "pkg:npm/body-parser@1.19.0",
"purl": "pkg:npm/body-parser@1.19.0",
"name": "body-parser",
"version": "1.19.0",
"description": "Node.js body parsing middleware",
"hashes": [
{
"alg": "SHA-1",
"content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
}
]
}
],
"properties": [
{
"name": "abc",
"value": "123"
}
]
}
```
不带 `properties` 的输出 BOM 结果:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9",
"version": 1,
"components": [
{
"type": "library",
"bom-ref": "pkg:npm/sample@2.0.0",
"name": "sample",
"version": "2.0.0",
"description": "Node.js Sampler package",
"purl": "pkg:npm/sample@2.0.0"
},
{
"type": "library",
"bom-ref": "pkg:npm/body-parser@1.19.0",
"name": "body-parser",
"version": "1.19.0",
"description": "Node.js body parsing middleware",
"hashes": [
{
"alg": "SHA-1",
"content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
}
],
"purl": "pkg:npm/body-parser@1.19.0"
}
]
}
```
##### 示例:从整个 JSON BOM 中修剪 `name` 和 `description`
```
./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=name,description -q
```
不带 `name` 或 `description` 的输出 BOM 结果:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9",
"version": 1,
"components": [
{
"type": "library",
"bom-ref": "pkg:npm/sample@2.0.0",
"version": "2.0.0",
"purl": "pkg:npm/sample@2.0.0",
"properties": [
{
"value": "bar"
}
]
},
{
"type": "library",
"bom-ref": "pkg:npm/body-parser@1.19.0",
"version": "1.19.0",
"hashes": [
{
"alg": "SHA-1",
"content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
}
],
"purl": "pkg:npm/body-parser@1.19.0"
}
],
"properties": [
{
"value": "123"
}
]
}
```
##### 示例:仅从 `components` 路径修剪 `properties`
```
./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=properties --from components -q
```
从所有 `components` 中移除 `properties` 的输出 BOM 结果:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9",
"version": 1,
"components": [
{
"type": "library",
"bom-ref": "pkg:npm/sample@2.0.0",
"name": "sample",
"version": "2.0.0",
"description": "Node.js Sampler package",
"purl": "pkg:npm/sample@2.0.0"
},
{
"type": "library",
"bom-ref": "pkg:npm/body-parser@1.19.0",
"name": "body-parser",
"version": "1.19.0",
"description": "Node.js body parsing middleware",
"hashes": [
{
"alg": "SHA-1",
"content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
}
],
"purl": "pkg:npm/body-parser@1.19.0"
}
],
"properties": [
{
"name": "abc",
"value": "123"
}
]
}
```
##### 示例:修剪 `bom-ref` 并规范化输出
```
./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-components-normalize.sbom.json --keys="bom-ref" --normalize -q
```
**注意** 如果您不想移除任何键而只是规范化输出,请将键设置为空字符串:`--keys=""`。
使用 trim 命令移除所有 `bom-ref` 字段并规范化输出:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"components": [
{
"type": "library",
"bom-ref": "pkg:npm/sample@2.0.0",
"purl": "pkg:npm/sample@2.0.0",
"name": "sample",
"version": "2.0.0",
"licenses": [
{
"license": {
"id": "GPL-2.0-or-later"
}
},
{
"license": {
"id": "LGPL-2.0-or-later"
}
},
{
"license": {
"id": "GPL-2.0-only"
}
}
],
"properties": [
{
"name": "moo",
"value": "cow"
},
{
"name": "foo",
"value": "bar"
}
]
},
{
"type": "library",
"bom-ref": "pkg:npm/body-parser@1.19.0",
"purl": "pkg:npm/body-parser@1.19.0",
"name": "body-parser",
"version": "1.19.0",
"hashes": [
{
"alg": "SHA-256",
"content": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
},
{
"alg": "SHA-1",
"content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
}
],
"licenses": [
{
"license": {
"id": "MIT"
}
},
{
"license": {
"id": "Apache-2.0"
}
}
],
"externalReferences": [
{
"type": "website",
"url": "https://example.com/website"
},
{
"type": "support",
"url": "https://example.com/support"
}
]
}
]
}
```
修剪后的、规范化的输出:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"components": [
{
"type": "library",
"name": "body-parser",
"version": "1.19.0",
"hashes": [
{
"alg": "SHA-1",
"content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
},
{
"alg": "SHA-256",
"content": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
}
],
"licenses": [
{
"license": {
"id": "Apache-2.0"
}
},
{
"license": {
"id": "MIT"
}
}
],
"purl": "pkg:npm/body-parser@1.19.0",
"externalReferences": [
{
"type": "support",
"url": "https://example.com/support"
},
{
"type": "website",
"url": "https://example.com/website"
}
]
},
{
"type": "library",
"name": "sample",
"version": "2.0.0",
"licenses": [
{
"license": {
"id": "GPL-2.0-only"
}
},
{
"license": {
"id": "GPL-2.0-or-later"
}
},
{
"license": {
"id": "LGPL-2.0-or-later"
}
}
],
"purl": "pkg:npm/sample@2.0.0",
"properties": [
{
"name": "foo",
"value": "bar"
},
{
"name": "moo",
"value": "cow"
}
]
}
]
}
```
### 补丁
此*实验性*命令能够使用 [IETF RFC6902](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1) *"JavaScript 对象表示法 (JSON) 补丁"*文件来“修补”现有的 JSON BOM 文档。
当前实现支持以下“修补”操作:
- "add"、"update"、"remove" 和 "test"
目前不支持 "move" 或 "copy" 操作。
修补适用于简单(即整数、浮点数、布尔值和字符串)值以及复杂值,例如 JSON 对象、map 和数组。
#### 修补支持的输出格式
此命令用于使用 [`--output-file` 标志](#output-flag)输出 JSON 格式的“修补后”BOM。
- `json` (默认)
#### 修补标志
patch 命令作用于 JSON BOM 输入文件(参见 [`--input-file` 标志](#input-flag))以及 [IETF RFC6902](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1)-格式的“补丁”文件,并使用以下标志生成输入 JSON BOM 的“修补后”版本作为输出:
##### 修补 `--patch-filename` 标志
`--patch-file ` 标志用于提供要应用于 BOM 输入文件的 IETF RFC6902 补丁文件的相对路径。
##### 修补 `--normalize` 标志
一个在修补后和输出前规范化 BOM 数据的标志。
标志调用自定义代码,使用自定义比较器对所有组件、服务、许可证、漏洞、属性、外部引用、哈希和*大多数*其他 BOM 数据进行排序。
每个比较器使用 `required` 字段和其他标识字段为每个唯一数据结构创建*“复合键”*。
#### 修补示例
本节包含所有支持的修补操作(即 add、replace、test)的示例,包括作为基元(即 `numbers`、`strings`)以及 JSON `objects` 且可能是索引 JSON `array` 元素的值。
- [示例 1:"add" BOM `serialNumber`](#patch-example-1-add-bom-serialnumber)
- [示例 2:"add" (update) BOM `version`](#patch-example-2-add-update-bom-version)
- [示例 3:"add" `supplier` 对象到 `metadata`](#patch-example-3-add-supplier-object-to-metadata-object)
- [示例 4:"add" `property` 对象到 `metadata.properties` 数组](#patch-example-4-add-property-objects-to-metadataproperties-array)
- [示例 4a:修补后规范化 `metadata.properties`](#patch-example-4a---normalize-properties-after-patching)
- [示例 5:"replace" `version` 和 `timestamp` 值](#patch-example-5-replace-bom-version-and-timestamp)
- [示例 6:从 `metadata.properties` 数组中 "remove" `property`](#patch-example-6-remove-property-from-the-metadataproperties-array)
- [示例 7:"test" `property` 是否存在于 `metadata.properties` 数组中](#patch-example-7-test-property-exists-in-the-metadataproperties-array)
##### 修补示例 1:"add" BOM `serialNumber`
此示例将新的顶级键 `"serialNumber"` 及相应的值添加到 CycloneDX JSON BOM 文件中。
原始 CycloneDX JSON BOM 文件:[test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json) 没有序列号:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
...
}
}
```
IETF RFC6902 JSON 补丁文件:[test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json):
```
[
{ "op": "add", "path": "/serialNumber", "value": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9" }
]
```
按如下方式调用 patch 命令:
```
./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-serial-number.json -q
```
修补后的 JSON BOM 输出文件:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9",
"version": 1,
"metadata": {
...
}
}
```
##### 修补示例 2:"add" (update) BOM `version`
此示例展示了如何使用补丁的 "add" 操作来更新现有值,这是 RFC6902 指定的行为。
原始 CycloneDX JSON BOM 文件:[test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json) 的 `version` 等于 `1`:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
...
}
}
```
IETF RFC6902 JSON 补丁文件:[test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json):
```
[
{ "op": "add", "path": "/version", "value": 2 }
]
```
按如下方式调用 patch 命令:
```
./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-update-version.json -q
```
修补后的输出 JSON BOM 文件,其 `version` 值已更改为 `2`:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 2,
"metadata": {
...
}
}
```
##### 修补示例 3:"add" `supplier` 对象到 `metadata` 对象
此示例展示了如何使用补丁的 "add" 操作将 JSON 对象添加到现有对象中。
原始 CycloneDX JSON BOM 文件:[test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"properties": [
...
]
}
}
```
应用以下 IETF RFC6902 JSON 补丁文件:[test/patch/cdx-patch-example-add-metadata-supplier.json](test/patch/cdx-patch-example-add-metadata-supplier.json):
```
[
{ "op": "add", "path": "/metadata/supplier", "value": {
"name": "Example Co. Distribution Dept.",
"url": [
"https://example.com/software/"
]
}
}
]
```
按如下方式调用 patch 命令:
```
./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-metadata-supplier.json -q
```
修补后的 BOM 已将 `supplier` 对象添加到 `metadata` 中:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"supplier": {
"name": "Example Co. Distribution Dept.",
"url": [
"https://example.com/software/"
]
},
"properties": [
...
]
}
}
```
##### 修补示例 4:"add" `property` 对象到 `metadata.properties` 数组
此示例展示了如何使用补丁的 "add" 操作将 `property` 对象添加到现有 `properties` 数组中。
原始 CycloneDX JSON BOM 文件:[test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"properties": [
{
"name": "Property 1",
"value": "Value 1"
},
{
"name": "Property 2",
"value": "Value 2"
}
]
}
}
```
应用以下 IETF RFC6902 JSON 补丁文件:[test/patch/cdx-patch-example-add-metadata-properties.json](test/patch/cdx-patch-example-add-metadata-properties.json):
```
[
{ "op": "add", "path": "/metadata/properties/-", "value": { "name": "foo", "value": "bar" } },
{ "op": "add", "path": "/metadata/properties/1", "value": { "name": "rush", "value": "yyz" } }
]
```
请注意,第一个补丁记录使用 `-`(破折号)表示“在末尾插入”,而第二个补丁记录具有从零开始的数组索引 `1`。
按如下方式调用 patch 命令:
```
./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-metadata-properties.json -q
```
修补后的输出 BOM 在指定索引处具有两个新属性:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"properties": [
{
"name": "Property 1",
"value": "Value 1"
},
{
"name": "rush",
"value": "yyz"
},
{
"name": "Property 2",
"value": "Value 2"
},
{
"name": "foo",
"value": "bar"
}
]
}
}
```
##### 修补示例 4a:修补后 `--normalize` 属性
此示例是前一个示例的变体,它还规范化了输出 BOM 数组;在这种情况下,规范化 `metadata.properties` 数组的现有和添加的属性。
```
./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-metadata-properties.json --normalize -q
```
修补和**规范化**后的 `metadata.properties` 如下所示:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"properties": [
{
"name": "Property 1",
"value": "Value 1"
},
{
"name": "Property 2",
"value": "Value 2"
},
{
"name": "foo",
"value": "bar"
},
{
"name": "rush",
"value": "yyz"
}
]
}
}
```
##### 修补示例 5:"replace" BOM `version` 和 `timestamp`
此示例展示了如何使用补丁的 "replace" 操作来更新 BOM 文档的 `version` 和 `timestamp` 值。
原始 CycloneDX JSON BOM 文件:[test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"properties": [
...
]
}
}
```
应用以下 IETF RFC6902 JSON 补丁文件:[test/patch/cdx-patch-example-replace-version-timestamp.json](test/patch/cdx-patch-example-replace-version-timestamp.json):
```
[
{ "op": "replace", "path": "/version", "value": 2 },
{ "op": "replace", "path": "/metadata/timestamp", "value": "2024-01-24T22:50:18+00:00" }
]
```
按如下方式调用 patch 命令:
```
./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-replace-version-timestamp.json -q
```
修补后的输出 BOM 同时更新了 `version` 和 `timestamp`:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 2,
"metadata": {
"timestamp": "2024-01-24T22:50:18+00:00",
"properties": [
...
}
}
```
##### 修补示例 6:从 `metadata.properties` 数组中 "remove" `property`
此示例展示了如何使用补丁的 "remove" 操作通过索引从 `metadata.properties` 数组中移除 `property` 对象。
原始 CycloneDX JSON BOM 文件:[test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"properties": [
{
"name": "Property 1",
"value": "Value 1"
},
{
"name": "Property 2",
"value": "Value 2"
}
]
}
}
```
应用以下 IETF RFC6902 JSON 补丁文件:[test/patch/cdx-patch-example-remove-metadata-property.json](test/patch/cdx-patch-example-remove-metadata-property.json):
```
[
{ "op": "remove", "path": "/metadata/properties/1" }
]
```
按如下方式调用 patch 命令:
```
./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-remove-metadata-property.json -q
```
`metadata.properties` 数组索引 `1` 处的 `property` 已被移除:
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"properties": [
{
"name": "Property 1",
"value": "Value 1"
}
]
}
}
```
##### 修补示例 7:"test" `property` 存在于 `metadata.properties` 数组中
此示例展示了补丁记录如何“测试”BOM 中的值或对象。该实用程序将确认“成功”(使用 `[INFO]` 日志消息);否则,该实用程序将退出并返回错误,并生成 `[ERROR]` 日志消息。
原始 CycloneDX JSON BOM 文件:[test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):
```
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2023-10-12T19:07:00Z",
"properties": [
{
"name": "Property 1",
"value": "Value 1"
},
{
"name": "Property 2",
"value": "Value 2"
}
]
}
}
```
应用以下 IETF RFC6902 JSON 补丁文件:[test/patch/cdx-patch-example-test-metadata-property.json](test/patch/cdx-patch-example-test-metadata-property.json):
```
[
{ "op": "test", "path": "/metadata/properties/1", "value":
{
"name": "Property 2",
"value": "Value 2"
}
}
]
```
按如下方式调用 patch 命令:
```
./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-test-metadata-property.json -q
```
由于在输入 BOM 中找到了 property 对象,因此会记录一条带 `success` 的信息性(即 `[INFO]`)消息:
```
[INFO] IETF RFC6902 test operation success. test record: {
"op": "test",
"path": "/metadata/properties/1",
"value": {
"name": "Property 2",
"value": "Value 2"
}
}
```
相反,如果我们[测试不同的 property](test/patch/cdx-patch-example-test-metadata-property-err.json) 对象:
```
[
{ "op": "test", "path": "/metadata/properties/1", "value":
{
"name": "Property 3",
"value": "Value 3"
}
}
]
```
该实用程序将返回错误(即 `[ERROR]`):
```
[ERROR] IETF RFC6902 test operation error. test record: {
"op": "test",
"path": "/metadata/properties/1",
"value": {
"name": "Property 3",
"value": "Value 3"
}
}
```
### 查询
此命令允许您对 JSON 格式的 SBOM 执行类似 SQL 的查询。目前,该命令可识别 `--select` 和 `--from` 以及 `--where` 过滤器。
#### 查询标志
##### 查询 `--from` 标志
`--from` 子句值应用于 JSON 文档对象模型,可以返回单个 JSON 对象或 JSON 对象数组作为结果。这由 schema 中声明的最后一个属性值的类型决定。
##### 查询 `--select` 标志
然后将 `--select` 子句应用于 `--from` 结果集,以仅返回指定的属性(名称及其值)。
##### 查询 `--where` 标志
如果结果集是数组,则可以通过对数组条目应用 `--where` 过滤器来减少它们,仅返回那些指定字段名与提供的正则表达式 匹配的条目。
**注意**:所有 `query` 命令结果都作为有效的 JSON 文档返回。这包括空结果集的 `null` 值。
#### 查询支持的格式
`query` 命令仅支持 JSON 输出。
- `json` (默认)
#### 查询结果排序
`query` 命令不支持格式化输出结果,因为总是返回 JSON 格式。
#### 查询示例
##### 示例:从 SBOM 中提取顶级 `component` 信息
此示例有效地从 SBOM 中提取了一阶包清单。
在此示例中,只需要 `--from` 子句来选择对象。省略了 `--select` 子句,这等效于使用“选择所有”通配符 `*`,它返回 `component` 对象中的所有字段和值。
```
./sbom-utility query -i test/cyclonedx/1.4/cdx-1-4-mature-example-1.json --from metadata.component
```
等效于使用通配符(根据您的 shell,可能需要用单引号或双引号括起来):
```
./sbom-utility query -i test/cyclonedx/1.4/cdx-1-4-mature-example-1.json --select '*' --from metadata.component -q
```
```
{
"name": "Example Application v10.0.4",
"bom-ref": "pkg:oci/example.com/product/application@10.0.4.0",
"description": "Example's Do-It-All application",
"externalReferences": [
{
"type": "website",
"url": "https://example.com/application"
}
],
"hashes": [
{
"alg": "SHA-1",
"content": "1111aaaa2222cccc3333dddd4444eeee5555ffff"
}
],
"licenses": [
{
"license": {
"id": "Apache-2.0"
}
}
],
...
```
##### 示例:提取 SBOM 的 `supplier`
在此示例中,`--from` 子句引用了顶级 `metadata.supplier` 对象。
```
./sbom-utility query -i test/cyclonedx/1.4/cdx-1-4-mature-example-1.json --from metadata.supplier -q
```
```
{
"contact": [
{
"email": "distribution@example.com"
}
],
"name": "Example Co. Distribution Dept.",
"url": [
"https://example.com/software/"
]
}
```
##### 示例:仅提取 SBOM 组件的 `name` 和 `version`
在此示例中,`--from` 子句引用了在顶级 `metadata` 对象下找到的单一 JSON 对象 `component`。然后它缩减生成的 JSON 对象,仅返回 `name` 和 `value` 字段及其在 `--select` 子句中请求的值。
```
./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 2 -q
```
结果,同时使用了 `--indent 2` 标志:
```
{
"name": "juice-shop",
"version": "11.1.2"
}
```
##### 示例:返回组件的 JSON 数组
在此示例中,`--from` 过滤器将返回整个 JSON components 数组。
```
./sbom-utility query -i test/cyclonedx/1.4/cdx-1-4-mature-example-1.json --from components -q
```
```
[
{
"bom-ref": "pkg:npm/sample@2.0.0",
"description": "Node.js Sampler package",
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"name": "sample",
"purl": "pkg:npm/sample@2.0.0",
"type": "library",
"version": "2.0.0"
},
{
"bom-ref": "pkg:npm/body-parser@1.19.0",
"description": "Node.js body parsing middleware",
"hashes": [
{
...
}
],
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"name": "body-parser",
"purl": "pkg:npm/body-parser@1.19.0",
"type": "library",
"version": "1.19.0"
}
]
```
**注意**:此示例的命令仅使用了 `--from` 标志,不需要提供 `--select '*'`,因为这是默认值。
##### 示例:使用指定值过滤结果条目
在此示例中,`--where` 过滤器将应用于一组 `properties` 结果,以仅包含与指定正则表达式匹配的条目。
```
./sbom-utility query -i test/cyclonedx/1.4/cdx-1-4-mature-example-1.json --from metadata.properties --where name=urn:example.com:classification -q
```
```
[
{
"name": "urn:example.com:classification",
"value": "This SBOM is Confidential Information. Do not distribute."
}
]
```
此外,您可以应用 `--select` 子句来简单地获取匹配条目的 `value`:
```
./sbom-utility query -i test/cyclonedx/1.4/cdx-1-4-mature-example-1.json --select value --from metadata.properties --where name=urn:example.com:classification -q
```
```
[
{
"value": "This SBOM is Confidential Information. Do not distribute."
}
]
```
### 组件
主要是,此命令用于使用 `component list` 提取、过滤和列出 CycloneDX BOM 组件数据。
#### 组件列表支持的格式
此命令支持带有以下任何值的 `--format` 标志:
- `txt`(默认)、`csv`、`md`
#### 组件列表标志
##### 组件列表 `--summary` 标志
在 `component list` 命令上使用 `--summary` 标志生成具有缩减列信息的汇总报告。
#### 组件列表示例
##### 示例:`component list`
此示例显示了显示所有列信息的组件列表。由于 CycloneDX 组件数据可能非常广泛,许多列仅指示组件`具有`更多可用数据,如果需要,可以使用 `query` 命令提取这些数据。
```
./sbom-utility component list -i test/cyclonedx/1.6/specification/valid-bom-1.6.json -q
```
```
bom-ref group type name version description copyright supplier-name supplier-url manufacturer-name manufacturer-url publisher purl swid-tag-id cpe mime-type scope number-hashes number-licenses has-pedigree has-evidence has-components has-release-notes has-model-card has-data has-tags has-signature
------- ----- ---- ---- ------- ----------- --------- ------------- ------------ ----------------- ---------------- --------- ---- ----------- --- --------- ----- ------------- --------------- ------------ ------------ -------------- ----------------- -------------- -------- -------- -------------
application Acme Application 9.1.1 swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1 0 0 false false false false false false false false
pkg:npm/acme/component@1.0.0 com.acme library tomcat-catalina 9.0.14 pkg:npm/acme/component@1.0.0 4 1 true false false false false false false false
org.example library mylibrary 1.0.0 Example, Inc. https://example.com Example-2, Inc. https://example.org required 0 0 true false false false false false false false
```
##### 示例:仅 `component list` 摘要
与上一个示例相同的 BOM 组件信息;但是,使用 summary 标志来减少列数据的数量。
```
./sbom-utility component list -i test/cyclonedx/1.6/specification/valid-bom-1.6.json --summary -q
```
```
bom-ref group type name version description copyright supplier-name supplier-url manufacturer-name manufacturer-url publisher purl swid-tag-id cpe number-hashes number-licenses
------- ----- ---- ---- ------- ----------- --------- ------------- ------------ ----------------- ---------------- --------- ---- ----------- --- ------------- ---------------
application Acme Application 9.1.1 swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1 0 0
pkg:npm/acme/component@1.0.0 com.acme library tomcat-catalina 9.0.14 pkg:npm/acme/component@1.0.0 4 1
org.example library mylibrary 1.0.0 Example, Inc. https://example.com Example-2, Inc. https://example.org 0 0
```
### 许可证
此命令用于聚合和汇总 SBOM 中包含的软件、硬件和数据许可证信息。它还根据当前策略文件(即 `license.json`)中定义的 SPDX 许可证标识符、许可证系列或逻辑许可证表达式得出的结论,显示资源的使用策略。
`license` 命令支持以下子命令:
- [list](#license-list-subcommand) - 列出或创建在输入 SBOM 中找到的许可证汇总报告。
- [带有 --summary 标志的 list](#license-list---summary-flag) - 由于完整的许可证信息可能非常庞大,因此摘要视图通常是最有用的。
- [policy](#license-policy-subcommand) - 按 SPDX 许可证 ID、系列名称和其他过滤器列出用户配置的许可证策略。
### License `list` 子命令
`list` 子命令生成 JSON 输出,其中包含在 BOM 输入文件中找到的 CycloneDX `LicenseChoice` 数据对象数组,但没有组件关联。`LicenseChoice` 数据通常可以使用注册的 SPDX ID、许可证表达式(SPDX ID 的)或许可证名称(不一定由 SPDX 注册)来提供许可证信息。许可证数据还可以包括用于确定许可证 SPDX ID 或名称的 base64 编码的许可证或法律文本。
#### 许可证列表支持的格式
此命令支持带有以下任何值的 `--format` 标志:
##### 不带 `--summary` 标志
输出将包含 CycloneDX `LicenseChoice 数据对象的规范 schema。
- `json`(默认)、`csv`、`md`
###### 示例 json 对象输出:
```
{
"license": {
"id": "MIT"
}
},
```
*可用于编辑或重写包含所有 `LicenseChoice` 数据摘要的 BOM。*
##### 带 `--summary` 标志
输出将包含来自 CycloneDX `LicenseChoice` 结构以及用户可自定义的许可证策略信息的简化的、扁平化的键值信息集(参见[许可证策略说明](#license-policy-notes))。
- `txt`(默认)、`csv`、`md`、`json`
###### 示例 json 对象输出:
```
{
"bom-location": "components",
"bom-ref": "pkg:lib/libraryA@1.0.0",
"license": "MIT",
"license-type": "id",
"resource-name": "Library A",
"usage-policy": "allow"
},
```
#### 许可证列表结果排序
- 基础 `license list` 子命令的结果不排序。
- 使用 `--summary` 标志:结果按许可证键(可以是许可证 `id` (SPDX ID)、`name` 或 `expression` 之一)升序排序。
#### 许可证列表标志
##### 许可证列表 `--summary` 标志
在 `license list` 命令上使用 `--summary` 标志生成 `txt`(默认)格式的汇总报告以及基于 `license.json` 声明的策略决定。
#### 许可证列表示例
##### 示例:许可证列表 JSON
此示例显示了描述上述三种许可证数据类型的 JSON 输出的几个条目:
```
./sbom-utility license list -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --format json -q
```
```
[
{
"license": {
"$comment": "by license `id",
"id": "MIT",
"name": "",
"url": ""
}
},
{
"license": {
"$comment": "by license `expression",
"id": "",
"name": "",
"url": ""
},
"expression": "Apache-2.0 AND (MIT OR GPL-2.0-only)"
},
{
"license": {
"$comment": "by license `name` with full license encoding",
"id": "",
"name": "Apache 2",
"text": {
"contentType": "text/plain",
"encoding": "base64",
"content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24 ..."
},
"url": "https://www.apache.org/licenses/LICENSE-2.0.txt"
}
},
...
]
```
###### 示例:许可证列表 `--summary`
此示例显示了使用 summary 标志的默认文本输出:
```
./sbom-utility license list -i test/cyclonedx/1.3/cdx-1-3-license-list.json --summary -q
```
```
usage-policy license-type license resource-name bom-ref bom-location
------------ ------------ ------- ------------- ------- ------------
needs-review id ADSL Foo service:example.com/myservices/foo services
needs-review name AGPL Library J pkg:lib/libraryJ@1.0.0 components
allow name Apache Library B pkg:lib/libraryB@1.0.0 components
allow id Apache-1.0 Library E pkg:lib/libraryE@1.0.0 components
allow id Apache-2.0 N/A N/A metadata.licenses
allow id Apache-2.0 Library A pkg:lib/libraryA@1.0.0 components
allow id Apache-2.0 Library F pkg:lib/libraryF@1.0.0 components
allow expression Apache-2.0 AND (MIT OR BSD-2-Clause) Library B pkg:lib/libraryB@1.0.0 components
allow name BSD Library J pkg:lib/libraryJ@1.0.0 components
deny name CC-BY-NC Library G pkg:lib/libraryG@1.0.0 components
needs-review name GPL Library H pkg:lib/libraryH@1.0.0 components
needs-review id GPL-2.0-only Library C pkg:lib/libraryC@1.0.0 components
needs-review id GPL-3.0-only Library D pkg:lib/libraryD@1.0.0 components
allow id MIT ACME Application pkg:app/sample@1.0.0 metadata.component
allow id MIT Library A pkg:lib/libraryA@1.0.0 components
UNDEFINED invalid NOASSERTION Library NoLicense pkg:lib/libraryNoLicense@1.0.0 components
UNDEFINED invalid NOASSERTION Bar service:example.com/myservices/bar services
needs-review name UFL ACME Application pkg:app/sample@1.0.0 metadata.component
```
- **注意**
- **使用策略**列值派生自 `license.json` 策略配置文件。
- `usage policy` 值为 `UNDEFINED` 表示 `license.json` 未提供与 SBOM 中声明的许可证(`id` 或 `name`)匹配的条目。
- **许可证表达式**(例如,`(MIT or GPL-2.0)`)如果其中一个项解析为 `UNDEFINED`,而另一个项具有具体策略,则对于 `OR` 表达式将解析为“乐观”策略,对于 `AND` 表达式将解析为“悲观”策略。此外,将发出有关此解析的警告。
###### 示例:带有 `--where` 过滤器的许可证列表摘要
可以使用报告中的列名通过 `--where` 标志过滤列表命令结果。这些包括 `usage-policy`、`license-type`、`license`、`resource-name`、`bom-ref` 和 `bom-location`。
以下示例显示了使用 `license-type` 列过滤组件许可证,其中许可证被描述为 `name` 值:
```
./sbom-utility license list -i test/cyclonedx/1.3/cdx-1-3-license-list.json --summary --where license-type=name -q
```
```
usage-policy license-type license resource-name bom-ref bom-location
------------ ------------ ------- ------------- ------- ------------
needs-review name AGPL Library J pkg:lib/libraryJ@1.0.0 components
allow name Apache Library B pkg:lib/libraryB@1.0.0 components
allow name BSD Library J pkg:lib/libraryJ@1.0.0 components
deny name CC-BY-NC Library G pkg:lib/libraryG@1.0.0 components
needs-review name GPL Library H pkg:lib/libraryH@1.0.0 components
needs-review name UFL ACME Application pkg:app/sample@1.0.0 metadata.component
```
在另一个示例中,列表按 `usage-policy` 过滤,其中值为 `needs-review`:
```
./sbom-utility license list -i test/cyclonedx/1.3/cdx-1-3-license-list.json --summary --where usage-policy=needs-review -q
```
```
usage-policy license-type license resource-name bom-ref bom-location
------------ ------------ ------- ------------- ------- ------------
needs-review id ADSL Foo service:example.com/myservices/foo services
needs-review name AGPL Library J pkg:lib/libraryJ@1.0.0 components
needs-review name GPL Library H pkg:lib/libraryH@1.0.0 components
needs-review id GPL-2.0-only Library C pkg:lib/libraryC@1.0.0 components
needs-review id GPL-3.0-only Library D pkg:lib/libraryD@1.0.0 components
needs-review name UFL ACME Application pkg:app/sample@1.0.0 metadata.component
```
### License `policy` 子命令
要查看包含当前策略文件(即 [`license.json`](https://github.com/CycloneDX/sbom-utility/blob/main/license.json))内容的报告列表,该文件包含按 SPDX ID 和许可证系列编码的已知软件和数据许可证以及可配置的使用策略(即 `"allow"`、`"deny"` 或 `"needs-review"`)。
#### 许可证策略支持的格式
此命令支持带有以下任何值的 `--format` 标志:
- `txt`(默认)、`csv`、`md`
#### 许可证策略结果排序
- 结果按许可证策略 `family` 排序。
#### 许可证策略标志
##### list `--summary` 标志
在 `license policy list` 命令上使用 `--summary` 标志生成具有缩减列数据集的汇总报告(即它仅包括以下列:`usage-policy`、`family`、`id`、`name`、`oci` (已批准)、`fsf` (已批准)、`deprecated` 和 SPDX `reference` URL)。
##### list `--wrap` 标志
使用 `--wrap` 标志切换许可证策略报告(仅限 `txt` 格式)输出中列内文本的换行,使用值 `true` 或 `false`。默认值为 `false`。
#### 许可证策略示例
##### 示例:许可证策略
```
./sbom-utility license policy -q
```
```
usage-policy family id name osi fsf deprecated reference aliases annotations notes
------------ ------ -- ---- --- --- ---------- --------- ------- ----------- -----
allow 0BSD 0BSD BSD Zero Clause License true false false https://spdx.org/licenses/0BSD.html Free Public License 1.0.0 APPROVED none
needs-review ADSL ADSL Amazon Digital Services License false false false https://spdx.org/licenses/ADSL.html none NEEDS-APPROVAL none
allow AFL AFL-3.0 Academic Free License v3.0 true true false https://spdx.org/licenses/AFL-3.0.html none APPROVED none
needs-review AGPL AGPL-1.0 Affero General Public License v1.0 false false true https://spdx.org/licenses/AGPL-1.0.html none NEEDS-APPROVAL,AGPL-WARNING none
allow Adobe Adobe-2006 Adobe Systems Incorporated CLA false false false https://spdx.org/licenses/Adobe-2006.html none APPROVED none
allow Apache Apache-2.0 Apache License 2.0 true true false https://spdx.org/licenses/Apache-2.0.html Apache License, Version 2.0 APPROVED none
allow Artistic Artistic-1.0 Artistic License 1.0 true false false https://spdx.org/licenses/Artistic-1.0.html none APPROVED none
...
```
###### 示例:带有 `--summary` 标志的策略
我们还可以应用 `--summary` 标志来获取缩减的列集,其中仅包括 `usage-policy` 以及基本的 SPDX 许可证信息(例如,没有注释或说明)。
```
./sbom-utility license policy --summary -q
```
```
usage-policy family id name osi fsf deprecated reference
------------ ------ -- ---- --- --- ---------- ---------
allow 0BSD 0BSD BSD Zero Clause License true false false https://spdx.org/licenses/0BSD.html
needs-review ADSL ADSL Amazon Digital Services License false false false https://spdx.org/licenses/ADSL.html
allow AFL AFL-3.0 Academic Free License v3.0 true true false https://spdx.org/licenses/AFL-3.0.html
needs-review AGPL AGPL-1.0 Affero General Public License v1.0 false false true https://spdx.org/licenses/AGPL-1.0.html
allow Adobe Adobe-2006 Adobe Systems Incorporated CLA false false false https://spdx.org/licenses/Adobe-2006.html
allow Apache Apache-2.0 Apache License 2.0 true true false https://spdx.org/licenses/Apache-2.0.html
allow Artistic Artistic-1.0 Artistic License 1.0 true true false https://spdx.org/licenses/Artistic-2.0.html
...
```
###### 示例:带有 `--where` 过滤器的策略
以下示例显示了使用 `id` 列过滤许可证策略:
```
./sbom-utility license policy --where id=Apache -q
```
```
usage-policy family id name osi fsf deprecated reference aliases annotations notes
------------ ------ -- ---- --- --- ---------- --------- ------- ----------- -----
allow Apache Apache-1.0 Apache v1.0 false true false https://spdx.org/licenses/Apache-1.0.html none APPROVED none
allow Apache Apache-1.1 Apache v1.1 true true false https://spdx.org/licenses/Apache-1.1.html none APPROVED Superseded by Apache-2.0
allow Apache Apache-2.0 Apache License 2.0 true true false https://spdx.org/licenses/Apache-2.0.html Apache License APPROVED none
```
###### 示例:带有 `--wrap` 标志的策略
```
./sbom-utility license policy --wrap=true -q
```
```
usage-policy family id name osi fsf deprecated reference aliases annotations notes
------------ ------ -- ---- --- --- ---------- --------- ------- ----------- -----
allow 0BSD 0BSD BSD Zero Clause Lice (20/23) true false false https://spdx.org/licenses/0BSD.html Free Public License 1.0. (24/25) APPROVED none
needs-review ADSL ADSL Amazon Digital Servi (20/31) false false false https://spdx.org/licenses/ADSL.html NEEDS-APPROVAL none
allow AFL AFL-3.0 Academic Free Licens (20/26) true true false https://spdx.org/licenses/AFL-3.0.ht (36/38) APPROVED none
needs-review AGPL AGPL-1.0 Affero General Publi (20/34) false false true https://spdx.org/licenses/AGPL-1.0.h (36/39) NEEDS-APPROVAL none
AGPL-WARNING
needs-review APSL APSL-2.0 Apple Public Source (20/31) true true false https://spdx.org/licenses/APSL-2.0.h (36/39) NEEDS-APPROVAL none
allow Adobe Adobe-2006 Adobe Systems Incorp (20/56) false false false https://spdx.org/licenses/Adobe-2006 (36/41) APPROVED none
allow Apache Apache-2.0 Apache License 2.0 true true false https://spdx.org/licenses/Apache-2.0 (36/41) Apache License, Version (24/27) APPROVED none
allow Artistic Artistic-2.0 Artistic License 2.0 true true false https://spdx.org/licenses/Artistic-2 (36/43) APPROVED none
...
```
#### 许可证策略说明
- 目前,用于派生 `usage-policy` 数据的默认 `license.json` 文件不包含整个 SPDX 3.2 许可证模板集的条目。
- 问题 [12](https://github.com/CycloneDX/sbom-utility/issues/12) 处于开放状态以增加对等性。
- 注释(标签)和说明可以在 `license.json` 文件中定义,并为每个许可证条目分配一个或多个。
- 为了向后兼容,`--where` 过滤器支持键 `spdx-id` 作为 `id` 的别名。
### 资源
`resource` 命令旨在根据作为 [OWASP 软件组件验证标准 (SCVS)](https://owasp.org/www-project-software-component-verification-standard/) 一部分开发的未来成熟度模型,检查 SBOM 中的各种资源类型及其信息。在 SCVS 模型中,“资源”是软件(组件)、服务、机器学习 (ML) 模型、数据、硬件、工具等的父分类。
主要是,通过调用 `resource list`,该命令用于按类型生成包含在 CycloneDX SBOM 中的资源列表。
#### 资源支持的输出格式
此命令支持带有以下任何值的 `--format` 标志:
- `txt`(默认)、`csv`、`md`
#### 资源结果排序
目前,所有 `resource list` 命令结果首先按资源 `type` 排序,然后按资源 `name`(必填字段)排序。
#### 资源示例
#### 示例:资源列表
```
./sbom-utility resource list -i test/cyclonedx/1.3/cdx-1-3-resource-list.json -q
```
```
bom-ref resource-type group name version description
------- ------------- ----- ---- ------- -----------
pkg:app/sample@1.0.0 component ACME Application 2.0.0 ACME sample application
pkg:lib/libraryA@1.0.0 component Library A 1.0.0 Library A description
pkg:lib/libraryC@1.0.0 component Library C 1.0.0 Library C description.
pkg:lib/libraryF@1.0.0 component Library F 1.0.0 Library F description.
pkg:lib/libraryG@1.0.0 component Library G 1.0.0 Library G description.
pkg:lib/libraryH@1.0.0 component Library H 1.0.0 Library H description.
pkg:lib/libraryNoLicense@1.0.0 component Library NoLicense 1.0.0 Library "NoLicense" description.
pkg:lib/libraryB@1.0.0 component blue Library B 1.0.0 Library B description.
pkg:lib/libraryE@1.0.0 component blue Library E 1.0.0 Library E description.
pkg:lib/libraryD@1.0.0 component green Library D 1.0.0 Library D description.
pkg:lib/libraryJ@1.0.0 component green Library J 1.0.0 Library J description.
service:example.com/myservices/bar service Bar Bar service
service:example.com/myservices/foo service Foo Foo service
```
##### 示例:使用 `--type service` 的资源列表
此示例使用 `type` 标志指定 `service`。另一个有效类型是 `component`。未来版本的 CycloneDX schema 将包括更多资源类型,例如“ml”(机器学习)或“tool”。
```
./sbom-utility resource list -i test/cyclonedx/1.3/cdx-1-3-resource-list.json --type service -q
```
```
resource-type group name version description bom-ref
------------- ----- ---- ------- ----------- -------
service Bar Bar service service:example.com/myservices/bar
service Foo Foo service service:example.com/myservices/foo
```
**注意** 结果等效于使用 `--where` 过滤器:
```
./sbom-utility resource list -i test/cyclonedx/1.3/cdx-1-3-resource-list.json --where "resource-type=service" -q
```
##### 示例:带有 `name` 正则表达式匹配的列表
此示例在 `name` 字段上使用 `where` 过滤器。在这种情况下,我们为 `name` 过滤器提供了一个精确的“startswith”正则表达式。
```
./sbom-utility resource list -i test/cyclonedx/1.3/cdx-1-3-resource-list.json --where "name=Library A" -q
```
```
resource-type group name version description bom-ref
------------- ----- ---- ------- ----------- -------
component Library A 1.0.0 Library A description pkg:lib/libraryA@1.0.0
```
### Schema
您可以使用 `schema` 命令验证哪些格式、schema、版本和变体可用于验证。
- **注意**:如果省略,`schema` 命令将默认为 `list` 子命令。
#### Schema 支持的输出格式
此命令支持带有以下任何值的 `--format` 标志:
- `txt`(默认)、`csv`、`md`
#### Schema 结果排序
- 格式化结果按 `format`(升序)、`version`(降序)和 `schema`(降序)排序
#### Schema 示例
##### 示例:schema 列表
```
./sbom-utility schema list -q
```
```
name variant format version file url
---- ------- ------ ------- ---- ---
CycloneDX v1.7 (latest) CycloneDX 1.7 schema/cyclonedx/1.7/bom-1.7.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.7.schema.json
CycloneDX v1.6.1(latest) CycloneDX 1.6 schema/cyclonedx/1.6/bom-1.6.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json
CycloneDX v1.5 (latest) CycloneDX 1.5 schema/cyclonedx/1.5/bom-1.5.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.5.schema.json
CycloneDX v1.4 (latest) CycloneDX 1.4 schema/cyclonedx/1.4/bom-1.4.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.4.schema.json
CycloneDX v1.4 custom CycloneDX 1.4 schema/test/bom-1.4-custom.schema.json
CycloneDX v1.3 (latest) CycloneDX 1.3 schema/cyclonedx/1.3/bom-1.3.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.3.schema.json
CycloneDX v1.3 custom CycloneDX 1.3 schema/test/bom-1.3-custom.schema.json
CycloneDX v1.3 strict CycloneDX 1.3 schema/cyclonedx/1.3/bom-1.3-strict.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.3-strict.schema.json
CycloneDX v1.2 (latest) CycloneDX 1.2 schema/cyclonedx/1.2/bom-1.2.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.2.schema.json
CycloneDX v1.2 strict CycloneDX 1.2 schema/cyclonedx/1.2/bom-1.2-strict.schema.json https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.2-strict.schema.json
SPDX v2.3 (latest) SPDX SPDX-2.3 schema/spdx/2.3/spdx-schema.json https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3/schemas/spdx-schema.json
SPDX v2.3.1 development SPDX SPDX-2.3 schema/spdx/2.3.1/spdx-schema.json https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3.1/schemas/spdx-schema.json
SPDX v2.2.2 (latest) SPDX SPDX-2.2 schema/spdx/2.2.2/spdx-schema.json https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.2/schemas/spdx-schema.json
SPDX v2.2.1 2.2.1 SPDX SPDX-2.2 schema/spdx/2.2.1/spdx-schema.json https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json
```
#### 添加 schema
可以通过添加新的 schema 条目将新的或“自定义” schema 的条目添加到 `config.json` 文件中,然后需要使用 `--config-schema` 标志在命令行上传递该文件。
这些新的 schema 条目将告诉 schema 加载器在何处可以本地找到 JSON schema 文件(相对于实用程序的可执行文件)。
有关详细信息,请参见“[添加新的 SBOM 格式、schema 版本和变体](#adding-new-sbom-formats-schema-versions-and-variants)”部分。
#### 嵌入 schema
如果您希望将新 schema *嵌入到可执行文件中*,只需按照格式和基于版本的目录结构将其添加到项目的 `resources` 子目录中。
### 漏洞
此命令将从具有“vulnerabilities”列表的 SBOM 或 CycloneDX 格式的独立 VEX 中提取基本漏洞报告数据。它包括通过将正则表达式应用于任何命名列数据来过滤报告数据的能力。
#### 漏洞支持的输出格式
在命令上使用 `--format` 标志选择一种支持的输出格式:
- txt(默认)、csv、md
#### 漏洞结果排序
- `txt`、`csv` 和 `md` 格式化结果按 vulnerability `id`(降序)然后按 `created` 日期(降序)排序。
- `json` 结果不排序
#### 漏洞示例
##### 示例:漏洞列表
`list` 子命令提供了大多数顶级漏洞字段的完整视图。
```
./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json -q
```
```
id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description
-- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- -----------
CVE-2023-42004 502 CVSSv31: 7.5 (high) NVD https://nvd.nist.gov/vuln/detail/CVE-2023-42004 2023-10-02 2023-10-02 2023-10-02 UNDEFINED UNDEFINED In FasterXML jackson-databind before 2.13.4, resource exhaustion can occur because of a lack of a check in BeanDeserializer._deserializeFromArray to prevent use of deeply nested arrays. An application is vulnerable only with certain customized choices for deserialization.
CVE-2023-42003 502 CVSSv31: 7.5 (high) NVD https://nvd.nist.gov/vuln/detail/CVE-2023-42003 2023-10-02 2023-10-02 2023-10-02 UNDEFINED UNDEFINED In FasterXML jackson-databind before 2.14.0-rc1, resource exhaustion can occur because of a lack of a check in primitive value deserializers to avoid deep wrapper array nesting, when the UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled. Additional fix version in 2.13.4.1 and 2.12.17.1
CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity.
```
###### 示例:漏洞列表摘要
此示例显示了使用 `--summary` 标志的默认文本输出:
```
./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --summary -q
```
```
id cvss-severity source-name published description
-- ------------- ----------- --------- -----------
CVE-2023-42004 CVSSv31: 7.5 (high) NVD 2023-10-02 In FasterXML jackson-databind before 2.13.4, resource exhaustion can occur because of a lack of a check in BeanDeserializer._deserializeFromArray to prevent use of deeply nested arrays. An application is vulnerable only with certain customized choices for deserialization.
CVE-2023-42003 CVSSv31: 7.5 (high) NVD 2023-10-02 In FasterXML jackson-databind before 2.14.0-rc1, resource exhaustion can occur because of a lack of a check in primitive value deserializers to avoid deep wrapper array nesting, when the UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled. Additional fix version in 2.13.4.1 and 2.12.17.1
CVE-2020-25649 CVSSv31: 7.5 (high) NVD 2020-12-03 com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity.
```
##### 示例:带有带有 `description` 键的 `--where` 过滤器的漏洞列表
```
./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --where description=XXE -q
```
```
id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description
-- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- -----------
CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity.
```
##### 示例:带有带有 `analysis-state` 键的 `--where` 过滤器的漏洞列表
```
./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --where analysis-state=not_affected -q
```
```
id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description
-- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- -----------
CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity.
```
### 补全
此命令将为此实用程序生成针对各种受支持的 shell 自定义的命令行补全脚本。
可以按如下方式调用补全命令:
```
./sbom_utility completion [shell]
```
其中 `shell` 的有效值为:
- bash
- fish
- powershell
- zsh
### 帮助
该实用程序支持根命令以及任何受支持命令的 `help` 命令
例如,列出顶级(根命令)帮助,其中列出了受支持的“可用命令”:
```
./sbom-utility help
```
特定的命令级帮助列表也可用。例如,您可以访问 `validate` 命令的帮助:
```
./sbom-utility help validate
```
## 实验性命令
本节包含*实验性*命令,这些命令将在经过社区两个或更多点版本的审查后被提升。
### Diff
此*实验性*命令将比较两个*相似*的 BOM,并以 JSON(diff-patch 格式)或文本形式返回增量(或“差异”)。此功能是“JSON 感知”的,并且基于用于报告 `git commit` 之间文件差异的代码的祖先。
##### 建议
- *即使对于**应该**相似的 BOM,也建议使用 **[trim](#trim)** 命令移除在 BOM 中一代代改变的数据,或者通常是专有的数据,例如:**bom-ref**、**hashes**、**timestamp**(s)、**properties** 等。*
- *此外,建议您也 `--normalize` 修剪后的输出数据,以更好地保证字段和数组数据的排序。*
##### 注意事项
- 此命令正在进行分析和测试,这暴露了依赖的 diff-patch 包中关于“移动”对象的一些潜在问题,这些问题可能无法修复且没有替代方案。
- *具体来说,在 JSON 的情况下,为“移动”对象分配“相似性”分数的方式似乎存在缺陷。*
- *此外,一些底层代码依赖于不保留键排序的 Go map。*
#### Diff 支持的输出格式
在命令上使用 `--format` 标志选择一种支持的输出格式:
- txt(默认)、json
#### Diff 示例
##### 示例:添加、删除和修改
```
./sbom-utility diff -i test/diff/json-array-order-change-with-add-and-delete-base.json -r test/diff/json-array-order-change-with-add-and-delete-delta.json --format txt --colorize=true -q
```
```
{
"licenses": [
0: {
"license": {
- "id": "Apache-1.0"
+ "id": "GPL-2.0"
}
},
-+ 2=>1: {
-+ "license": {
-+ "id": "GPL-3.0-only"
-+ }
-+ },
2: {
"license": {
"id": "GPL-3.0-only"
}
},
3: {
"license": {
"id": "MIT"
}
}
]
}
```
## 贡献
欢迎在 Apache 2.0 许可证下做出贡献。在以下方面需要帮助:
- [TODO 列表](#todo-list)
- [优先功能](#priority-features)
#### TODO 列表
整个代码包含标签“**TODO**”,并带有在编写基础功能时构想到的功能或改进事项的注释。其中大多数没有为它们开启活跃的 issue。
随意使用 “grep” 搜索 “TODO” 标签,开启 issue 和/或提交 draft PR。
#### 优先功能
一个专门的功能“TODO”临时列表,旨在使工具更易于访问、可扩展和有用,特别是围绕“核心”命令(如验证)。
- **Merge 命令** 支持合并两个(均已验证的)SBOM,具有去重和可配置性。请注意,在合并之前需要某种规范化方法。
- **远程 Schema 加载** 支持使用从已知的、可信来源位置(例如,SPDX、CycloneDX 规范 schema 的发布)远程托管(可通过网络)的 SBOM schema 文件。请注意,配置文件中每个条目都有一个现有的 `url` 字段可用于此目的。
- **--orderby** 支持通过比较指定字段键中的值来排序查询结果集。
- **license.json** 文档化许可证策略配置 JSON schema 结构,以及如何添加与 CycloneDX `LicenseChoice` 对象(针对具有 SPDX ID 和不具有 SPDX ID 的条目)相关的条目。
- **license.json** 为 v3.21 中列出的所有 SPDX 许可证添加条目。
- 参见 issue:https://github.com/CycloneDX/sbom-utility/issues/12
- **Go 库** 用生成维护版本的替代品替换 `go-prettyjson`、`go-multimap` 库。
## 设计考量
### 内存安全
该实用程序本身是用 `Go` 编写的,以利用语言内置的类型强制和内存安全功能,及其为范围广泛的目标平台和架构编译的能力。
### 一致的输出
该实用程序还旨在生成一致的输出格式(例如,JSON)并一致地处理退出代码,以使其立即作为独立的实用程序或作为自动化持续集成 (CI) 工具链的一部分用于下游使用或检查。
### 安全和完整性重点
计划推出更多命令和报告,优先考虑的用例能够更深入地洞察和分析 SBOM 中捕获的法律、安全和合规数据,例如组件**来源**和**签名**(例如,通过哈希或指纹验证资源身份)。
此外,预期将包含围绕 BOM 组件的**持续集成和交付 (CI/CD)** 或“构建完整性”信息,作为 CycloneDX Formulation 工作的一部分,这将需要用于工作流洞察的功能。
### 功能优先级
该实用程序还优先考虑帮助深入了解 BOM 内容以搜索和报告缺失(即完整性)或特定数据要求(例如,组织或客户特定要求)的命令。
通常,这些优先命令的目标是支持 CycloneDX 社区确定的许多主要 BOM 用例的数据验证(参见 https://cyclonedx.org/use-cases/)。功能开发侧重于那些验证清单(资源身份)、法律合规性(例如,许可证)和安全分析(例如,漏洞)的用例,这些是任何 SBOM 的基础。
### 支持所有 BOM 格式
未来,我们设想支持其他类型的 BOM(例如,硬件 (HBOM)、机器学习 (MLBOM) 等),每种类型再次具有不同的数据要求和成熟度级别,这将增加对领域特定验证的需求。具体来说,该实用程序打算支持 [OWASP 软件组件验证标准 (SCVS)](https://owasp.org/www-project-software-component-verification-standard/) 的工作,该标准正在定义 BOM 成熟度模型 (BMM)。
## 开发
本节包含以下面向开发的主题:
- [前置条件](#prerequisites)
- [构建](#building)
- [从源代码运行](#running-from-source)
- [调试](#debugging)
- [使用 VSCode](#vscode)
- [添加新的 SBOM 格式、schema 版本和变体](#adding-new-sbom-formats-schema-versions-and-variants)
### 前置条件
- Go v1.20.1 或更高版本:参见 [https://go.dev/doc/install](https://go.dev/doc/install)
- `git` 客户端:参见 [https://git-scm.com/downloads](https://git-scm.com/downloads)
### 构建
要构建与您的本地计算机架构兼容的实用程序可执行文件,请使用项目 `Makefile` 中的 `build` 目标:
```
cd sbom-utility/
make build
```
这将在项目的 `release` 目录中生成一个名为 `sbom-utility` 且版本设置为 `latest` 的二进制文件。
```
$ ls
-rwxr-xr-x 1 User1 staff 11501122 Jan 24 08:29 sbom-utility
```
```
$ ./sbom-utility version
Welcome to the sbom-utility! Version `latest` (sbom-utility) (darwin/arm64)
```
**注意** 使用 `make build` 创建的二进制文件将适用于本地系统的操作系统和架构(即 `GOOS`、`GOARCH`)。这实际上将与在同一本地系统上运行时使用 `uname -s -m` unix 命令报告的内容相匹配。
如果您希望为 `GOOS` 和 `GOARCH` 值的所有受支持组合构建二进制文件,请使用 `release` 目标(即 `make release`),这将在 `release` 目录下生成名为 `sbom-utility-${GOOS}-${GOARCH}` 形式的二进制文件(例如,`sbom-utility-darwin-amd64`)。
### 从源代码运行
开发人员可以使用 `go run main.go` 在其本地分支中运行当前的源代码。例如:
```
go run main.go validate -i test/cyclonedx/1.4/cdx-1-4-mature-example-1.json
```
### 调试
#### VSCode
此项目是使用 VSCode 开发的,可以作为项目无缝加载。
##### 调试全局变量
为了在调试特定配置时查看全局变量,您可以在 `launch.json` 配置文件中为其添加 `"showGlobalVariables": true`:
```
{
"showGlobalVariables": true,
"name": "Test name",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "main.go",
"args": ["validate", "-i", "test/cyclonedx/1.3/cdx-1-3-min-required.json","-t"]
},
```
或将其全局添加到 `settings.json` 文件中:
1. 使用 `Command-Shift-P` 打开 `settings.json`
2. 选择“Preferences: Open Settings (JSON)”
3. 在顶层添加以下块:
```
"go.delveConfig": {
"showGlobalVariables": true
},
```
**注意**:*`showGlobalVariables` 设置最近在 VSCode 中作为默认设置被禁用,这是由于 Windows 下的性能(加载)问题而采取的权宜之计。*
### 添加新的 SBOM 格式、schema 版本和变体
该实用程序使用 [`config.json`](./config.json) 文件(默认的嵌入版本或使用 `--config-schema` 标志在命令行上提供的等效文件)来查找支持的格式及其关联的版本化 JSON schema 文件。要添加另一种 SBOM 格式,只需在文档的 `format` 数组中添加另一个条目:
```
{
"canonicalName": "SPDX",
"propertyKeyFormat": "SPDXID",
"propertyKeyVersion": "spdxVersion",
"propertyValueFormat": "SPDXRef-DOCUMENT",
"schemas": [
{
...
}
]
...
}
```
`propertyKeyFormat` 的值应该是 JSON SBOM 本身中出现的键字段的确切名称,可用于确认它确实是格式匹配。此外,应在 `propertyValueFormat` 值中声明要为该键匹配的相应值。
字段 `canonicalName`、`propertyKeyFormat`、propertyKeyVersion` 和 `propertyValueFormat` 是必需的。`format` 对象**必须**至少有一个有效的 `schema` 对象。
规范 SPDX v2.3(默认,无变体)schema 的示例 `schema` 对象如下所示:
```
{
{
"version": "SPDX-2.3",
"variant": "",
"name": "SPDX v2.3",
"file": "schema/spdx/2.3/spdx-schema.json",
"development": "https://github.com/spdx/spdx-spec/blob/development/v2.3/schemas/spdx-schema.json",
"url": "https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3/schemas/spdx-schema.json",
"default": true
},
},
```
- 在项目中 `resources/schema///` 结构下本地添加 JSON schema 文件的副本。
- **注意** 如果 schema 位于 `resources` 目录下,当使用 `go build`(包括使用项目的 `Makefile`)构建时,它将自动嵌入到可执行二进制文件中。
- 确保对于给定格式和版本,**只有一个** `schema` 对象条目的 `latest` 值设置为 `true`。当被验证的 SBOM 没有明确声明版本,**或者**与 `--force latest` 标志一起使用时,将使用此最新 schema。
- 如果您有一个用于验证的 schema 自定义或“变体”版本(具有相同的格式和版本值)(例如,具有附加要求或用于测试未发布版本的 `corporate` 或 `staging` 版本),您可以创建一个具有与另一个条目相同 `version` 的条目,但同时声明其 `variant` 名称 *(非空值)*。可以在命令行中使用 `--variant ` 标志提供此值,以强制验证器使用它而不是默认值 *(空变体值)*。
## 测试
本节描述了测试实现和调用以及示例,包括:
- [编写 Go 测试文件](#authoring-go-test-files)
- [运行测试](#running-tests)
### 编写 Go 测试文件
内置的 `go test` 命令将执行文件名符合以下模式的所有功能测试:`_test.go`。这些文件从其各自的 `.go` 源代码文件所在的同一目录(包)中执行,并将其设置为“工作目录”。
*例如,* `validate_test.go` 文件中的测试是从 `cmd` 子目录执行的。
这通常是一个问题,因为实际的测试 SBOM JSON 测试文件位于相对于项目根目录高一级的位置,并且“工作目录”无法找到它们。为了纠正这一点,测试工作目录会自动更改为 `root_test.go` 中的 `TestMain` 例程中所有测试的工作目录。
### 运行测试
`Makefile` 包含一个 `test` 目标,方便使用 `go test` 运行所有子目录中找到的所有测试:
```
make test
```
#### 运行单个包的测试
`test_cmd` 目标将仅运行在 `cmd` 包中找到的测试:
```
make test_cmd
```
`test_schema` 目标将仅运行在 `schema` 包中找到的测试:
```
make test_schema
```
#### 使用 `go test`
示例:运行 `cmd` 包中的所有测试:
```
go test github.com/CycloneDX/sbom-utility/cmd -v
```
示例:运行 `schema` 包中的所有测试:
```
go test github.com/CycloneDX/sbom-utility/schema -v
```
#### 在静默模式下运行测试
在“静默”模式下运行以不查看错误测试输出:
```
go test github.com/CycloneDX/sbom-utility/cmd -v --quiet
```
运行 `cmd` 包中的单个测试:
```
go test github.com/CycloneDX/sbom-utility/cmd -v -run TestValidateCdx14MinRequiredBasic
```
#### 调试 `go test`
只需将标志 `--args --trace` 或 `--args --debug` 附加到您的 `go test` 命令,为您指定的测试启用跟踪或调试输出:
```
go test github.com/CycloneDX/sbom-utility/cmd -v --args --trace
```
**注意**:您应该始终使用 `go test` 的 `--args` 标志,因为这将确保不与 `go test` 内置标志发生冲突,`--trace` 标志就是这种情况。
#### 消除无关的测试输出
有几个测试仍会按设计输出错误和警告消息。如果这些消息令人分心,您可以使用 `--quiet` 标志将其关闭。
```
go test github.com/CycloneDX/sbom-utility/cmd -v --quiet
```
## 发布
### GitHub
为了启动发布工作流,只需转到仓库的发布页面:
- [https://github.com/CycloneDX/sbom-utility/releases](https://github.com/CycloneDX/sbom-utility/releases)
然后点击 `Draft a new release` 按钮。按照说明创建新的版本标签,提供适当的发布标题和描述,然后 `publish` 该发布。GitHub 发布工作流将被自动触发。
### 本地
对于本地开发,您可以选择使用 `Makefile` 指令 `release` 在您的机器上进行发布:
```
make release
```
所有构建完成后,可以验证二进制文件和配置文件是否位于目标 `release` 目录中:
```
ls release
```
```
total 131680
drwxr-xr-x 8 User1 staff 256 Jan 27 14:43 .
drwxr-xr-x 27 User1 staff 864 Jan 27 14:43 ..
-rw-r--r-- 1 User1 staff 7121 Jan 27 14:43 config.json
-rw-r--r-- 1 User1 staff 1346 Jan 27 14:43 custom.json
-rw-r--r-- 1 User1 staff 62532 Jan 27 14:43 license.json
-rwxr-xr-x 1 User1 staff 11336640 Jan 27 14:43 sbom-utility-darwin-amd64
-rwxr-xr-x 1 User1 staff 11146770 Jan 27 14:43 sbom-utility-darwin-arm64
-rwxr-xr-x 1 User1 staff 11495647 Jan 27 14:43 sbom-utility-linux-amd64
-rwxr-xr-x 1 User1 staff 11076025 Jan 27 14:43 sbom-utility-linux-arm64
-rwxr-xr-x 1 User1 staff 11416576 Jan 27 14:43 sbom-utility-windows-amd64
-rwxr-xr-x 1 User1 staff 10934272 Jan 27 14:43 sbom-utility-windows-arm64
...
```
- *还请注意,常见的 `*.json` 配置文件也会被复制到 `release` 目录中。*
### 版本控制
要生成发布版本,您可以设置以下标志并直接调用 `go build`:
```
BINARY=sbom-utility
VERSION=latest
LDFLAGS=-ldflags "-X main.Version=${VERSION} -X main.Binary=${BINARY}"
$ go build ${LDFLAGS} -o ${BINARY}
```
**TODO**:更新 `Makefile's` 的 `release` 目标,以有条件地从环境变量值中提取发布版本,并且仅在运行时构建环境中未找到时才使用硬编码值作为默认值。
## BOM 参考
### 软件物料清单 (SBOM)
- [NTIA - SBOM 最低要求](https://www.ntia.doc.gov/blog/2021/ntia-releases-minimum-elements-software-bill-materials)
- [CISA - 软件物料清单 (SBOM)](https://www.cisa.gov/sbom)
- [FOSSA - 软件物料清单:格式、用例和工具](https://fossa.com/blog/software-bill-of-materials-formats-use-cases-tools/)
#### 指南
- [FOSSA](https://fossa.com/)
- *["CycloneDX 实用指南"](https://fossa.com/cyclonedx)*
### CycloneDX
- [CycloneDX 规范概述](https://cyclonedx.org/specification/overview/)
- GitHub: https://github.com/CycloneDX
- 规范(按分支):https://github.com/CycloneDX/specification
- Schemas(所有版本):https://github.com/CycloneDX/specification/tree/master/schema
- 示例:https://github.com/CycloneDX/sbom-examples
- CycloneDX 工具中心 : https://cyclonedx.org/tool-center/
#### CycloneDX 用例
- [CycloneDX 用例](https://cyclonedx.org/use-cases/)(综合),包括:
- [清单](https://cyclonedx.org/use-cases/#inventory)
- [许可证合规性](https://cyclonedx.org/use-cases/#license-compliance)
- [已知漏洞](https://cyclonedx.org/use-cases/#known-vulnerabilities)
- [CycloneDX 漏洞可利用性交换 (VEX) 格式概述](https://cyclonedx.org/capabilities/vex/)
- 示例:https://github.com/CycloneDX/bom-examples/tree/master/VEX
### SPDX
- GitHub: https://github.com/spdx
- 规范(按分支):https://github.com/spdx/spdx-spec
- Schemas(按分支):
- [v2.3.1](https://github.com/spdx/spdx-spec/tree/development/v2.3.1/schemas)
- [v2.3](https://github.com/spdx/spdx-spec/tree/development/v2.3/schemas)
- [v2.2.2](https://github.com/spdx/spdx-spec/tree/development/v2.2.2/schemas)
- SPDX 示例:[https://github.com/spdx/spdx-examples](https://github.com/spdx/spdx-examples)
- 工具
- [SPDX 在线工具](https://tools.spdx.org/app/)
- **注意** 使用了 [convert](https://tools.spdx.org/app/convert/) 工具将 SPDX 示例从 `.tv` 格式转换为 `.json`;然而,转换 [`example6-bin.spdx`](https://github.com/spdx/spdx-examples/blob/master/example6/spdx/example6-bin.spdx) 导致了错误。
标签:API平台, BOM管理, CycloneDX, EVTX分析, Go语言, GPT, IETF RFC 6902, JSON Schema, SBOM, SPDX, WebSocket, 依赖分析, 安全合规, 数据校验, 日志审计, 正则表达式查询, 漏洞管理, 硬件无关, 程序破解, 端点安全, 网络代理, 聊天机器人, 补丁管理, 许可证合规, 跌倒检测, 软件物料清单
