github.com/CycloneDX/sbom-utility@v0.16.0/README.md (about) 1 [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 2 [![License](https://img.shields.io/badge/CycloneDX-v1.2,1.3,1.4,1.5,1.6-darkcyan.svg)](https://opensource.org/licenses/Apache-2.0) 3 [![License](https://img.shields.io/badge/SPDX-v2.1,2.2,2.3-purple.svg)](https://opensource.org/licenses/Apache-2.0) 4 5 # sbom-utility 6 7 The **`sbom-utility`** was designed to be an API platform to validate, analyze and edit **Bills-of-Materials (BOMs)**. Initially, it was created to **validate** either CycloneDX *or* SPDX-formatted BOMs against official, versioned JSON schemas as published by their respective standards communities. 8 9 - *Organizations may also design and supply **"custom JSON schema"** variants to the validate command which are perhaps designed to assure additional data-compliance requirements are met.* 10 11 The utility also offers commands that support analysis and editing of BOM document data including **trim**, **patch** (IETF RFC 6902) and **diff** *(experimental)*. 12 13 In addition, the utility features "report" commands that can easily *extract*, *filter*, *list* and *summarize* **component**, **service**, **license**, **resource**, **vulnerability** and other BOM information using the utility's powerful, SQL-like query command. The **query** command allows **select**-ion of specific data **from** anywhere in the BOM document **where** data values match specified (regex) patterns. 14 15 - *Report output can be produced in several formats (e.g., `txt`, `csv`, `md` (markdown) and `json`) to accommodate further processing.* 16 17 > **Note**: *This utility supports all CycloneDX BOM variants, such as Software (**SBOM**), Hardware (**HBOM**), Manufacturing (**MBOM**), Machine Learning and AI (**MLBOM**), Cryptographic (**CBOM**), etc.* 18 19 --- 20 21 ### Command Overview 22 23 The following commands, which operate against input BOMs and their data, are offered by the utility: 24 25 | Command <font size="-1">*[`subcommand`]*</font> | Description | 26 | :-- | :-- | 27 | **[validate](#validate)** | Enables validation of SBOMs against their declared format (e.g., SPDX, CycloneDX) and version (e.g., "2.3", "1.6", etc.) using their JSON schemas.| 28 | **[patch](#patch)** | Applies a JSON patch file, as defined by [IETF RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/), to an input JSON BOM file. | 29 | **[trim](#trim)** | Removes specified JSON information from the input JSON BOM document and produce output BOMs with reduced or targeted sets of information.</br></br>*A "SQL-like" set of parameters allows for fine-grained specification of which fields should be trimmed from which document paths.* | 30 | **[diff](#diff)** | **Experimental**[<sup>1</sup>](#experimental-commands): Displays the delta between two similar BOM versions in JSON (diff) patch format as defined by [IETF RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/). *Please read "recommendations" before running.* | 31 | **[query](#query)** | Retrieves JSON data from BOMs using SQL-style query statements (i.e., `--select <data fields> --from <BOM object> --where <field=regex>`). The JSON data can be used to create custom listings or reports. | 32 | **[component](#component)** **[`list`](#component-list-command)** | Produces filterable listings of hardware or software components declared in the BOM. | 33 | **[license](#license)** **[`list`](#license-list-subcommand)** | Produces filterable listings of license data declared in the BOM along with the associated component or service. Includes *"usage policy"* determinations as declared in the `license.json` configuration file. | 34 | **[license](#license)** **[`policy`](#license-policy-subcommand)** | Produces filterable listings of software and data license information and associated license usage policies as defined a `license.json` configuration file. | 35 | **[resource `list`](#resource)** | Produces filterable listings of resources (i.e., components and services) declared in the BOM. | 36 | **[schema `list`](#schema)** | Produces filterable listings of schema formats, versions and variants supported by the `validation` command.</br></br> **Note**: Customized JSON schemas can also be permanently configured as named schema "variants" within the utility's configuration file (see the `schema` command's [adding schemas](#adding-schemas) section). | 37 | **[vulnerability `list`](#vulnerability)** | produces filterable listings of vulnerabilities declared in the BOM (i.e., CycloneDX Vulnerability Exploitability eXchange (**VEX**)) data or independently stored CycloneDX Vulnerability Disclosure Report (**VDR**) data stored in the BOM format. | 38 39 > **Experimental commands**: 40 *Testing, feedback and helpful suggestions and code commits are appreciated on experimental commands.* 41 42 --- 43 44 ### Project Index 45 46 - [Installation](#installation) 47 - [Running](#running) 48 - [Commands](#commands) 49 - [Contributing](#contributing) 50 - [Design considerations](#design-considerations) 51 - [Development](#development) 52 - [Testing](#testing) 53 - [Releasing](#releasing) 54 - [BOM References](#bom-references) 55 - [CycloneDX](#cyclonedx), [SPDX](#spdx) 56 57 --- 58 59 ### Installation 60 61 Download and decompress the correct archive file (i.e., `.tar` for Unix/Linux systems and `.zip` for Windows) for your target system's architecture and operating system from the releases page within this repository. 62 63 - [https://github.com/CycloneDX/sbom-utility/releases](https://github.com/CycloneDX/sbom-utility/releases) 64 65 The source archive will contain the following files under the root directory: 66 67 - `sbom-utility` - binary executable. This is all most need for non-customized configurations. 68 - `LICENSE` - the software license for the utility (i.e. Apache 2) 69 - `sbom-utility-<version>.sbom.json` - a simple Software Bill-of-Materials (SBOM) for the utility 70 71 as well as sample configuration files: 72 73 - `config.json` *(optional)* - copy of the default schema configuration file for optional customization (to be passed on the command line) 74 - `license.json` *(optional)* - copy of the default license policy configuration file for optional customization (to be passed on the command line) 75 - `custom.json` *(experimental, unused)* - custom validation configuration file 76 77 --- 78 79 ## Running 80 81 For convenience, the default `config.json` and optional `license.json` configuration files have been embedded in the executable and used. *You can provide your own versions of these files on the command line using the `--config-schema` or `--config-license` flags respectively.* 82 83 - **Note**: *When providing configuration files using command line flags, the executable attempts to load them from the same path where the executable is run from. If you choose to keep them in a different directory, you will have to supply their location relative to the executable along with the filename.* 84 85 ##### MacOS - Granting executable permission 86 87 On MacOS, the utility is not a registered Apple application and may warn you that it cannot open it the first time. If so, you will need to explicitly permit the executable to be "opened" on your system acknowledging it trusted. This process is initiated from the Finder application by using `ctrl-click` on the executable file and agreeing using the "Open" button. 88 89 - See how to ["Open a Mac app from an unidentified developer"](https://support.apple.com/guide/mac-help/open-a-mac-app-from-an-unidentified-developer-mh40616/mac) 90 91 --- 92 93 ## Commands 94 95 This section provides detailed descriptions of all commands, supported flags and output formats along with usage examples. 96 97 All commands generate consistent [exit codes](#exit-codes) as well as share some [persistent flags](#persistent-flags) which are described here: 98 99 - [Exit codes](#exit-codes): Including: *`0`: no error, `1`: application error, `2`: validation error, etc.* 100 - [Persistent flags](#persistent-flags) Including: *`--input`, `--output`, `--format`, `--quiet`, `--where`, etc.* 101 102 Convenient links to each command: 103 104 - [validate](#validate): Validates BOM data against declared or required JSON schema. 105 - [trim](#trim): Removes uninteresting or necessary fields and data from a BOM. 106 - [patch](#patch): Patches BOMs using IETF RFC 6902 records. 107 - [diff](#diff): *(Experimental)*: Displays the differences between two similar BOMs. *Please read recommendations before executing.* 108 - [query](#query): Extracts JSON objects and fields from a BOM using SQL-like queries. 109 - [component list](#component): Lists all component information found in a BOM. 110 - [license](#license) 111 - [list](#license-list-subcommand): Lists all license information found in a BOM. 112 - [policy](#license-policy-subcommand): Lists configurable license usage policies found in the `license.json` file. 113 - [resource list](#resource): Lists all resource information by type (e.g., components, services). 114 - [schema list](#schema): Lists supported JSON schemas by BOM format, version and variant. 115 - [vulnerability list](#vulnerability): Lists vulnerability (i.e., `VEX`) information included in a BOM or standalone `VDR` BOM. 116 - [completion](#completion): Generates command-line completion scripts for the this utility. 117 - [help](#help): Displays help and usage information for the utility or currently specified command. 118 119 --- 120 121 ### Exit codes 122 123 All commands return a numeric exit code (i.e., a POSIX exit code) for use in automated processing where `0` indicates success and a non-zero value indicates failure of some kind designated by the number. 124 125 The SBOM Utility always returns one of these 3 codes to accommodate logic in BASH (shell) scripting: 126 127 - `0`= no error (valid) 128 - `1`= application error 129 - `2`= validation error 130 131 ##### Example: exit code 132 133 This example uses the `schema` list command to verify its exit code: 134 135 ```bash 136 ./sbom-utility schema list 137 ``` 138 139 verify the exit code: 140 141 ```bash 142 echo $? 143 ``` 144 145 which returns `0` (zero) or "no error": 146 147 ```bash 148 0 149 ``` 150 151 --- 152 153 ### Persistent flags 154 155 This section describes some of the important command line flags that apply to most of the utility's commands. 156 157 - [format flag](#format-flag): with `--format` 158 - [indent flag](#indent-flag): with `--indent` 159 - [input flag](#input-flag): with `--input` or `-i` 160 - [output flag](#output-flag): with `--output` or `-o` 161 - [quiet flag](#quiet-flag): with `--quiet` or `-q` 162 - [where flag](#where-flag-output-filtering): with `--where` 163 164 #### Format flag 165 166 All `list` subcommands support the `--format` flag with the following values: 167 168 - `txt`: text (tabbed tables) 169 - `csv`: Comma Separated Value (CSV), e.g., for spreadsheets 170 - `md`: Markdown (GitHub-compliant tables) 171 172 Some commands, which can output lists of JSON objects, also support JSON format using the `json` value. 173 174 ##### Example: `--format` flag 175 176 This example uses the `--format` flag on the `schema` command to output in markdown: 177 178 ```bash 179 ./sbom-utility schema --format md -q 180 ``` 181 182 ```md 183 |name|format|version|variant|file (local)|url (remote)| 184 |:--|:--|:--|:--|:--|:--| 185 |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| 186 |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| 187 |CycloneDX/specification/master/schema/bom-1.3-strict.schema.json| 188 |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| 189 |CycloneDX/specification/master/schema/bom-1.2-strict.schema.json| 190 |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| 191 |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| 192 |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| 193 |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| 194 |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| 195 ``` 196 197 #### Indent flag 198 199 This flag supplies an integer to any command that encodes JSON output to determine how many spaces to indent nested JSON elements. If not specified, the default indent is `4` (spaces). 200 201 ##### Example: indent flag on the query command 202 203 ```bash 204 ./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 2 -q 205 ``` 206 207 output with `indent 2`: 208 209 ```json 210 { 211 "name": "juice-shop", 212 "version": "11.1.2" 213 } 214 ``` 215 216 ```bash 217 ./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 6 -q 218 ``` 219 220 output with `indent 6`: 221 222 ```json 223 { 224 "name": "juice-shop", 225 "version": "11.1.2" 226 } 227 ``` 228 229 #### Input flag 230 231 All `list` subcommands and the `validate` command support the `--input-file <filename>` flag (or its short-form `-i <filename>`) to declare file contents (i.e., BOM data) the commands will read and operate on. 232 233 #### Standard input (stdin) 234 235 All commands that support the input flag can also accept data from standard input or `stdin` by using the `-` (dash) character as the value instead of a filename. 236 237 ##### Example of stdin using pipe 238 239 ```bash 240 cat examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json | ./sbom-utility resource list -i - 241 ``` 242 243 ##### Example of stdin using redirect 244 245 ```bash 246 ./sbom-utility validate -i - < examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json 247 ``` 248 249 #### Output flag 250 251 All `list` subcommands and the `validate` command support the `--output-file <filename>` flag (or its short-form `-o <filename>`) to send formatted output to a file. 252 253 ##### Example: `--output-file` flag 254 255 This example uses the `schema` command to output to a file named `output.txt` with format set to `csv`: 256 257 ```bash 258 ./sbom-utility schema --format csv -o output.csv 259 ``` 260 261 Verify the contents of `output.csv` contain CSV formatted output: 262 263 ```bash 264 cat output.csv 265 ``` 266 267 ```csv 268 Name,Format,Version,Variant,File (local),URL (remote) 269 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 270 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 271 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 272 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 273 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 274 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 275 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 276 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 277 ``` 278 279 - **Note**: You can verify that `output.csv` loads within a spreadsheet app like MS Excel. 280 281 #### Quiet flag 282 283 All commands support the `--quiet` flag. By default, the utility outputs informational (INFO), warning (WARNING) and error (ERROR) text along with the actual command results to `stdout`. If you wish to only see the command results (JSON) or report (tables) you can run any command in "quiet mode" by simply supplying the `--quiet` or its short-form `-q` flag. 284 285 ##### Example: `--quiet` flag 286 287 This example shows the `--quiet` flag being used on the `schema` command to turn off or "quiet" any informational output so that only the result table is displayed. 288 289 ```bash 290 ./sbom-utility schema list --quiet 291 ``` 292 293 ```bash 294 name format version variant file (local) url (remote) 295 ---- ------ ------- ------- ------------ ------------ 296 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 297 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 298 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 299 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 300 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 301 ... 302 ``` 303 304 #### Where flag (output filtering) 305 306 All `list` subcommands support the `--where` flag. It can be used to filter output results based upon matches to regular expressions (regex) by using the output list's column titles as keys. 307 308 Multiple key-value (i.e., column-title=regex) pairs can be provided on the same `--where` filter flag using commas. 309 310 **Syntax**: `[--where key=regex[,...]]` 311 312 See each command's section for contextual examples of the `--where` flag filter usage. 313 314 --- 315 316 ### Validate 317 318 This command will parse standardized SBOMs and validate it against its declared format and version (e.g., SPDX 2.3, CycloneDX 1.6). Custom variants of standard JSON schemas can be used for validation by supplying the `--variant` name as a flag. Explicit JSON schemas can be specified using the `--force` flag. 319 320 #### Validating using supported schemas 321 322 Use the [schema](#schema) command to list supported schemas formats, versions and variants. 323 324 #### Validating using "custom" schemas 325 326 Customized JSON schemas can also be permanently configured as named schema "variants" within the utility's configuration file. See [adding schemas](#adding-schemas). 327 328 - **"Customized" schema** variants, perhaps derived from standard BOM schemas, can be used for validation using the `--variant` flag (e.g., industry or company-specific schemas). 329 - **Overriding default schema** - You can override an BOM's declared BOM version using the `--force` flag (e.g., verify a BOM against a newer specification version). 330 331 #### Validate flags 332 333 The following flags can be used to improve performance when formatting error output results: 334 335 ##### `--error-limit` flag 336 337 Use the `--error-limit x` (default: `10`) flag to reduce the formatted error result output to the first `x` errors. By default, only the first 10 errors are output with an informational messaging indicating `x/y` errors were shown. 338 339 ##### `--error-value` flag 340 341 Use the `--error-value=true|false` (default: `true`) flag to reduce the formatted error result output by not showing the `value` field which shows detailed information about the failing data in the BOM. 342 343 ##### `--colorize` flag 344 345 Use the `--colorize=true|false` (default: `false`) flag to add/remove color formatting to error result `txt` formatted output. By default, `txt` formatted error output is colorized to help with human readability; for automated use, it can be turned off. 346 347 #### Validate Examples 348 349 ##### Example: Validate using inferred format and schema 350 351 Validating the "juice shop" SBOM (CycloneDX 1.2) example provided in this repository. 352 353 ```bash 354 ./sbom-utility validate -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json 355 ``` 356 357 ```bash 358 [INFO] Loading (embedded) default schema config file: `config.json`... 359 [INFO] Loading (embedded) default license policy file: `license.json`... 360 [INFO] Attempting to load and unmarshal data from: `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json`... 361 [INFO] Successfully unmarshalled data from: `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json` 362 [INFO] Determining file's BOM format and version... 363 [INFO] Determined BOM format, version (variant): `CycloneDX`, `1.2` (latest) 364 [INFO] Matching BOM schema (for validation): schema/cyclonedx/1.2/bom-1.2.schema.json 365 [INFO] Loading schema `schema/cyclonedx/1.2/bom-1.2.schema.json`... 366 [INFO] Schema `schema/cyclonedx/1.2/bom-1.2.schema.json` loaded. 367 [INFO] Validating `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json`... 368 [INFO] BOM valid against JSON schema: `true` 369 ``` 370 371 You can also verify the [exit code](#exit-codes) from the validate command: 372 373 ```bash 374 echo $? 375 ``` 376 377 ```bash 378 0 // no error (valid) 379 ``` 380 381 #### Example: Validate using "custom" schema variants 382 383 The validation command will use the declared format and version found within the SBOM JSON file itself to lookup the default (latest) matching schema version (as declared in`config.json`; however, if variants of that same schema (same format and version) are declared, they can be requested via the `--variant` command line flag: 384 385 ```bash 386 ./sbom-utility validate -i test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json --variant custom 387 ``` 388 389 If you run the sample command above, you would see several "custom" schema errors resulting in an invalid SBOM determination (i.e., `exit status 2`): 390 391 ```text 392 [INFO] Loading (embedded) default schema config file: `config.json`... 393 [INFO] Loading (embedded) default license policy file: `license.json`... 394 [INFO] Attempting to load and unmarshal data from: `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`... 395 [INFO] Successfully unmarshalled data from: `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json` 396 [INFO] Determining file's BOM format and version... 397 [INFO] Determined BOM format, version (variant): `CycloneDX`, `1.4` custom 398 [INFO] Matching BOM schema (for validation): schema/test/bom-1.4-custom.schema.json 399 [INFO] Loading schema `schema/test/bom-1.4-custom.schema.json`... 400 [INFO] Schema `schema/test/bom-1.4-custom.schema.json` loaded. 401 [INFO] Validating `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`... 402 [INFO] BOM valid against JSON schema: `false` 403 [INFO] (3) schema errors detected. 404 [INFO] Formatting error results (`txt` format)... 405 1. { 406 "type": "contains", 407 "field": "metadata.properties", 408 "context": "(root).metadata.properties", 409 "description": "At least one of the items must match", 410 "value": [ 411 { 412 "name": "urn:example.com:disclaimer", 413 "value": "This SBOM is current as of the date it was generated." 414 }, 415 { 416 "name": "urn:example.com:classification", 417 "value": "This SBOM is Confidential Information. Do not distribute." 418 } 419 ] 420 } 421 2. { 422 "type": "const", 423 "field": "metadata.properties.0.value", 424 "context": "(root).metadata.properties.0.value", 425 "description": "metadata.properties.0.value does not match: \"This SBOM is current as of the date it was generated and is subject to change.\"", 426 "value": "This SBOM is current as of the date it was generated." 427 } 428 3. { 429 "type": "number_all_of", 430 "field": "metadata.properties", 431 "context": "(root).metadata.properties", 432 "description": "Must validate all the schemas (allOf)", 433 "value": [ 434 { 435 "name": "urn:example.com:disclaimer", 436 "value": "This SBOM is current as of the date it was generated." 437 }, 438 { 439 "name": "urn:example.com:classification", 440 "value": "This SBOM is Confidential Information. Do not distribute." 441 } 442 ] 443 } 444 [ERROR] invalid SBOM: schema errors found (test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json) 445 [INFO] document `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`: valid=[false] 446 ``` 447 448 confirming the exit code: 449 450 ```bash 451 echo $? 452 ``` 453 454 ```bash 455 2 // SBOM error 456 ``` 457 458 ##### Why validation failed 459 460 The output shows a first schema error indicating the failing JSON object; in this case, 461 462 - the CycloneDX `metadata.properties` field, which is a list of `property` objects. 463 - Found that a property with a `name` field with the value `"urn:example.com:disclaimer"` had an incorrect `value`. 464 - the `value` field SHOULD have had a constant value of `"This SBOM is current as of the date it was generated and is subject to change."` (as was required by the custom schema's regex). 465 - However, it was found to have only a partial match of `"This SBOM is current as of the date it was generated."`. 466 467 ##### Details of the schema error 468 469 Use the `--debug` or `-d` flag to see all schema error details: 470 471 ```bash 472 ./sbom-utility validate -i test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json --variant custom -d 473 ``` 474 475 The details include the full context of the failing `metadata.properties` object which also includes a `"urn:example.com:classification"` property: 476 477 ```bash 478 3. { 479 "type": "number_all_of", 480 "field": "metadata.properties", 481 "context": "(root).metadata.properties", 482 "description": "Must validate all the schemas (allOf)", 483 "value": [ 484 { 485 "name": "urn:example.com:disclaimer", 486 "value": "This SBOM is current as of the date it was generated." 487 }, 488 { 489 "name": "urn:example.com:classification", 490 "value": "This SBOM is Confidential Information. Do not distribute." 491 } 492 ] 493 } 494 ``` 495 496 #### Example: Validate using "JSON" format 497 498 The JSON format will provide an `array` of schema error results that can be post-processed as part of validation toolchain. 499 500 ```bash 501 ./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json -q 502 ``` 503 504 ```json 505 [ 506 { 507 "type": "unique", 508 "field": "components", 509 "context": "(root).components", 510 "description": "array items[1,2] must be unique", 511 "value": { 512 "type": "array", 513 "index": 1, 514 "item": { 515 "bom-ref": "pkg:npm/body-parser@1.19.0", 516 "description": "Node.js body parsing middleware", 517 "hashes": [ 518 { 519 "alg": "SHA-1", 520 "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 521 } 522 ], 523 "licenses": [ 524 { 525 "license": { 526 "id": "MIT" 527 } 528 } 529 ], 530 "name": "body-parser", 531 "purl": "pkg:npm/body-parser@1.19.0", 532 "type": "library", 533 "version": "1.19.0" 534 } 535 } 536 }, 537 { 538 "type": "unique", 539 "field": "components", 540 "context": "(root).components", 541 "description": "array items[2,4] must be unique", 542 "value": { 543 "type": "array", 544 "index": 2, 545 "item": { 546 "bom-ref": "pkg:npm/body-parser@1.19.0", 547 "description": "Node.js body parsing middleware", 548 "hashes": [ 549 { 550 "alg": "SHA-1", 551 "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 552 } 553 ], 554 "licenses": [ 555 { 556 "license": { 557 "id": "MIT" 558 } 559 } 560 ], 561 "name": "body-parser", 562 "purl": "pkg:npm/body-parser@1.19.0", 563 "type": "library", 564 "version": "1.19.0" 565 } 566 } 567 } 568 ] 569 ``` 570 571 ##### Reducing output size using `error-value=false` flag 572 573 In many cases, BOMs may have many errors and having the `value` information details included can be too verbose and lead to large output files to inspect. In those cases, simply set the `error-value` flag to `false`. 574 575 Rerunning the same command with this flag set to false yields a reduced set of information. 576 577 ```bash 578 ./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json --error-value=false -q 579 ``` 580 581 ```json 582 [ 583 { 584 "type": "unique", 585 "field": "components", 586 "context": "(root).components", 587 "description": "array items[1,2] must be unique" 588 }, 589 { 590 "type": "unique", 591 "field": "components", 592 "context": "(root).components", 593 "description": "array items[2,4] must be unique" 594 } 595 ] 596 ``` 597 598 --- 599 600 ### Trim 601 602 This command is able to "trim" one or more JSON keys (fields) from specified JSON BOM documents effectively "pruning" the JSON document. This functionality helps consumers of large-sized BOMs that need to analyze specific types of data in large BOMs in reducing the BOM data to just what is needed for their use cases or needs. 603 604 #### Trim supported output formats 605 606 This command is used to output, using the [`--output-file` flag](#output-flag), a "trimmed" BOM in JSON format. 607 608 - `json` (default) 609 610 #### Trim flags 611 612 Trim operates on a JSON BOM input file (see [`--input-file` flag](#input-flag)) and produces a trimmed JSON BOM output file using the following flags: 613 614 ##### Trim `--keys` flag 615 616 A comma-separated list of JSON map keys. Similar to the [query command's `--select` flag](#query---select-flag) syntax. 617 618 ##### Trim `--from` flag 619 620 A comma-separated list of JSON document paths using the same syntax as the [query command's `--from` flag](#query---from-flag). 621 622 ##### Trim `--normalize` flag 623 624 A flag that normalizes the BOM data after trimming and prior to output. 625 626 This flag has custom code that sorts all components, services, licenses, vulnerabilities, properties, external references, hashes and *most* other BOM data using custom comparators. 627 628 Each comparator uses `required` fields and other identifying fields to create *"composite keys"* for each unique data structure. 629 630 #### Trim examples 631 632 The original BOM used for these examples can be found here: 633 634 - [test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json](test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json) 635 636 ##### Example: Trim `properties` from entire JSON BOM 637 638 Validating the "juice shop" SBOM (CycloneDX 1.2) example provided in this repository. 639 640 ```bash 641 ./sbom-utility trim -i ./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=properties 642 ``` 643 644 Original BOM with `properties`: 645 646 ```json 647 { 648 "bomFormat": "CycloneDX", 649 "specVersion": "1.5", 650 "version": 1, 651 "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", 652 "components": [ 653 { 654 "type": "library", 655 "bom-ref": "pkg:npm/sample@2.0.0", 656 "purl": "pkg:npm/sample@2.0.0", 657 "name": "sample", 658 "version": "2.0.0", 659 "description": "Node.js Sampler package", 660 "properties": [ 661 { 662 "name": "foo", 663 "value": "bar" 664 } 665 ] 666 }, 667 { 668 "type": "library", 669 "bom-ref": "pkg:npm/body-parser@1.19.0", 670 "purl": "pkg:npm/body-parser@1.19.0", 671 "name": "body-parser", 672 "version": "1.19.0", 673 "description": "Node.js body parsing middleware", 674 "hashes": [ 675 { 676 "alg": "SHA-1", 677 "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 678 } 679 ] 680 } 681 ], 682 "properties": [ 683 { 684 "name": "abc", 685 "value": "123" 686 } 687 ] 688 } 689 ``` 690 691 Output BOM results without `properties`: 692 693 ```json 694 { 695 "bomFormat": "CycloneDX", 696 "specVersion": "1.5", 697 "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", 698 "version": 1, 699 "components": [ 700 { 701 "type": "library", 702 "bom-ref": "pkg:npm/sample@2.0.0", 703 "name": "sample", 704 "version": "2.0.0", 705 "description": "Node.js Sampler package", 706 "purl": "pkg:npm/sample@2.0.0" 707 }, 708 { 709 "type": "library", 710 "bom-ref": "pkg:npm/body-parser@1.19.0", 711 "name": "body-parser", 712 "version": "1.19.0", 713 "description": "Node.js body parsing middleware", 714 "hashes": [ 715 { 716 "alg": "SHA-1", 717 "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 718 } 719 ], 720 "purl": "pkg:npm/body-parser@1.19.0" 721 } 722 ] 723 } 724 ``` 725 726 ##### Example: Trim `name` and `description` from entire JSON BOM 727 728 ```bash 729 ./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=name,description -q 730 ``` 731 732 Output BOM results without `name` or `description`: 733 734 ```json 735 { 736 "bomFormat": "CycloneDX", 737 "specVersion": "1.5", 738 "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", 739 "version": 1, 740 "components": [ 741 { 742 "type": "library", 743 "bom-ref": "pkg:npm/sample@2.0.0", 744 "version": "2.0.0", 745 "purl": "pkg:npm/sample@2.0.0", 746 "properties": [ 747 { 748 "value": "bar" 749 } 750 ] 751 }, 752 { 753 "type": "library", 754 "bom-ref": "pkg:npm/body-parser@1.19.0", 755 "version": "1.19.0", 756 "hashes": [ 757 { 758 "alg": "SHA-1", 759 "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 760 } 761 ], 762 "purl": "pkg:npm/body-parser@1.19.0" 763 } 764 ], 765 "properties": [ 766 { 767 "value": "123" 768 } 769 ] 770 } 771 ``` 772 773 ##### Example: Trim `properties` from only `components` path 774 775 ```bash 776 ./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=properties --from components -q 777 ``` 778 779 Output BOM results with `properties` removed from all `components`: 780 781 ```json 782 { 783 "bomFormat": "CycloneDX", 784 "specVersion": "1.5", 785 "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", 786 "version": 1, 787 "components": [ 788 { 789 "type": "library", 790 "bom-ref": "pkg:npm/sample@2.0.0", 791 "name": "sample", 792 "version": "2.0.0", 793 "description": "Node.js Sampler package", 794 "purl": "pkg:npm/sample@2.0.0" 795 }, 796 { 797 "type": "library", 798 "bom-ref": "pkg:npm/body-parser@1.19.0", 799 "name": "body-parser", 800 "version": "1.19.0", 801 "description": "Node.js body parsing middleware", 802 "hashes": [ 803 { 804 "alg": "SHA-1", 805 "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 806 } 807 ], 808 "purl": "pkg:npm/body-parser@1.19.0" 809 } 810 ], 811 "properties": [ 812 { 813 "name": "abc", 814 "value": "123" 815 } 816 ] 817 } 818 ``` 819 820 --- 821 822 ##### Example: Trim `bom-ref` and normalize output 823 824 ```bash 825 ./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-components-normalize.sbom.json --keys="bom-ref" --normalize -q 826 ``` 827 828 **Note** If you do not want to remove any keys and simply normalize output, set keys to an empty string: `--keys=""`. 829 830 Use the trim command to remove all `bom-ref` fields and normalize output: 831 832 ```json 833 { 834 "bomFormat": "CycloneDX", 835 "specVersion": "1.5", 836 "components": [ 837 { 838 "type": "library", 839 "bom-ref": "pkg:npm/sample@2.0.0", 840 "purl": "pkg:npm/sample@2.0.0", 841 "name": "sample", 842 "version": "2.0.0", 843 "licenses": [ 844 { 845 "license": { 846 "id": "GPL-2.0-or-later" 847 } 848 }, 849 { 850 "license": { 851 "id": "LGPL-2.0-or-later" 852 } 853 }, 854 { 855 "license": { 856 "id": "GPL-2.0-only" 857 } 858 } 859 ], 860 "properties": [ 861 { 862 "name": "moo", 863 "value": "cow" 864 }, 865 { 866 "name": "foo", 867 "value": "bar" 868 } 869 ] 870 }, 871 { 872 "type": "library", 873 "bom-ref": "pkg:npm/body-parser@1.19.0", 874 "purl": "pkg:npm/body-parser@1.19.0", 875 "name": "body-parser", 876 "version": "1.19.0", 877 "hashes": [ 878 { 879 "alg": "SHA-256", 880 "content": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" 881 }, 882 { 883 "alg": "SHA-1", 884 "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 885 } 886 ], 887 "licenses": [ 888 { 889 "license": { 890 "id": "MIT" 891 } 892 }, 893 { 894 "license": { 895 "id": "Apache-2.0" 896 } 897 } 898 ], 899 "externalReferences": [ 900 { 901 "type": "website", 902 "url": "https://example.com/website" 903 }, 904 { 905 "type": "support", 906 "url": "https://example.com/support" 907 } 908 ] 909 } 910 ] 911 } 912 ``` 913 914 Trimmed, normalized output: 915 916 ```json 917 { 918 "bomFormat": "CycloneDX", 919 "specVersion": "1.5", 920 "components": [ 921 { 922 "type": "library", 923 "name": "body-parser", 924 "version": "1.19.0", 925 "hashes": [ 926 { 927 "alg": "SHA-1", 928 "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 929 }, 930 { 931 "alg": "SHA-256", 932 "content": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" 933 } 934 ], 935 "licenses": [ 936 { 937 "license": { 938 "id": "Apache-2.0" 939 } 940 }, 941 { 942 "license": { 943 "id": "MIT" 944 } 945 } 946 ], 947 "purl": "pkg:npm/body-parser@1.19.0", 948 "externalReferences": [ 949 { 950 "type": "support", 951 "url": "https://example.com/support" 952 }, 953 { 954 "type": "website", 955 "url": "https://example.com/website" 956 } 957 ] 958 }, 959 { 960 "type": "library", 961 "name": "sample", 962 "version": "2.0.0", 963 "licenses": [ 964 { 965 "license": { 966 "id": "GPL-2.0-only" 967 } 968 }, 969 { 970 "license": { 971 "id": "GPL-2.0-or-later" 972 } 973 }, 974 { 975 "license": { 976 "id": "LGPL-2.0-or-later" 977 } 978 } 979 ], 980 "purl": "pkg:npm/sample@2.0.0", 981 "properties": [ 982 { 983 "name": "foo", 984 "value": "bar" 985 }, 986 { 987 "name": "moo", 988 "value": "cow" 989 } 990 ] 991 } 992 ] 993 } 994 ``` 995 996 --- 997 998 ### Patch 999 1000 This *experimental* command is able to "patch" an existing JSON BOM document using an [IETF RFC6902](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1) *"JavaScript Object Notation (JSON) Patch"* file. 1001 1002 The current implementation supports the following "patch" operations: 1003 1004 - "add", "update", "remove" and "test" 1005 1006 At this time the "move" or "copy" operations are not supported. 1007 1008 Patches work for both simple (i.e., integer, float, boolean and string) values as well as complex values such as JSON objects, maps and arrays. 1009 1010 #### Patch supported output formats 1011 1012 This command is used to output, using the [`--output-file` flag](#output-flag), a "patched" BOM in JSON format. 1013 1014 - `json` (default) 1015 1016 #### Patch flags 1017 1018 The patch command operates on a JSON BOM input file (see [`--input-file` flag](#input-flag)) as well as an [IETF RFC6902](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1)-formatted "patch' file and produces a "patched" version of the input JSON BOM as output using the following flags: 1019 1020 ##### Patch `--patch-filename` flag 1021 1022 The `--patch-file <filename>` flag is used to provide the relative path to the IETF RFC6902 patch file to applied to the BOM input file. 1023 1024 #### Patch examples 1025 1026 This section contains examples of all supported patch operations (i.e., add, replace, test) including values that are primitives (i.e., `numbers`, `strings`) as well as JSON `objects` and may be indexed JSON `array` elements. 1027 1028 - ["add" BOM `serialNumber`](#patch-example-1-add-bom-serialnumber) 1029 - ["add" (update) BOM `version`](#patch-example-2-add-update-bom-version) 1030 - ["add" `supplier` object to `metadata`](#patch-example-3-add-supplier-object-to-metadata-object) 1031 - ["add" `property` objects to `metadata.properties` array](#patch-example-4-add-property-objects-to-metadataproperties-array) 1032 - ["replace" `version` and `timestamp` values](#patch-example-5-replace-bom-version-and-timestamp) 1033 - ["remove" `property` from the `metadata.properties` array](#patch-example-6-remove-property-from-the-metadataproperties-array) 1034 - ["test" if a `property` exists in the `metadata.properties` array](#patch-example-7-test-property-exists-in-the-metadataproperties-array) 1035 1036 ##### Patch example 1: "add" BOM `serialNumber` 1037 1038 This example adds a new top-level key `"serialNumber"` and corresponding value to a CycloneDX JSON BOM file. 1039 1040 The original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json) has no serial number: 1041 1042 ```json 1043 { 1044 "bomFormat": "CycloneDX", 1045 "specVersion": "1.5", 1046 "version": 1, 1047 "metadata": { 1048 ... 1049 } 1050 } 1051 ``` 1052 1053 IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json): 1054 1055 ```json 1056 [ 1057 { "op": "add", "path": "/serialNumber", "value": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9" } 1058 ] 1059 ``` 1060 1061 Invoke the patch command as follows: 1062 1063 ```bash 1064 ./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 1065 ``` 1066 1067 Patched JSON BOM output file: 1068 1069 ```json 1070 { 1071 "bomFormat": "CycloneDX", 1072 "specVersion": "1.5", 1073 "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", 1074 "version": 1, 1075 "metadata": { 1076 ... 1077 } 1078 } 1079 ``` 1080 1081 ##### Patch example 2: "add" (update) BOM `version` 1082 1083 This example shows how the patch's "add" operation can be used to update existing values which is the specified behavior of RFC6902. 1084 1085 Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json) with `version` equal to `1`: 1086 1087 ```json 1088 { 1089 "bomFormat": "CycloneDX", 1090 "specVersion": "1.5", 1091 "version": 1, 1092 "metadata": { 1093 ... 1094 } 1095 } 1096 ``` 1097 1098 IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json): 1099 1100 ```json 1101 [ 1102 { "op": "add", "path": "/version", "value": 2 } 1103 ] 1104 ``` 1105 1106 Invoke the patch command as follows: 1107 1108 ```bash 1109 ./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 1110 ``` 1111 1112 The patched, output JSON BOM file which has the changed `version` value of `2`: 1113 1114 ```json 1115 { 1116 "bomFormat": "CycloneDX", 1117 "specVersion": "1.5", 1118 "version": 2, 1119 "metadata": { 1120 ... 1121 } 1122 } 1123 ``` 1124 1125 ##### Patch example 3: "add" `supplier` object to `metadata` object 1126 1127 This example shows how the patch's "add" operation can be used to add a JSON object to an existing object. 1128 1129 Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): 1130 1131 ```json 1132 { 1133 "bomFormat": "CycloneDX", 1134 "specVersion": "1.5", 1135 "version": 1, 1136 "metadata": { 1137 "timestamp": "2023-10-12T19:07:00Z", 1138 "properties": [ 1139 ... 1140 ] 1141 } 1142 } 1143 ``` 1144 1145 Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-metadata-supplier.json](test/patch/cdx-patch-example-add-metadata-supplier.json): 1146 1147 ```json 1148 [ 1149 { "op": "add", "path": "/metadata/supplier", "value": { 1150 "name": "Example Co. Distribution Dept.", 1151 "url": [ 1152 "https://example.com/software/" 1153 ] 1154 } 1155 } 1156 ] 1157 ``` 1158 1159 Invoke the patch command as follows: 1160 1161 ```bash 1162 ./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 1163 ``` 1164 1165 The patched BOM has the `supplier` object added to the `metadata`: 1166 1167 ```json 1168 { 1169 "bomFormat": "CycloneDX", 1170 "specVersion": "1.5", 1171 "version": 1, 1172 "metadata": { 1173 "timestamp": "2023-10-12T19:07:00Z", 1174 "supplier": { 1175 "name": "Example Co. Distribution Dept.", 1176 "url": [ 1177 "https://example.com/software/" 1178 ] 1179 }, 1180 "properties": [ 1181 ... 1182 ] 1183 } 1184 } 1185 ``` 1186 1187 ##### Patch example 4: "add" `property` objects to `metadata.properties` array 1188 1189 This example shows how the patch's "add" operation can be used to add `property` objects to an existing `properties` array. 1190 1191 Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): 1192 1193 ```json 1194 { 1195 "bomFormat": "CycloneDX", 1196 "specVersion": "1.5", 1197 "version": 1, 1198 "metadata": { 1199 "timestamp": "2023-10-12T19:07:00Z", 1200 "properties": [ 1201 { 1202 "name": "Property 1", 1203 "value": "Value 1" 1204 }, 1205 { 1206 "name": "Property 2", 1207 "value": "Value 2" 1208 } 1209 ] 1210 } 1211 } 1212 ``` 1213 1214 Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-metadata-properties.json](test/patch/cdx-patch-example-add-metadata-properties.json): 1215 1216 ```json 1217 [ 1218 { "op": "add", "path": "/metadata/properties/-", "value": { "name": "foo", "value": "bar" } }, 1219 { "op": "add", "path": "/metadata/properties/1", "value": { "name": "rush", "value": "yyz" } } 1220 ] 1221 ``` 1222 1223 Note that the first patch record uses the `-` (dash) to indicate "insert at end" whereas the second patch record has the zero-based array index `1`. 1224 1225 Invoke the patch command as follows: 1226 1227 ```bash 1228 ./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 1229 ``` 1230 1231 The patched, output BOM has the two new properties at the specified indices: 1232 1233 ```json 1234 { 1235 "bomFormat": "CycloneDX", 1236 "specVersion": "1.5", 1237 "version": 1, 1238 "metadata": { 1239 "timestamp": "2023-10-12T19:07:00Z", 1240 "properties": [ 1241 { 1242 "name": "Property 1", 1243 "value": "Value 1" 1244 }, 1245 { 1246 "name": "rush", 1247 "value": "yyz" 1248 }, 1249 { 1250 "name": "Property 2", 1251 "value": "Value 2" 1252 }, 1253 { 1254 "name": "foo", 1255 "value": "bar" 1256 } 1257 ] 1258 } 1259 } 1260 ``` 1261 1262 ##### Patch example 5: "replace" BOM `version` and `timestamp` 1263 1264 This example shows how the patch's "replace" operation can be used to update the BOM document's `version` and `timestamp` values. 1265 1266 Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): 1267 1268 ```json 1269 { 1270 "bomFormat": "CycloneDX", 1271 "specVersion": "1.5", 1272 "version": 1, 1273 "metadata": { 1274 "timestamp": "2023-10-12T19:07:00Z", 1275 "properties": [ 1276 ... 1277 ] 1278 } 1279 } 1280 ``` 1281 1282 Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-replace-version-timestamp.json](test/patch/cdx-patch-example-replace-version-timestamp.json): 1283 1284 ```json 1285 [ 1286 { "op": "replace", "path": "/version", "value": 2 }, 1287 { "op": "replace", "path": "/metadata/timestamp", "value": "2024-01-24T22:50:18+00:00" } 1288 ] 1289 ``` 1290 1291 Invoke the patch command as follows: 1292 1293 ```bash 1294 ./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 1295 ``` 1296 1297 The patched, output BOM has both an updated `version` and `timestamp`: 1298 1299 ```json 1300 { 1301 "bomFormat": "CycloneDX", 1302 "specVersion": "1.5", 1303 "version": 2, 1304 "metadata": { 1305 "timestamp": "2024-01-24T22:50:18+00:00", 1306 "properties": [ 1307 ... 1308 } 1309 } 1310 ``` 1311 1312 ##### Patch example 6: "remove" `property` from the `metadata.properties` array 1313 1314 This example shows how the patch's "remove" operation can be used to remove a `property` object from the `metadata.properties` array using an index. 1315 1316 Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): 1317 1318 ```json 1319 { 1320 "bomFormat": "CycloneDX", 1321 "specVersion": "1.5", 1322 "version": 1, 1323 "metadata": { 1324 "timestamp": "2023-10-12T19:07:00Z", 1325 "properties": [ 1326 { 1327 "name": "Property 1", 1328 "value": "Value 1" 1329 }, 1330 { 1331 "name": "Property 2", 1332 "value": "Value 2" 1333 } 1334 ] 1335 } 1336 } 1337 ``` 1338 1339 Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-remove-metadata-property.json](test/patch/cdx-patch-example-remove-metadata-property.json): 1340 1341 ```json 1342 [ 1343 { "op": "remove", "path": "/metadata/properties/1" } 1344 ] 1345 ``` 1346 1347 Invoke the patch command as follows: 1348 1349 ```bash 1350 ./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 1351 ``` 1352 1353 The `property` at index `1` of the `metadata.properties` array has been removed: 1354 1355 ```json 1356 { 1357 "bomFormat": "CycloneDX", 1358 "specVersion": "1.5", 1359 "version": 1, 1360 "metadata": { 1361 "timestamp": "2023-10-12T19:07:00Z", 1362 "properties": [ 1363 { 1364 "name": "Property 1", 1365 "value": "Value 1" 1366 } 1367 ] 1368 } 1369 } 1370 ``` 1371 1372 ##### Patch example 7: "test" `property` exists in the `metadata.properties` array 1373 1374 This example shows how the patch records's can "test" for values or objects in a BOM. The utility will confirm "success" (using an `[INFO]` log message); otherwise, the utility will exit and return an error and generate an `[ERROR]` log message. 1375 1376 Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): 1377 1378 ```json 1379 { 1380 "bomFormat": "CycloneDX", 1381 "specVersion": "1.5", 1382 "version": 1, 1383 "metadata": { 1384 "timestamp": "2023-10-12T19:07:00Z", 1385 "properties": [ 1386 { 1387 "name": "Property 1", 1388 "value": "Value 1" 1389 }, 1390 { 1391 "name": "Property 2", 1392 "value": "Value 2" 1393 } 1394 ] 1395 } 1396 } 1397 ``` 1398 1399 Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-test-metadata-property.json](test/patch/cdx-patch-example-test-metadata-property.json): 1400 1401 ```json 1402 [ 1403 { "op": "test", "path": "/metadata/properties/1", "value": 1404 { 1405 "name": "Property 2", 1406 "value": "Value 2" 1407 } 1408 } 1409 ] 1410 ``` 1411 1412 Invoke the patch command as follows: 1413 1414 ```bash 1415 ./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 1416 ``` 1417 1418 An informational (i.e., `[INFO]`) message is logged with `success` since the property object was found in the input BOM: 1419 1420 ```json 1421 [INFO] IETF RFC6902 test operation success. test record: { 1422 "op": "test", 1423 "path": "/metadata/properties/1", 1424 "value": { 1425 "name": "Property 2", 1426 "value": "Value 2" 1427 } 1428 } 1429 ``` 1430 1431 If instead, we [tested for a different property](test/patch/cdx-patch-example-test-metadata-property-err.json) object: 1432 1433 ```json 1434 [ 1435 { "op": "test", "path": "/metadata/properties/1", "value": 1436 { 1437 "name": "Property 3", 1438 "value": "Value 3" 1439 } 1440 } 1441 ] 1442 ``` 1443 1444 an error (i.e., `[ERROR]`) would be returned from the utility: 1445 1446 ```json 1447 [ERROR] IETF RFC6902 test operation error. test record: { 1448 "op": "test", 1449 "path": "/metadata/properties/1", 1450 "value": { 1451 "name": "Property 3", 1452 "value": "Value 3" 1453 } 1454 } 1455 ``` 1456 1457 --- 1458 1459 ### Query 1460 1461 This command allows you to perform SQL-like queries into JSON format SBOMs. Currently, the command recognizes the `--select` and `--from` as well as the `--where` filter. 1462 1463 #### Query flags 1464 1465 ##### Query `--from` flag 1466 1467 The `--from` clause value is applied to the JSON document object model and can return either a singleton JSON object or an array of JSON objects as a result. This is determined by the last property value's type as declared in the schema. 1468 1469 ##### Query `--select` flag 1470 1471 The `--select` clause is then applied to the `--from` result set to only return the specified properties (names and their values). 1472 1473 ##### Query `--where` flag 1474 1475 If the result set is an array, the array entries can be reduced by applying the `--where` filter to ony return those entries whose specified field names match the supplied regular expression (regex). 1476 1477 **Note**: All `query` command results are returned as valid JSON documents. This includes a `null` value for empty result sets. 1478 1479 #### Query supported formats 1480 1481 The `query` command only supports JSON output. 1482 1483 - `json` (default) 1484 1485 #### Query result sorting 1486 1487 The `query` command does not support formatting of output results as JSON format is always returned. 1488 1489 #### Query examples 1490 1491 ##### Example: Extract the top-level `component` information from an SBOM 1492 1493 This example effectively extracts the first-order package manifest from the SBOM. 1494 1495 In this example, only the `--from` clause is needed to select an object. The `--select` clause is omitted which is equivalent to using the "select all" wildcard character `*` which returns all fields and values from the `component` object. 1496 1497 ```bash 1498 ./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --from metadata.component 1499 ``` 1500 1501 is equivalent to using the wildcard character (which may need to be enclosed in single or double quotes depending on your shell): 1502 1503 ```bash 1504 ./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --select '*' --from metadata.component -q 1505 ``` 1506 1507 ```json 1508 { 1509 "name": "Example Application v10.0.4", 1510 "bom-ref": "pkg:oci/example.com/product/application@10.0.4.0", 1511 "description": "Example's Do-It-All application", 1512 "externalReferences": [ 1513 { 1514 "type": "website", 1515 "url": "https://example.com/application" 1516 } 1517 ], 1518 "hashes": [ 1519 { 1520 "alg": "SHA-1", 1521 "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 1522 } 1523 ], 1524 "licenses": [ 1525 { 1526 "license": { 1527 "id": "Apache-2.0" 1528 } 1529 } 1530 ], 1531 ... 1532 ``` 1533 1534 ##### Example: Extract the `supplier` of the SBOM 1535 1536 In this example, the `--from` clause references the top-level `metadata.supplier` object. 1537 1538 ```bash 1539 ./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --from metadata.supplier -q 1540 ``` 1541 1542 ```json 1543 { 1544 "contact": [ 1545 { 1546 "email": "distribution@example.com" 1547 } 1548 ], 1549 "name": "Example Co. Distribution Dept.", 1550 "url": [ 1551 "https://example.com/software/" 1552 ] 1553 } 1554 ``` 1555 1556 ##### Example: Extract just the SBOM component's `name` and `version` 1557 1558 In this example, the `--from` clause references the singleton JSON object `component` found under the top-level `metadata` object. It then reduces the resultant JSON object to only return the `name` and `value` fields and their values as requested on the `--select` clause. 1559 1560 ```bash 1561 ./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 2 -q 1562 ``` 1563 1564 The result, which also uses the `--indent 2` flag: 1565 1566 ```json 1567 { 1568 "name": "juice-shop", 1569 "version": "11.1.2" 1570 } 1571 ``` 1572 1573 ##### Example: Return the JSON array of components 1574 1575 In this example, the `--from` filter will return the entire JSON components array. 1576 1577 ```bash 1578 ./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --from components -q 1579 ``` 1580 1581 ```json 1582 [ 1583 { 1584 "bom-ref": "pkg:npm/sample@2.0.0", 1585 "description": "Node.js Sampler package", 1586 "licenses": [ 1587 { 1588 "license": { 1589 "id": "MIT" 1590 } 1591 } 1592 ], 1593 "name": "sample", 1594 "purl": "pkg:npm/sample@2.0.0", 1595 "type": "library", 1596 "version": "2.0.0" 1597 }, 1598 { 1599 "bom-ref": "pkg:npm/body-parser@1.19.0", 1600 "description": "Node.js body parsing middleware", 1601 "hashes": [ 1602 { 1603 ... 1604 } 1605 ], 1606 "licenses": [ 1607 { 1608 "license": { 1609 "id": "MIT" 1610 } 1611 } 1612 ], 1613 "name": "body-parser", 1614 "purl": "pkg:npm/body-parser@1.19.0", 1615 "type": "library", 1616 "version": "1.19.0" 1617 } 1618 ] 1619 ``` 1620 1621 **Note**: The command for this example only used the `--from` flag and did not need to supply `--select '*'` as this us the default. 1622 1623 ##### Example: Filter result entries with a specified value 1624 1625 In this example, the `--where` filter will be applied to a set of `properties` results to only include entries that match the specified regex. 1626 1627 ```bash 1628 ./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --from metadata.properties --where name=urn:example.com:classification -q 1629 ``` 1630 1631 ```json 1632 [ 1633 { 1634 "name": "urn:example.com:classification", 1635 "value": "This SBOM is Confidential Information. Do not distribute." 1636 } 1637 ] 1638 ``` 1639 1640 additionally, you can apply a `--select` clause to simply obtain the matching entry's `value`: 1641 1642 ```bash 1643 ./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --select value --from metadata.properties --where name=urn:example.com:classification -q 1644 ``` 1645 1646 ```json 1647 [ 1648 { 1649 "value": "This SBOM is Confidential Information. Do not distribute." 1650 } 1651 ] 1652 ``` 1653 1654 --- 1655 1656 ### Component 1657 1658 Primarily, this command is used to extract, filter and list CycloneDX BOM component data using `component list`. 1659 1660 #### Component list supported formats 1661 1662 This command supports the `--format` flag with any of the following values: 1663 1664 - `txt` (default), `csv`, `md` 1665 1666 #### Component list flags 1667 1668 ##### Component list `--summary` flag 1669 1670 Use the `--summary` flag on the `component list` command to produce a summary report with reduced column information. 1671 1672 #### Component list examples 1673 1674 ##### Example: `component list` 1675 1676 This example shows the component list with all column information display. Since CycloneDX component data can be very extensive, many columns simply indicate the component `has` more data available which can be extracted using the `query` command if needed. 1677 1678 ```bash 1679 ./sbom-utility component list -i test/cyclonedx/1.6/specification/valid-bom-1.6.json -q 1680 ``` 1681 1682 ```text 1683 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 1684 ------- ----- ---- ---- ------- ----------- --------- ------------- ------------ ----------------- ---------------- --------- ---- ----------- --- --------- ----- ------------- --------------- ------------ ------------ -------------- ----------------- -------------- -------- -------- ------------- 1685 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 1686 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 1687 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 1688 ``` 1689 1690 ##### Example: `component list` summary only 1691 1692 The same BOM component information as in the previous example; however, using the summary flag to reduce the number of columns data. 1693 1694 ```bash 1695 ./sbom-utility component list -i test/cyclonedx/1.6/specification/valid-bom-1.6.json --summary -q 1696 ``` 1697 1698 ```text 1699 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 1700 ------- ----- ---- ---- ------- ----------- --------- ------------- ------------ ----------------- ---------------- --------- ---- ----------- --- ------------- --------------- 1701 application Acme Application 9.1.1 swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1 0 0 1702 pkg:npm/acme/component@1.0.0 com.acme library tomcat-catalina 9.0.14 pkg:npm/acme/component@1.0.0 4 1 1703 org.example library mylibrary 1.0.0 Example, Inc. https://example.com Example-2, Inc. https://example.org 0 0 1704 ``` 1705 1706 --- 1707 1708 ### License 1709 1710 This command is used to aggregate and summarize software, hardware and data license information included in the SBOM. It also displays license usage policies for resources based upon concluded by SPDX license identifier, license family or logical license expressions as defined in he current policy file (i.e., `license.json`). 1711 1712 The `license` command supports the following subcommands: 1713 1714 - [list](#license-list-subcommand) - list or create a summarized report of licenses found in input SBOM. 1715 - [list with --summary flag](#license-list---summary-flag) - As full license information can be very large, a summary view is often most useful. 1716 - [policy](#license-policy-subcommand) - list user configured license policies by SPDX license ID, family name and other filters. 1717 1718 --- 1719 1720 ### License `list` subcommand 1721 1722 The `list` subcommand produces JSON output which contains an array of CycloneDX `LicenseChoice` data objects found in the BOM input file without component association. `LicenseChoice` data, in general, may provide license information using registered SPDX IDs, license expressions (of SPDX IDs) or license names (not necessarily registered by SPDX). License data may also include base64-encoded license or legal text that was used to determine a license's SPDX ID or name. 1723 1724 #### License list supported formats 1725 1726 This command supports the `--format` flag with any of the following values: 1727 1728 - `json` (default), `csv`, `md` 1729 - using the `--summary` flag: `txt` (default), `csv`, `md` 1730 1731 #### License list result sorting 1732 1733 - Results are not sorted for base `license list` subcommand. 1734 - using the `--summary` flag: results are sorted (ascending) by license key which can be one of license `id` (SPDX ID), `name` or `expression`. 1735 1736 #### License list flags 1737 1738 ##### License list `--summary` flag 1739 1740 Use the `--summary` flag on the `license list` command to produce a summary report in `txt` (default) format as well as policy determination based upon the `license.json` declarations. 1741 1742 #### License list examples 1743 1744 ##### Example: license list JSON 1745 1746 This example shows a few entries of the JSON output that exhibit the three types of license data described above: 1747 1748 ```bash 1749 ./sbom-utility license list -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --format json -q 1750 ``` 1751 1752 ```json 1753 [ 1754 { 1755 "license": { 1756 "$comment": "by license `id", 1757 "id": "MIT", 1758 "name": "", 1759 "url": "" 1760 } 1761 }, 1762 { 1763 "license": { 1764 "$comment": "by license `expression", 1765 "id": "", 1766 "name": "", 1767 "url": "" 1768 }, 1769 "expression": "Apache-2.0 AND (MIT OR GPL-2.0-only)" 1770 }, 1771 { 1772 "license": { 1773 "$comment": "by license `name` with full license encoding", 1774 "id": "", 1775 "name": "Apache 2", 1776 "text": { 1777 "contentType": "text/plain", 1778 "encoding": "base64", 1779 "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24 ..." 1780 }, 1781 "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" 1782 } 1783 }, 1784 ... 1785 ] 1786 ``` 1787 1788 ###### Example: license list `--summary` 1789 1790 This example shows the default text output from using the summary flag: 1791 1792 ```bash 1793 ./sbom-utility license list -i test/cyclonedx/cdx-1-3-license-list.json --summary -q 1794 ``` 1795 1796 ```bash 1797 usage-policy license-type license resource-name bom-ref bom-location 1798 ------------ ------------ ------- ------------- ------- ------------ 1799 needs-review id ADSL Foo service:example.com/myservices/foo services 1800 needs-review name AGPL Library J pkg:lib/libraryJ@1.0.0 components 1801 allow name Apache Library B pkg:lib/libraryB@1.0.0 components 1802 allow id Apache-1.0 Library E pkg:lib/libraryE@1.0.0 components 1803 allow id Apache-2.0 N/A N/A metadata.licenses 1804 allow id Apache-2.0 Library A pkg:lib/libraryA@1.0.0 components 1805 allow id Apache-2.0 Library F pkg:lib/libraryF@1.0.0 components 1806 allow expression Apache-2.0 AND (MIT OR BSD-2-Clause) Library B pkg:lib/libraryB@1.0.0 components 1807 allow name BSD Library J pkg:lib/libraryJ@1.0.0 components 1808 deny name CC-BY-NC Library G pkg:lib/libraryG@1.0.0 components 1809 needs-review name GPL Library H pkg:lib/libraryH@1.0.0 components 1810 needs-review id GPL-2.0-only Library C pkg:lib/libraryC@1.0.0 components 1811 needs-review id GPL-3.0-only Library D pkg:lib/libraryD@1.0.0 components 1812 allow id MIT ACME Application pkg:app/sample@1.0.0 metadata.component 1813 allow id MIT Library A pkg:lib/libraryA@1.0.0 components 1814 UNDEFINED invalid NOASSERTION Library NoLicense pkg:lib/libraryNoLicense@1.0.0 components 1815 UNDEFINED invalid NOASSERTION Bar service:example.com/myservices/bar services 1816 needs-review name UFL ACME Application pkg:app/sample@1.0.0 metadata.component 1817 ``` 1818 1819 - **Notes** 1820 - **Usage policy** column values are derived from the `license.json` policy configuration file. 1821 - A `usage policy` value of `UNDEFINED` indicates that `license.json` provided no entry that matched the declared license (`id` or `name`) in the SBOM. 1822 - **License expressions** (e.g., `(MIT or GPL-2.0)`) with one term resolving to `UNDEFINED` and the the other term having a concrete policy will resolve to the "optimistic" policy for `OR` expressions and the "pessimistic" policy for `AND` expressions. In addition, a warning of this resolution is emitted. 1823 1824 ###### Example: license list summary with `--where` filter 1825 1826 The list command results can be filtered using the `--where` flag using the column names in the report. These include `usage-policy`, `license-type`, `license`, `resource-name`, `bom-ref` and `bom-location`. 1827 1828 The following example shows filtering of component licenses using the `license-type` column where the license was described as a `name` value: 1829 1830 ```bash 1831 ./sbom-utility license list -i test/cyclonedx/cdx-1-3-license-list.json --summary --where license-type=name -q 1832 ``` 1833 1834 ```bash 1835 usage-policy license-type license resource-name bom-ref bom-location 1836 ------------ ------------ ------- ------------- ------- ------------ 1837 needs-review name AGPL Library J pkg:lib/libraryJ@1.0.0 components 1838 allow name Apache Library B pkg:lib/libraryB@1.0.0 components 1839 allow name BSD Library J pkg:lib/libraryJ@1.0.0 components 1840 deny name CC-BY-NC Library G pkg:lib/libraryG@1.0.0 components 1841 needs-review name GPL Library H pkg:lib/libraryH@1.0.0 components 1842 needs-review name UFL ACME Application pkg:app/sample@1.0.0 metadata.component 1843 ``` 1844 1845 In another example, the list is filtered by the `usage-policy` where the value is `needs-review`: 1846 1847 ```bash 1848 ./sbom-utility license list -i test/cyclonedx/cdx-1-3-license-list.json --summary --where usage-policy=needs-review -q 1849 ``` 1850 1851 ```bash 1852 usage-policy license-type license resource-name bom-ref bom-location 1853 ------------ ------------ ------- ------------- ------- ------------ 1854 needs-review id ADSL Foo service:example.com/myservices/foo services 1855 needs-review name AGPL Library J pkg:lib/libraryJ@1.0.0 components 1856 needs-review name GPL Library H pkg:lib/libraryH@1.0.0 components 1857 needs-review id GPL-2.0-only Library C pkg:lib/libraryC@1.0.0 components 1858 needs-review id GPL-3.0-only Library D pkg:lib/libraryD@1.0.0 components 1859 needs-review name UFL ACME Application pkg:app/sample@1.0.0 metadata.component 1860 ``` 1861 1862 --- 1863 1864 ### License `policy` subcommand 1865 1866 To view a report listing the contents of the current policy file (i.e., [`license.json`](https://github.com/CycloneDX/sbom-utility/blob/main/license.json)) which contains an encoding of known software and data licenses by SPDX ID and license family along with a configurable usage policy (i.e., `"allow"`, `"deny"` or `"needs-review"`). 1867 1868 #### License policy supported formats 1869 1870 This command supports the `--format` flag with any of the following values: 1871 1872 - `txt` (default), `csv`, `md` 1873 1874 #### License policy result sorting 1875 1876 - Results are sorted by license policy `family`. 1877 1878 #### License policy flags 1879 1880 ##### list `--summary` flag 1881 1882 Use the `--summary` flag on the `license policy list` command to produce a summary report with a reduced set of column data (i.e., it includes only the following columns: `usage-policy`, `family`, `id`, `name`, `oci` (approved) `fsf` (approved), `deprecated`, and SPDX `reference` URL). 1883 1884 ##### list `--wrap` flag 1885 1886 Use the `--wrap` flag to toggle the wrapping of text within columns of the license policy report (`txt` format only) output using the values `true` or `false`. The default value is `false`. 1887 1888 #### License policy examples 1889 1890 ##### Example: license policy 1891 1892 ```bash 1893 ./sbom-utility license policy -q 1894 ``` 1895 1896 ```bash 1897 usage-policy family id name osi fsf deprecated reference aliases annotations notes 1898 ------------ ------ -- ---- --- --- ---------- --------- ------- ----------- ----- 1899 allow 0BSD 0BSD BSD Zero Clause License true false false https://spdx.org/licenses/0BSD.html Free Public License 1.0.0 APPROVED none 1900 needs-review ADSL ADSL Amazon Digital Services License false false false https://spdx.org/licenses/ADSL.html none NEEDS-APPROVAL none 1901 allow AFL AFL-3.0 Academic Free License v3.0 true true false https://spdx.org/licenses/AFL-3.0.html none APPROVED none 1902 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 1903 allow Adobe Adobe-2006 Adobe Systems Incorporated CLA false false false https://spdx.org/licenses/Adobe-2006.html none APPROVED none 1904 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 1905 allow Artistic Artistic-1.0 Artistic License 1.0 true false false https://spdx.org/licenses/Artistic-1.0.html none APPROVED none 1906 ... 1907 ``` 1908 1909 ###### Example: policy with `--summary` flag 1910 1911 We can also apply the `--summary` flag to get a reduced set of columns that includes only the `usage-policy` along with the essential SPDX license information (e.g., no annotations or notes). 1912 1913 ```bash 1914 ./sbom-utility license policy --summary -q 1915 ``` 1916 1917 ```bash 1918 usage-policy family id name osi fsf deprecated reference 1919 ------------ ------ -- ---- --- --- ---------- --------- 1920 allow 0BSD 0BSD BSD Zero Clause License true false false https://spdx.org/licenses/0BSD.html 1921 needs-review ADSL ADSL Amazon Digital Services License false false false https://spdx.org/licenses/ADSL.html 1922 allow AFL AFL-3.0 Academic Free License v3.0 true true false https://spdx.org/licenses/AFL-3.0.html 1923 needs-review AGPL AGPL-1.0 Affero General Public License v1.0 false false true https://spdx.org/licenses/AGPL-1.0.html 1924 allow Adobe Adobe-2006 Adobe Systems Incorporated CLA false false false https://spdx.org/licenses/Adobe-2006.html 1925 allow Apache Apache-2.0 Apache License 2.0 true true false https://spdx.org/licenses/Apache-2.0.html 1926 allow Artistic Artistic-1.0 Artistic License 1.0 true true false https://spdx.org/licenses/Artistic-2.0.html 1927 ... 1928 ``` 1929 1930 ###### Example: policy with `--where` filter 1931 1932 The following example shows filtering of license policies using the `id` column: 1933 1934 ```bash 1935 ./sbom-utility license policy --where id=Apache -q 1936 ``` 1937 1938 ```bash 1939 usage-policy family id name osi fsf deprecated reference aliases annotations notes 1940 ------------ ------ -- ---- --- --- ---------- --------- ------- ----------- ----- 1941 allow Apache Apache-1.0 Apache v1.0 false true false https://spdx.org/licenses/Apache-1.0.html none APPROVED none 1942 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 1943 allow Apache Apache-2.0 Apache License 2.0 true true false https://spdx.org/licenses/Apache-2.0.html Apache License APPROVED none 1944 1945 ``` 1946 1947 ###### Example: policy with `--wrap` flag 1948 1949 ```bash 1950 ./sbom-utility license policy --wrap=true -q 1951 ``` 1952 1953 ```bash 1954 usage-policy family id name osi fsf deprecated reference aliases annotations notes 1955 ------------ ------ -- ---- --- --- ---------- --------- ------- ----------- ----- 1956 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 1957 needs-review ADSL ADSL Amazon Digital Servi (20/31) false false false https://spdx.org/licenses/ADSL.html NEEDS-APPROVAL none 1958 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 1959 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 1960 AGPL-WARNING 1961 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 1962 allow Adobe Adobe-2006 Adobe Systems Incorp (20/56) false false false https://spdx.org/licenses/Adobe-2006 (36/41) APPROVED none 1963 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 1964 allow Artistic Artistic-2.0 Artistic License 2.0 true true false https://spdx.org/licenses/Artistic-2 (36/43) APPROVED none 1965 ... 1966 ``` 1967 1968 #### License policy notes 1969 1970 - Currently, the default `license.json` file, used to derive the `usage-policy` data, does not contain entries for the entire set of SPDX 3.2 license templates. 1971 - An issue [12](https://github.com/CycloneDX/sbom-utility/issues/12) is open to add parity. 1972 - Annotations (tags) and notes can be defined within the `license.json` file and one or more assigned each license entry. 1973 <!-- - Column data is, by default, truncated in `txt` format views only. In these cases, the number of characters shown out of the total available will be displayed at the point of truncation (e.g., seeing `(24/26)` in a column would indicate 24 out of 26 characters were displayed). --> 1974 - For backwards compatibility, the `--where` filter supports the key `spdx-id` as an alias for `id`. 1975 1976 --- 1977 1978 ### Resource 1979 1980 The `resource` command is geared toward inspecting various resources types and their information from SBOMs against future maturity models being developed as part of the [OWASP Software Component Verification Standard (SCVS)](https://owasp.org/www-project-software-component-verification-standard/). In the SCVS model, a "resource" is the parent classification for software (components), services, Machine Learning (ML) models, data, hardware, tools and more. 1981 1982 Primarily, the command is used to generate lists of resources, by type, that are included in a CycloneDX SBOM by invoking `resource list`. 1983 1984 #### Resource supported output formats 1985 1986 This command supports the `--format` flag with any of the following values: 1987 1988 - `txt` (default), `csv`, `md` 1989 1990 #### Resource result sorting 1991 1992 Currently, all `resource list` command results are sorted by resource `type` then by resource `name` (required field). 1993 1994 #### Resource Examples 1995 1996 #### Example: resource list 1997 1998 ```bash 1999 ./sbom-utility resource list -i test/cyclonedx/cdx-1-3-resource-list.json -q 2000 ``` 2001 2002 ```bash 2003 resource-type group name version description bom-ref 2004 ------------- ----- ---- ------- ----------- ------- 2005 component ACME Application 2.0.0 ACME sample application pkg:app/sample@1.0.0 2006 component Library A 1.0.0 Library A description pkg:lib/libraryA@1.0.0 2007 component Library C 1.0.0 Library C description. pkg:lib/libraryC@1.0.0 2008 component Library F 1.0.0 Library F description. pkg:lib/libraryF@1.0.0 2009 component Library G 1.0.0 Library G description. pkg:lib/libraryG@1.0.0 2010 component Library H 1.0.0 Library H description. pkg:lib/libraryH@1.0.0 2011 component Library NoLicense 1.0.0 Library "NoLicense" description. pkg:lib/libraryNoLicense@1.0.0 2012 component blue Library B 1.0.0 Library B description. pkg:lib/libraryB@1.0.0 2013 component blue Library E 1.0.0 Library E description. pkg:lib/libraryE@1.0.0 2014 component green Library D 1.0.0 Library D description. pkg:lib/libraryD@1.0.0 2015 component green Library J 1.0.0 Library J description. pkg:lib/libraryJ@1.0.0 2016 service Bar Bar service service:example.com/myservices/bar 2017 service Foo Foo service service:example.com/myservices/foo 2018 2019 ``` 2020 2021 ##### Example: resource list using `--type service` 2022 2023 This example uses the `type` flag to specific `service`. The other valid type is `component`. Future versions of CycloneDX schema will include more resource types such as "ml" (machine learning) or "tool". 2024 2025 ```bash 2026 ./sbom-utility resource list -i test/cyclonedx/cdx-1-3-resource-list.json --type service -q 2027 ``` 2028 2029 ```bash 2030 resource-type group name version description bom-ref 2031 ------------- ----- ---- ------- ----------- ------- 2032 service Bar Bar service service:example.com/myservices/bar 2033 service Foo Foo service service:example.com/myservices/foo 2034 ``` 2035 2036 **Note** The results would be equivalent to using the `--where` filter: 2037 2038 ```bash 2039 ./sbom-utility resource list -i test/cyclonedx/cdx-1-3-resource-list.json --where "resource-type=service" -q 2040 ``` 2041 2042 ##### Example: list with `name` regex match 2043 2044 This example uses the `where` filter on the `name` field. In this case we supply an exact "startswith" regex. for the `name` filter. 2045 2046 ```bash 2047 ./sbom-utility resource list -i test/cyclonedx/cdx-1-3-resource-list.json --where "name=Library A" -q 2048 ``` 2049 2050 ```bash 2051 resource-type group name version description bom-ref 2052 ------------- ----- ---- ------- ----------- ------- 2053 component Library A 1.0.0 Library A description pkg:lib/libraryA@1.0.0 2054 ``` 2055 2056 --- 2057 2058 ### Schema 2059 2060 You can verify which formats, schemas, versions and variants are available for validation by using the `schema` command. 2061 2062 - **Note**: The `schema` command will default to the `list` subcommand if omitted. 2063 2064 #### Schema supported output formats 2065 2066 This command supports the `--format` flag with any of the following values: 2067 2068 - `txt` (default), `csv`, `md` 2069 2070 #### Schema result sorting 2071 2072 - Formatted results are sorted by `format` (ascending), `version` (descending) and `schema` (descending) 2073 2074 #### Schema examples 2075 2076 ##### Example: schema list 2077 2078 ```bash 2079 ./sbom-utility schema list -q 2080 ``` 2081 2082 ```bash 2083 name variant format version file url 2084 ---- ------- ------ ------- ---- --- 2085 CycloneDX v1.6 development CycloneDX 1.6 schema/cyclonedx/1.6/bom-1.6.schema.json https://raw.githubusercontent.com/CycloneDX/specification/1.6-dev/schema/bom-1.6.schema.json 2086 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 2087 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 2088 CycloneDX v1.4 custom CycloneDX 1.4 schema/test/bom-1.4-custom.schema.json 2089 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 2090 CycloneDX v1.3 custom CycloneDX 1.3 schema/test/bom-1.3-custom.schema.json 2091 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 2092 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 2093 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 2094 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 2095 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 2096 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 2097 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 2098 ``` 2099 2100 #### Adding schemas 2101 2102 Entries for new or "custom" schemas can be added to the `config.json` file by adding a new schema entry and then will need to pass that file on the command line using the `--config-schema` flag. 2103 2104 These new schema entries will tell the schema loader where to find the JSON schema file locally, relative to the utility's executable. 2105 2106 For details see the "[Adding new SBOM formats, schema versions and variants](#adding-new-sbom-formats-schema-versions-and-variants)" section. 2107 2108 #### Embedding schemas 2109 2110 If you wish to have the new schema *embedded in the executable*, simply add it to the project's `resources` subdirectory following the format and version-based directory structure. 2111 2112 --- 2113 2114 ### Vulnerability 2115 2116 This command will extract basic vulnerability report data from an SBOM that has a "vulnerabilities" list or from a standalone VEX in CycloneDX format. It includes the ability to filter reports data by applying regex to any of the named column data. 2117 2118 #### Vulnerability supported output formats 2119 2120 Use the `--format` flag on the to choose one of the supported output formats: 2121 2122 - txt (default), csv, md 2123 2124 #### Vulnerability result sorting 2125 2126 - `txt`, `csv` and `md` formatted results are sorted by vulnerability `id` (descending) then by `created` date (descending). 2127 - `json` results are not sorted 2128 2129 #### Vulnerability Examples 2130 2131 ##### Example: Vulnerability list 2132 2133 The `list` subcommand provides a complete view of most top-level, vulnerability fields. 2134 2135 ```bash 2136 ./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json -q 2137 ``` 2138 2139 ```bash 2140 id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description 2141 -- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- 2142 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. 2143 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 2144 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. 2145 ``` 2146 2147 ###### Example: Vulnerability list summary 2148 2149 This example shows the default text output from using the `--summary` flag: 2150 2151 ```bash 2152 ./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --summary -q 2153 ``` 2154 2155 ```bash 2156 id cvss-severity source-name published description 2157 -- ------------- ----------- --------- ----------- 2158 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. 2159 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 2160 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. 2161 ``` 2162 2163 ##### Example: Vulnerability list with `--where` filter with `description` key 2164 2165 ```bash 2166 ./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --where description=XXE -q 2167 ``` 2168 2169 ```bash 2170 id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description 2171 -- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- 2172 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. 2173 ``` 2174 2175 ##### Example: Vulnerability list with `--where` filter with `analysis-state` key 2176 2177 ```bash 2178 ./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --where analysis-state=not_affected -q 2179 ``` 2180 2181 ```bash 2182 id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description 2183 -- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- 2184 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. 2185 ``` 2186 2187 --- 2188 2189 ### Completion 2190 2191 This command will generate command-line completion scripts, for the this utility, customized for various supported shells. 2192 2193 The completion command can be invoked as follows: 2194 2195 ```bash 2196 ./sbom_utility completion [shell] 2197 ``` 2198 2199 where valid values for `shell` are: 2200 2201 - bash 2202 - fish 2203 - powershell 2204 - zsh 2205 2206 --- 2207 2208 ### Help 2209 2210 The utility supports the `help` command for the root command as well as any supported commands 2211 2212 For example, to list top-level (root command) help which lists the supported "Available Commands": 2213 2214 ```bash 2215 ./sbom-utility help 2216 ``` 2217 2218 A specific command-level help listing is also available. For example, you can access the help for the `validate` command: 2219 2220 ```bash 2221 ./sbom-utility help validate 2222 ``` 2223 2224 --- 2225 2226 ## Experimental Commands 2227 2228 This section contains *experimental* commands that will be promoted once vetted by the community over two or more point releases. 2229 2230 ### Diff 2231 2232 This *experimental* command will compare two *similar* BOMs and return the delta (or "diff") in JSON (diff-patch format) or text. This functionality is "JSON aware" and based upon code ancestral to that used to report file diffs between `git commit`s. 2233 2234 ##### Recommendations 2235 2236 - *Even with BOMs that **SHOULD** be similar, it is recommended to use the **[trim](#trim)** command to remove data that changes within a BOM from one generation to another *or* is often proprietary such as: **bom-ref**, **hashes**, **timestamp**(s), **properties**, etc.*. 2237 - *In addition, it is recommended that you also `--normalize` trimmed output data to better guarantee ordering of fields and array data.* 2238 2239 ##### Notes 2240 2241 - This command is undergoing analysis and tests which are exposing some underlying issues around "moved" objects in dependent diff-patch packages that may not be fixable and have no alternatives. 2242 - *Specifically, the means by which "moved" objects are assigned "similarity" scores appears flawed in the case of JSON.* 2243 - *Additionally, some of the underlying code relies upon Go maps which do not preserve key ordering.* 2244 2245 #### Diff supported output formats 2246 2247 Use the `--format` flag on the to choose one of the supported output formats: 2248 2249 - txt (default), json 2250 2251 #### Diff Examples 2252 2253 ##### Example: Add, delete and modify 2254 2255 ```bash 2256 ./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 2257 ``` 2258 2259 ```bash 2260 { 2261 "licenses": [ 2262 0: { 2263 "license": { 2264 - "id": "Apache-1.0" 2265 + "id": "GPL-2.0" 2266 } 2267 }, 2268 -+ 2=>1: { 2269 -+ "license": { 2270 -+ "id": "GPL-3.0-only" 2271 -+ } 2272 -+ }, 2273 2: { 2274 "license": { 2275 "id": "GPL-3.0-only" 2276 } 2277 }, 2278 3: { 2279 "license": { 2280 "id": "MIT" 2281 } 2282 } 2283 ] 2284 } 2285 ``` 2286 2287 --- 2288 2289 ## Contributing 2290 2291 Contributions are welcome under the Apache 2.0 license. Help is wanted in the following areas: 2292 2293 - [TODO list](#todo-list) 2294 - [Priority features](#priority-features) 2295 2296 #### TODO list 2297 2298 The entirety of the code contains the tag "**TODO**" with comments of things that are features or improvements conceived while authoring the base functionality. Most of these do not have active issues opened form them. 2299 2300 Feel free to "grep" for the "TODO" tag, open an issue and/or submit a draft PR. 2301 2302 #### Priority features 2303 2304 An ad-hoc list of featured "TODOs" geared at making the tool more accessible, extensible and useful especially around "core" commands such as validation. 2305 2306 - **Merge command** Support merge of two (both validated) SBOMs with de-duplication and configurable. Please note that some method of normalization prior to merge will be necessary. 2307 - **Remote Schema loading** Support using SBOM schema files that are remotely hosted (network accessible) from known, trusted source locations (e.g., releases of SPDX, CycloneDX specification schemas). Note that the config file has an existing `url` field per entry that can be used for this purpose. 2308 - **--orderby** Support ordering of query result sets by comparison of values from a specified field key. 2309 - **license.json** Document license policy configuration JSON schema structure and how to add entries relative to a CycloneDX `LicenseChoice` object for entries with SPDX IDs and those without. 2310 - **license.json** Add entries for all SPDX licenses listed in v3.21. 2311 - See issue: https://github.com/CycloneDX/sbom-utility/issues/12 2312 - **Go libraries** Replace `go-prettyjson`, `go-multimap` libraries with alternatives that produce maintained releases. 2313 2314 --- 2315 2316 ## Design considerations 2317 2318 ### Memory safety 2319 2320 The utility itself is written in `Go` to advantage the language's built-in typing enforcement and memory safe features and its ability to be compiled for a wide range of target platforms and architectures. 2321 2322 ### Consistent output 2323 2324 The utility also is designed to produce output formats (e.g., JSON) and handle exit codes consistently to make it immediately useful standalone or as part of automated Continuous Integration (CI) tool chains for downstream use or inspection. 2325 2326 ### Security and integrity focus 2327 2328 Further commands and reports are planned that prioritize use cases that enable greater insight and analysis of the legal, security and compliance data captured in the SBOM such as component **provenance** and **signage** (e.g., verifying resource identities by hashes or fingerprints). 2329 2330 In addition, inclusion of **Continuous Integration and Delivery (CI/CD)** or "build integrity" information around the BOM component is anticipated as part of the CycloneDX Formulation work which will require features for workflow insights. 2331 2332 ### Functional priorities 2333 2334 The utility additionally prioritizes commands that help provide insight into contents of the BOM to search for and report on missing (i.e., completeness) or specific data requirements (e.g., organization or customer-specific requirements). 2335 2336 In general, the goal of these prioritized commands is to support data verification for many of the primary BOM use cases as identified by the CycloneDX community (see https://cyclonedx.org/use-cases/). Functional development has focused on those use cases that verify inventory (resource identity), legal compliance (e.g., license), and security analysis (e.g., vulnerability) which are foundational to any SBOM. 2337 2338 ### Support all BOM formats 2339 2340 In the future, we envision support for additional kinds of BOMs (e.g., Hardware (HBOM), Machine Learning (MLBOM), etc.) with each again having different data requirements and levels of maturity which will increase the need for domain-specific validation. Specifically, this utility intends to support the work of the [OWASP Software Component Verification Standard (SCVS)](https://owasp.org/www-project-software-component-verification-standard/) which is defining a BOM Maturity Model (BMM). 2341 2342 --- 2343 2344 ## Development 2345 2346 The following development-oriented topics are included in this section: 2347 2348 - [Prerequisites](#prerequisites) 2349 - [Building](#building) 2350 - [Running from source](#running-from-source) 2351 - [Debugging](#debugging) 2352 - [Using VSCode](#vscode) 2353 - [Adding new SBOM formats, schema versions and variants](#adding-new-sbom-formats-schema-versions-and-variants) 2354 2355 ### Prerequisites 2356 2357 - Go v1.20.1 or higher: see [https://go.dev/doc/install](https://go.dev/doc/install) 2358 - `git` client: see [https://git-scm.com/downloads](https://git-scm.com/downloads) 2359 2360 ### Building 2361 2362 To build an executable of the utility compatible with your local computer's architecture use the `build` target in the project's `Makefile`: 2363 2364 ```bash 2365 cd sbom-utility/ 2366 make build 2367 ``` 2368 2369 The will produce a binary named `sbom-utility` with version set to `latest` in the project's `release` directory. 2370 2371 ```bash 2372 $ ls 2373 -rwxr-xr-x 1 User1 staff 11501122 Jan 24 08:29 sbom-utility 2374 ``` 2375 2376 ```bash 2377 $ ./sbom-utility version 2378 Welcome to the sbom-utility! Version `latest` (sbom-utility) (darwin/arm64) 2379 ``` 2380 2381 **Note** The binary created using `make build` will be for the local system's operating system and architecture (i.e., `GOOS`, `GOARCH`). This would effectively match what would be reported using the `uname -s -m` unix command when run on the same local system. 2382 2383 If you wish to build binaries for all supported combinations of `GOOS` and `GOARCH` values, use the `release` target (i.e., `make release`) which will produce named binaries of the form `sbom-utility-${GOOS}-${GOARCH}` under the `release` directory (e.g., `sbom-utility-darwin-amd64`). 2384 2385 ### Running from source 2386 2387 Developers can run using the current source code in their local branch using `go run main.go`. For example: 2388 2389 ```bash 2390 go run main.go validate -i test/cyclonedx/cdx-1-4-mature-example-1.json 2391 ``` 2392 2393 ### Debugging 2394 2395 #### VSCode 2396 2397 This project was developed using VSCode and can be seamlessly loaded as a project. 2398 2399 ##### Debugging globals 2400 2401 In order to see global variables while debugging a specific configuration, you can add the `"showGlobalVariables": true` to it within your `launch.json` config. file: 2402 2403 ```json 2404 { 2405 "showGlobalVariables": true, 2406 "name": "Test name", 2407 "type": "go", 2408 "request": "launch", 2409 "mode": "debug", 2410 "program": "main.go", 2411 "args": ["validate", "-i", "test/cyclonedx/cdx-1-3-min-required.json","-t"] 2412 }, 2413 ``` 2414 2415 or add it globally to the `settings.json` file: 2416 2417 1. Use `Command-Shift-P` to open `settings.json` 2418 2. Select "Preferences: Open Settings (JSON)" 2419 3. Add the following block at the top level: 2420 2421 ```json 2422 "go.delveConfig": { 2423 "showGlobalVariables": true 2424 }, 2425 ``` 2426 2427 **Note**: *The `showGlobalVariables` setting was only recently disabled as the default in VSCode as a stop-gap measure due to performance (loading) problems under Windows.* 2428 2429 ### Adding new SBOM formats, schema versions and variants 2430 2431 The utility uses the [`config.json`](./config.json) file (either the default, embedded version or the equivalent provided on the command line using `--config-schema` flag) to lookup supported formats and their associated versioned JSON schema files. To add another SBOM format simply add another entry to the `format` array in the document: 2432 2433 ```json 2434 { 2435 "canonicalName": "SPDX", 2436 "propertyKeyFormat": "SPDXID", 2437 "propertyKeyVersion": "spdxVersion", 2438 "propertyValueFormat": "SPDXRef-DOCUMENT", 2439 "schemas": [ 2440 { 2441 ... 2442 } 2443 ] 2444 ... 2445 } 2446 ``` 2447 2448 The value for `propertyKeyFormat` should be the exact name of key field that would appear in the JSON SBOM itself which can be used to confirm it is indeed a format match. In addition, the corresponding value to match for that key should be declared in the `propertyValueFormat` value. 2449 2450 The fields `canonicalName`, `propertyKeyFormat`, `propertyKeyVersion`, and `propertyValueFormat` are required. The `format` object **MUST** have at least one valid `schema` object. 2451 2452 An example `schema` object for the canonical SPDX v2.3 (default, no variant) schema appears as follows: 2453 2454 ```json 2455 { 2456 { 2457 "version": "SPDX-2.3", 2458 "variant": "", 2459 "name": "SPDX v2.3", 2460 "file": "schema/spdx/2.3/spdx-schema.json", 2461 "development": "https://github.com/spdx/spdx-spec/blob/development/v2.3/schemas/spdx-schema.json", 2462 "url": "https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3/schemas/spdx-schema.json", 2463 "default": true 2464 }, 2465 }, 2466 ``` 2467 2468 - Add a copy of the JSON schema file locally in the project under the structure `resources/schema/<format>/<version>/<schema filename>`. 2469 - **Note** If the schema exists under the `resources` directory, it will automatically be embedded in in the executable binary when built using `go build` which includes using the project's `Makefile`. 2470 - Assure **only one** `schema` object entry for a given format and version has the value `latest` set to `true`. This latest schema will be used when the SBOM being validated does not have a clear version declared **or** used with the `--force latest` flag. 2471 - If you have a customized or "variant" version of a schema (with the same format and version values) you wish to use for validation (e.g., a `corporate`or `staging` version with added requirements or for testing an unreleased version), you can create an entry that has the same `version` as another entry, but also declare its `variant` name *(non-empty value)*. This value can be supplied on the commend line with the `--variant <variant name>` flag to force the validator to use it instead of the default *(empty variant value)*. 2472 2473 --- 2474 2475 ## Testing 2476 2477 Testing implementation and invocation, with examples, is described in this section including: 2478 2479 - [Authoring Go test files](#authoring-go-test-files) 2480 - [Running tests](#running-tests) 2481 2482 ### Authoring Go test files 2483 2484 The built-in `go test` command will execute all functional tests that appear in files named with the pattern: `<filename>_test.go`. These files are executed from within the same directory (package) where its respective `<filename>.go` source code file is located and sets that same as the "working directory". 2485 2486 *For example,* tests in the `validate_test.go` file are executed from the `cmd` subdirectory. 2487 2488 This is normally a problem as the actual test SBOM JSON test files are located relative the project root, one level higher, and would not be found by the "working directory". In order to correct for that, the test working directory is automatically changed for all tests within the `TestMain` routine found in `root_test.go`. 2489 2490 ### Running tests 2491 2492 The `Makefile` includes a `test` target for convenience which will use `go test` to run all tests found in all subdirectories: 2493 2494 ```bash 2495 make test 2496 ``` 2497 2498 #### Running tests for a single package 2499 2500 The `test_cmd` target will use run only the test found in the `cmd` package: 2501 2502 ```bash 2503 make test_cmd 2504 ``` 2505 2506 The `test_schema` target will use run only the test found in the `schema` package: 2507 2508 ```bash 2509 make test_schema 2510 ``` 2511 2512 #### Using `go test` 2513 2514 Example: running all tests in the `cmd` package: 2515 2516 ```bash 2517 go test github.com/CycloneDX/sbom-utility/cmd -v 2518 ``` 2519 2520 Example: running all tests in the `schema` package: 2521 2522 ```bash 2523 go test github.com/CycloneDX/sbom-utility/schema -v 2524 ``` 2525 2526 #### Running tests in quiet mode 2527 2528 Run in "quiet" mode to not see error test output: 2529 2530 ```bash 2531 go test github.com/CycloneDX/sbom-utility/cmd -v --quiet 2532 ``` 2533 2534 run an individual test within the `cmd` package: 2535 2536 ```bash 2537 go test github.com/CycloneDX/sbom-utility/cmd -v -run TestValidateCdx14MinRequiredBasic 2538 ``` 2539 2540 #### Debugging `go test` 2541 2542 Simply append the flags `--args --trace` or `--args --debug` to your `go test` command to enable trace or debug output for your designated test(s): 2543 2544 ```bash 2545 go test github.com/CycloneDX/sbom-utility/cmd -v --args --trace 2546 ``` 2547 2548 **Note**: You should always use the `--args` flag of `go test` as this will assure non-conflict with `go test` built-in flags which is the case with the `--trace` flag. 2549 2550 #### Eliminating extraneous test output 2551 2552 Several tests will still output error and warning messages as designed. If these messages are distracting, you can turn them off using the `--quiet` flag. 2553 2554 ```bash 2555 go test github.com/CycloneDX/sbom-utility/cmd -v --quiet 2556 ``` 2557 2558 --- 2559 2560 ## Releasing 2561 2562 ### GitHub 2563 2564 In order to initiate the release workflow, simply go to the release page of the repository: 2565 2566 - [https://github.com/CycloneDX/sbom-utility/releases](https://github.com/CycloneDX/sbom-utility/releases) 2567 2568 and click on the `Draft a new release` button. Follow the instructions to create a new version tag, provide an appropriate release title and description and `publish` the release. The GitHub release workflow will be triggered automatically. 2569 2570 ### Local 2571 2572 For local development, you may choose to make a release on your machine using the `Makefile` directive `release`: 2573 2574 ```bash 2575 make release 2576 ``` 2577 2578 After all builds are done, the binaries and config. files can be verified to be in the target `release` directory: 2579 2580 ```bash 2581 ls release 2582 ``` 2583 2584 ```bash 2585 total 131680 2586 drwxr-xr-x 8 User1 staff 256 Jan 27 14:43 . 2587 drwxr-xr-x 27 User1 staff 864 Jan 27 14:43 .. 2588 -rw-r--r-- 1 User1 staff 7121 Jan 27 14:43 config.json 2589 -rw-r--r-- 1 User1 staff 1346 Jan 27 14:43 custom.json 2590 -rw-r--r-- 1 User1 staff 62532 Jan 27 14:43 license.json 2591 -rwxr-xr-x 1 User1 staff 11336640 Jan 27 14:43 sbom-utility-darwin-amd64 2592 -rwxr-xr-x 1 User1 staff 11146770 Jan 27 14:43 sbom-utility-darwin-arm64 2593 -rwxr-xr-x 1 User1 staff 11495647 Jan 27 14:43 sbom-utility-linux-amd64 2594 -rwxr-xr-x 1 User1 staff 11076025 Jan 27 14:43 sbom-utility-linux-arm64 2595 -rwxr-xr-x 1 User1 staff 11416576 Jan 27 14:43 sbom-utility-windows-amd64 2596 -rwxr-xr-x 1 User1 staff 10934272 Jan 27 14:43 sbom-utility-windows-arm64 2597 ... 2598 ``` 2599 2600 - *Please also note that the common `*.json` configuration files are also copied to the `release` directory.* 2601 2602 ### Versioning 2603 2604 to produce a release version you can set the following flags and invoke `go build` directly: 2605 2606 ```bash 2607 BINARY=sbom-utility 2608 VERSION=latest 2609 LDFLAGS=-ldflags "-X main.Version=${VERSION} -X main.Binary=${BINARY}" 2610 $ go build ${LDFLAGS} -o ${BINARY} 2611 ``` 2612 2613 **TODO**: Update the `Makefile's` `release` target to conditionally pull the release version from environment variable values and only uses the hardcoded values as defaults when not found in the runtime build environment. 2614 2615 --- 2616 2617 ## BOM References 2618 2619 ### Software-Bill-of-Materials (SBOM) 2620 2621 - [NTIA - SBOM Minimum Requirements](https://www.ntia.doc.gov/blog/2021/ntia-releases-minimum-elements-software-bill-materials) 2622 - [CISA - Software Bill of Materials (SBOM)](https://www.cisa.gov/sbom) 2623 - [FOSSA - Software Bill Of Materials: Formats, Use Cases, and Tools](https://fossa.com/blog/software-bill-of-materials-formats-use-cases-tools/) 2624 2625 #### Guides 2626 2627 - [FOSSA](https://fossa.com/) 2628 - *["A Practical Guide to CycloneDX"](https://fossa.com/cyclonedx)* 2629 2630 ### CycloneDX 2631 2632 - [CycloneDX Specification Overview](https://cyclonedx.org/specification/overview/) 2633 - GitHub: https://github.com/CycloneDX 2634 - Specifications (by branch): https://github.com/CycloneDX/specification 2635 - Schemas (all versions): https://github.com/CycloneDX/specification/tree/master/schema 2636 - Examples: https://github.com/CycloneDX/sbom-examples 2637 - CycloneDX Tool Center : https://cyclonedx.org/tool-center/ 2638 2639 #### CycloneDX use cases 2640 2641 - [CycloneDX Use Cases](https://cyclonedx.org/use-cases/) (comprehensive), including: 2642 - [Inventory](https://cyclonedx.org/use-cases/#inventory) 2643 - [License Compliance](https://cyclonedx.org/use-cases/#license-compliance) 2644 - [Known Vulnerabilities](https://cyclonedx.org/use-cases/#known-vulnerabilities) 2645 2646 - [CycloneDX Vulnerability Exploitability Exchange (VEX) format Overview](https://cyclonedx.org/capabilities/vex/) 2647 - Examples: https://github.com/CycloneDX/bom-examples/tree/master/VEX 2648 2649 ### SPDX 2650 2651 - GitHub: https://github.com/spdx 2652 - Specifications (by branch): https://github.com/spdx/spdx-spec 2653 - Schemas (by branch): 2654 - [v2.3.1](https://github.com/spdx/spdx-spec/tree/development/v2.3.1/schemas) 2655 - [v2.3](https://github.com/spdx/spdx-spec/tree/development/v2.3/schemas) 2656 - [v2.2.2](https://github.com/spdx/spdx-spec/tree/development/v2.2.2/schemas) 2657 - SPDX Examples: [https://github.com/spdx/spdx-examples](https://github.com/spdx/spdx-examples) 2658 2659 - Tools 2660 - [SPDX Online Tool](https://tools.spdx.org/app/) 2661 - **Note** Used the [convert](https://tools.spdx.org/app/convert/) tool to convert SPDX examples from `.tv` format to `.json`; however, conversion of [`example6-bin.spdx`](https://github.com/spdx/spdx-examples/blob/master/example6/spdx/example6-bin.spdx) resulted in an error.