{"id":20617781,"url":"https://github.com/cyclonedx/sbom-utility","last_synced_at":"2025-10-23T18:07:22.287Z","repository":{"id":143000706,"uuid":"587144814","full_name":"CycloneDX/sbom-utility","owner":"CycloneDX","description":"Utility that provides an API platform for validating, querying and managing BOM data","archived":false,"fork":false,"pushed_at":"2024-11-19T14:26:48.000Z","size":10357,"stargazers_count":104,"open_issues_count":25,"forks_count":14,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-29T16:08:39.778Z","etag":null,"topics":["bill-of-materials","bom","cyclonedx","hacktoberfest","mbom","obom","owasp","package-url","purl","saasbom","sbom","sbom-quality","sbom-tool","software-bill-of-materials","spdx","spdx-license","spdx-sbom","vdr","vex"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CycloneDX.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://owasp.org/donate/?reponame=www-project-cyclonedx\u0026title=OWASP+CycloneDX"]}},"created_at":"2023-01-10T04:00:14.000Z","updated_at":"2025-02-20T18:08:46.000Z","dependencies_parsed_at":"2023-12-17T05:24:41.966Z","dependency_job_id":"14947ee0-82da-42c4-bd6e-d68687320f36","html_url":"https://github.com/CycloneDX/sbom-utility","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CycloneDX%2Fsbom-utility","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CycloneDX%2Fsbom-utility/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CycloneDX%2Fsbom-utility/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CycloneDX%2Fsbom-utility/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CycloneDX","download_url":"https://codeload.github.com/CycloneDX/sbom-utility/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369952,"owners_count":20927928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bill-of-materials","bom","cyclonedx","hacktoberfest","mbom","obom","owasp","package-url","purl","saasbom","sbom","sbom-quality","sbom-tool","software-bill-of-materials","spdx","spdx-license","spdx-sbom","vdr","vex"],"created_at":"2024-11-16T12:05:57.367Z","updated_at":"2025-10-23T18:07:22.277Z","avatar_url":"https://github.com/CycloneDX.png","language":"Go","funding_links":["https://owasp.org/donate/?reponame=www-project-cyclonedx\u0026title=OWASP+CycloneDX"],"categories":[],"sub_categories":[],"readme":"[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![License](https://img.shields.io/badge/CycloneDX-v1.2,1.3,1.4,1.5,1.6-darkcyan.svg)](https://github.com/CycloneDX/specification)\n[![License](https://img.shields.io/badge/SPDX-v2.1,2.2,2.3-purple.svg)](https://github.com/spdx/spdx-spec)\n[![Go Report Card](https://goreportcard.com/badge/github.com/CycloneDX/sbom-utility)](https://goreportcard.com/badge/github.com/CycloneDX/sbom-utility)\n\u003c!--![CodeQL](https://github.com/CycloneDX/sbom-utility/actions/workflows/codeql.yml/badge.svg)--\u003e\n![golangci-lint](https://github.com/CycloneDX/sbom-utility/actions/workflows/golangci-lint.yml/badge.svg)\n\n# sbom-utility\n\nThe **`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.\n\n- *Organizations may also design and supply **\"custom JSON schema\"** variants to the validate command which are perhaps designed to enforce additional data-compliance requirements.*\n\nThe utility also offers commands that support analysis and editing of BOM document data including **trim**, **patch** (IETF RFC 6902) and **diff** *(experimental)*.\n\nIn 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.\n\n- *Report output can be produced in several formats (e.g., `txt`, `csv`, `md` (markdown) and `json`) to accommodate further processing.*\n\n\u003e **Note**: *This utility supports all CycloneDX BOM variants, such as Software (**SBOM**), Hardware (**HBOM**), Manufacturing (**MBOM**), Machine Learning and AI (**MLBOM**), Cryptographic (**CBOM**), etc.*\n\n---\n\n\u003ch5\u003e\u003cimg alt=\"New!\" src=\"docs/new-3d.png\" align=\"left\" width=\"100\" height=\"100\" style=\"height: 8em; width:8em; vertical-align: middle;\"\u003e\u003c/h5\u003e\n\n **Custom JSON Validation**\u003c/br\u003eDon't want to create custom CycloneDX and SPDX schemas to enforce your BOM requirements on the structure, fields, values and more?  Good news! Now you can add your own custom validation of BOM content using the new `--custom` flag on the `validate` command!\n\n- Learn how to use this long-awaited, **experimental** feature by reading the [Custom validation examples](docs/custom-examples.md) page.\n\n---\n\n### Command Overview\n\nThe following commands, which operate against input BOMs and their data, are offered by the utility:\n\n| Command \u003cfont size=\"-1\"\u003e*[`subcommand`]*\u003c/font\u003e | Description |\n| :-- | :-- |\n| **[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.|\n| **[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. |\n| **[trim](#trim)** | Removes specified JSON information from the input JSON BOM document and produce output BOMs with reduced or targeted sets of information.\u003c/br\u003e\u003c/br\u003e*A \"SQL-like\" set of parameters allows for fine-grained specification of which fields should be trimmed from which document paths.* |\n| **[diff](#diff)** | **Experimental**[\u003csup\u003e1\u003c/sup\u003e](#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.* |\n| **[query](#query)** | Retrieves JSON data from BOMs using SQL-style query statements (i.e., `--select \u003cdata fields\u003e --from \u003cBOM object\u003e --where \u003cfield=regex\u003e`). The JSON data can be used to create custom listings or reports. |\n| **[component](#component)** **[`list`](#component-list-command)** | Produces filterable listings of hardware or software components declared in the BOM. |\n| **[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. |\n| **[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. |\n| **[resource `list`](#resource)** | Produces filterable listings of resources (i.e., components and services) declared in the BOM. |\n| **[schema `list`](#schema)** | Produces filterable listings of schema formats, versions and variants supported by the `validation` command.\u003c/br\u003e\u003c/br\u003e **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). |\n| **[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. |\n\n\u003e **Experimental commands**:\n*Testing, feedback and helpful suggestions and code commits are appreciated on experimental commands.*\n\n---\n\n### Project Index\n\n- [Installation](#installation)\n- [Running](#running)\n- [Commands](#commands)\n- [Contributing](#contributing)\n- [Design considerations](#design-considerations)\n- [Development](#development)\n- [Testing](#testing)\n- [Releasing](#releasing)\n- [BOM References](#bom-references)\n  - [CycloneDX](#cyclonedx), [SPDX](#spdx)\n\n---\n\n### Installation\n\nDownload 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.\n\n- [https://github.com/CycloneDX/sbom-utility/releases](https://github.com/CycloneDX/sbom-utility/releases)\n\nThe source archive will contain the following files under the root directory:\n\n- `sbom-utility` - binary executable. This is all most need for non-customized configurations.\n- `LICENSE` - the software license for the utility (i.e. Apache 2)\n- `sbom-utility-\u003cversion\u003e.sbom.json` - a simple Software Bill-of-Materials (SBOM) for the utility\n\nas well as sample configuration files:\n\n- `config.json` *(optional)* - copy of the default schema configuration file for optional customization (to be passed on the command line)\n- `license.json` *(optional)* - copy of the default license policy configuration file for optional customization (to be passed on the command line)\n- `custom.json` *(experimental, unused)* - custom validation configuration file\n\n---\n\n## Running\n\nFor 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.*\n\n- **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.*\n\n##### MacOS - Granting executable permission\n\nOn 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.\n\n- 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)\n\n---\n\n## Commands\n\nThis section provides detailed descriptions of all commands, supported flags and output formats along with usage examples.\n\nAll commands generate consistent [exit codes](#exit-codes) as well as share some [persistent flags](#persistent-flags) which are described here:\n\n- [Exit codes](#exit-codes): Including: *`0`: no error, `1`: application error, `2`: validation error, etc.*\n- [Persistent flags](#persistent-flags) Including: *`--input`, `--output`, `--format`, `--quiet`, `--where`, etc.*\n\nConvenient links to each command:\n\n- [validate](#validate): Validates BOM data against declared or required JSON schema.\n- [trim](#trim): Removes uninteresting or necessary fields and data from a BOM.\n- [patch](#patch): Patches BOMs using IETF RFC 6902 records.\n- [diff](#diff): *(Experimental)*: Displays the differences between two similar BOMs. *Please read recommendations before executing.*\n- [query](#query): Extracts JSON objects and fields from a BOM using SQL-like queries.\n- [component list](#component): Lists all component information found in a BOM.\n- [license](#license)\n  - [list](#license-list-subcommand): Lists all license information found in a BOM.\n  - [policy](#license-policy-subcommand): Lists configurable license usage policies found in the `license.json` file.\n- [resource list](#resource): Lists all resource information by type (e.g., components, services).\n- [schema list](#schema): Lists supported JSON schemas by BOM format, version and variant.\n- [vulnerability list](#vulnerability): Lists vulnerability (i.e., `VEX`) information included in a BOM or standalone `VDR` BOM.\n- [completion](#completion): Generates command-line completion scripts for the this utility.\n- [help](#help): Displays help and usage information for the utility or currently specified command.\n\n---\n\n### Exit codes\n\nAll 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.\n\nThe SBOM Utility always returns one of these 3 codes to accommodate logic in BASH (shell) scripting:\n\n- `0`= no error (valid)\n- `1`= application error\n- `2`= validation error\n\n##### Example: exit code\n\nThis example uses the `schema` list command to verify its exit code:\n\n```bash\n./sbom-utility schema list\n```\n\nverify the exit code:\n\n```bash\necho $?\n```\n\nwhich returns `0` (zero) or \"no error\":\n\n```bash\n0\n```\n\n---\n\n### Persistent flags\n\nThis section describes some of the important command line flags that apply to most of the utility's commands.\n\n- [format flag](#format-flag): with `--format`\n- [indent flag](#indent-flag): with `--indent`\n- [input flag](#input-flag): with `--input` or `-i`\n- [output flag](#output-flag): with `--output` or `-o`\n- [quiet flag](#quiet-flag): with `--quiet` or `-q`\n- [where flag](#where-flag-output-filtering): with `--where`\n\n#### Format flag\n\nAll `list` subcommands support the `--format` flag with the following values:\n\n- `txt`: text (tabbed tables)\n- `csv`: Comma Separated Value (CSV), e.g., for spreadsheets\n- `md`: Markdown (GitHub-compliant tables)\n\nSome commands, which can output lists of JSON objects, also support JSON format using the `json` value.\n\n##### Example: `--format` flag\n\nThis example uses the `--format` flag on the `schema` command to output in markdown:\n\n```bash\n./sbom-utility schema --format md -q\n```\n\n```md\n|name|format|version|variant|file (local)|url (remote)|\n|:--|:--|:--|:--|:--|:--|\n|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|\n|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|\n|CycloneDX/specification/master/schema/bom-1.3-strict.schema.json|\n|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|\n|CycloneDX/specification/master/schema/bom-1.2-strict.schema.json|\n|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|\n|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|\n|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|\n|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|\n|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|\n```\n\n#### Indent flag\n\nThis 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).\n\n##### Example: indent flag on the query command\n\n```bash\n./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 2 -q\n```\n\noutput with `indent 2`:\n\n```json\n{\n  \"name\": \"juice-shop\",\n  \"version\": \"11.1.2\"\n}\n```\n\n```bash\n./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 6 -q\n```\n\noutput with `indent 6`:\n\n```json\n{\n      \"name\": \"juice-shop\",\n      \"version\": \"11.1.2\"\n}\n```\n\n#### Input flag\n\nAll `list` subcommands and the `validate` command support the `--input-file \u003cfilename\u003e` flag (or its short-form `-i \u003cfilename\u003e`) to declare file contents (i.e., BOM data) the commands will read and operate on.\n\n#### Standard input (stdin)\n\nAll 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.\n\n##### Example of stdin using pipe\n\n```bash\n cat examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json | ./sbom-utility resource list -i -\n```\n\n##### Example of stdin using redirect\n\n```bash\n./sbom-utility validate -i - \u003c examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json\n```\n\n#### Output flag\n\nAll `list` subcommands and the `validate` command support the `--output-file \u003cfilename\u003e` flag (or its short-form `-o \u003cfilename\u003e`) to send formatted output to a file.\n\n##### Example: `--output-file` flag\n\nThis example uses the `schema` command to output to a file named `output.txt` with format set to `csv`:\n\n```bash\n./sbom-utility schema --format csv -o output.csv\n```\n\nVerify the contents of `output.csv` contain CSV formatted output:\n\n```bash\ncat output.csv\n```\n\n```csv\nName,Format,Version,Variant,File (local),URL (remote)\nCycloneDX 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\nCycloneDX 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\nCycloneDX 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\nCycloneDX 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\nSPDX 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\nSPDX 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\nSPDX 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\nSPDX 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\n```\n\n- **Note**: You can verify that `output.csv` loads within a spreadsheet app like MS Excel.\n\n#### Quiet flag\n\nAll 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.\n\n##### Example: `--quiet` flag\n\nThis 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.\n\n```bash\n./sbom-utility schema list --quiet\n```\n\n```bash\nname                          format     version   variant      file (local)                                     url (remote)\n----                          ------     -------   -------      ------------                                     ------------\nCycloneDX 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\nCycloneDX 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\nCycloneDX 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\nCycloneDX 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\nSPDX 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\n...\n```\n\n#### Where flag (output filtering)\n\nAll `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.\n\nMultiple key-value (i.e., column-title=regex) pairs can be provided on the same `--where` filter flag using commas.\n\n**Syntax**: `[--where key=regex[,...]]`\n\nSee each command's section for contextual examples of the `--where` flag filter usage.\n\n---\n\n### Validate\n\nThis command will parse standardized SBOMs and validate it against its declared format and version (e.g., SPDX 2.3, CycloneDX 1.6).\n\n- Custom  variants of standard JSON schemas can be used for validation by supplying the `--variant` name as a flag.\n- Explicit JSON schemas can be specified using the `--force` flag.\n\n#### Validating using supported schemas\n\nUse the [schema](#schema) command to list supported schemas formats, versions and variants.\n\n- A \"supported\" schema is already **\"built-in\"** to the utility resources along with any dependent schemas it imports.\n- This means that BOM files **can be validated when there is no network connection** to load the schemas from remote locations (a.k.a., *\"off-line\"* mode).\n\n#### Validating using \"custom\" schemas\n\nCustomized JSON schemas can also be permanently configured as named schema \"variants\" within the utility's configuration file. See [adding schemas](#adding-schemas).\n\n- **Overriding default schema**\n  - Using the [`--force` flag](#--force-flag) and passing in a URI to an alternative JSON schema.\n- **\"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).\n  - **Note**: *These variants need to be built into the utility binary as a resource.*\n\n#### Validate flags\n\nThe following flags can be used to improve performance when formatting error output results:\n\n##### `--force` flag\n\nYou can override the schema used for validation *(which defaults to the schema that matches the declared format and version found in the input BOM file)* by providing a different one using the `--force` flag. This may be useful to verify a BOM contents against a newer specification version or provide a customized schema.\n  - **Note**: *The `--force` flag works with schema files with valid URIs which include URLs (e.g., 'https://') and files (e.g., 'file://').*\n\n##### `--custom \u003cfilename\u003e` flag *`(experimental)`*\n\nIn addition to validating the the BOM input file using the standard CycloneDX schema, you now can provide a custom JSON file that will apply a built-in set of validation functions to selected parts of the BOM document that can validate JSON elements, property keys and values.\n\n- Learn how to use this long-awaited, **experimental** feature by reading the [Custom validation examples](docs/custom-examples.md) page.\n\nThe current set of functions that can achieve this includes:\n\n- `isUnique` - checks uniqueness of array items given a property name as key\n- `hasProperties` - can verify that a named property exists on a select element and can also enforce the corresponding property has the expected value using regex.\n\n**Note**: *More functions are planned for future releases if use cases are found.*\n\n##### `--error-limit` flag\n\nUse 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.\n\n##### `--error-value` flag\n\nUse 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.\n\n##### `--colorize` flag\n\nUse 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.\n\n#### Validate Examples\n\n##### Example: Validate using inferred format and schema\n\nValidating the \"juice shop\" SBOM (CycloneDX 1.2) example provided in this repository.\n\n```bash\n./sbom-utility validate -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json\n```\n\n```bash\n[INFO] Attempting to load and unmarshal data from: 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json'...\n[INFO] Successfully unmarshalled data from: 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json'\n[INFO] Determining file's BOM format and version...\n[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.2' (latest)\n[INFO] Matching BOM schema (for validation): schema/cyclonedx/1.2/bom-1.2.schema.json\n[INFO] Loading schema 'schema/cyclonedx/1.2/bom-1.2.schema.json'...\n[INFO] Schema 'schema/cyclonedx/1.2/bom-1.2.schema.json' loaded.\n[INFO] Validating 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json'...\n[INFO] BOM valid against JSON schema: 'true'\n```\n\nYou can also verify the [exit code](#exit-codes) from the validate command:\n\n```bash\necho $?\n```\n\n```bash\n0  // no error (valid)\n```\n\n##### Example: Validate using a remote JSON schema file using '--force' flag\n\n```bash\n./sbom-utility validate -i test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json --force https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json\n```\n\n```bash\n[INFO] Attempting to load and unmarshal data from: 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json'...\n[INFO] Successfully unmarshalled data from: 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json'\n[INFO] Determining file's BOM format and version...\n[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.6' (latest)\n[INFO] Matching BOM schema (for validation): schema/cyclonedx/1.6/bom-1.6.schema.json\n[INFO] Loading schema from '--force' flag: 'https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json'...\n[INFO] Validating document using forced schema (i.e., '--force https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json')\n[INFO] Schema 'schema/cyclonedx/1.6/bom-1.6.schema.json' loaded.\n[INFO] Validating 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json'...\n[INFO] BOM valid against JSON schema: 'true'\n```\n\nYou can also verify the [exit code](#exit-codes) from the validate command:\n\n```bash\necho $?\n```\n\n```bash\n0  // no error (valid)\n```\n\n\n##### Example: Validate using \"custom\" schema variants\n\nThe 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:\n\n```bash\n./sbom-utility validate -i test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json --variant custom\n```\n\nIf you run the sample command above, you would see several \"custom\" schema errors resulting in an invalid SBOM determination (i.e., `exit status 2`):\n\n```text\n[INFO] Attempting to load and unmarshal data from: 'test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json'...\n[INFO] Successfully unmarshalled data from: 'test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json'\n[INFO] Determining file's BOM format and version...\n[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.4' custom\n[INFO] Matching BOM schema (for validation): schema/test/bom-1.4-custom.schema.json\n[INFO] Loading schema 'schema/test/bom-1.4-custom.schema.json'...\n[INFO] Schema 'schema/test/bom-1.4-custom.schema.json' loaded.\n[INFO] Validating 'test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json'...\n[INFO] BOM valid against JSON schema: 'false'\n[INFO] (3) schema errors detected.\n[INFO] Formatting error results ('txt' format)...\n1. {\n        \"type\": \"contains\",\n        \"field\": \"metadata.properties\",\n        \"context\": \"(root).metadata.properties\",\n        \"description\": \"At least one of the items must match\",\n        \"value\": [\n            {\n                \"name\": \"urn:example.com:disclaimer\",\n                \"value\": \"This SBOM is current as of the date it was generated.\"\n            },\n            {\n                \"name\": \"urn:example.com:classification\",\n                \"value\": \"This SBOM is Confidential Information. Do not distribute.\"\n            }\n        ]\n    }\n2. {\n        \"type\": \"const\",\n        \"field\": \"metadata.properties.0.value\",\n        \"context\": \"(root).metadata.properties.0.value\",\n        \"description\": \"metadata.properties.0.value does not match: \\\"This SBOM is current as of the date it was generated and is subject to change.\\\"\",\n        \"value\": \"This SBOM is current as of the date it was generated.\"\n    }\n3. {\n        \"type\": \"number_all_of\",\n        \"field\": \"metadata.properties\",\n        \"context\": \"(root).metadata.properties\",\n        \"description\": \"Must validate all the schemas (allOf)\",\n        \"value\": [\n            {\n                \"name\": \"urn:example.com:disclaimer\",\n                \"value\": \"This SBOM is current as of the date it was generated.\"\n            },\n            {\n                \"name\": \"urn:example.com:classification\",\n                \"value\": \"This SBOM is Confidential Information. Do not distribute.\"\n            }\n        ]\n    }\n[ERROR] invalid SBOM: schema errors found (test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json)\n[INFO] document 'test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json': valid=[false]\n```\n\nconfirming the exit code:\n\n```bash\necho $?\n```\n\n```bash\n2 // SBOM error\n```\n\n###### Why validation failed\n\nThe output shows a first schema error indicating the failing JSON object; in this case,\n\n- the CycloneDX `metadata.properties` field, which is a list of `property` objects.\n- Found that a property with a `name` field with the value  `\"urn:example.com:disclaimer\"` had an incorrect `value`.\n  - 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).\n  - However, it was found to have only a partial match of `\"This SBOM is current as of the date it was generated.\"`.\n\n###### Details of the schema error\n\nUse the `--debug` or `-d` flag to see all schema error details:\n\n```bash\n./sbom-utility validate -i test/custom/cdx-1-4-test-metadata-property-disclaimer-invalid.json --variant custom -d\n```\n\nThe details include the full context of the failing `metadata.properties` object which also includes a `\"urn:example.com:classification\"` property:\n\n```bash\n3. {\n        \"type\": \"number_all_of\",\n        \"field\": \"metadata.properties\",\n        \"context\": \"(root).metadata.properties\",\n        \"description\": \"Must validate all the schemas (allOf)\",\n        \"value\": [\n            {\n                \"name\": \"urn:example.com:disclaimer\",\n                \"value\": \"This SBOM is current as of the date it was generated.\"\n            },\n            {\n                \"name\": \"urn:example.com:classification\",\n                \"value\": \"This SBOM is Confidential Information. Do not distribute.\"\n            }\n        ]\n    }\n```\n\n###### Example: Validate using \"JSON\" output format\n\nThe JSON format will provide an `array` of schema error results that can be post-processed as part of validation toolchain.\n\n```bash\n./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json -q\n```\n\n```json\n[\n    {\n        \"type\": \"unique\",\n        \"field\": \"components\",\n        \"context\": \"(root).components\",\n        \"description\": \"array items[1,2] must be unique\",\n        \"value\": {\n            \"type\": \"array\",\n            \"index\": 1,\n            \"item\": {\n                \"bom-ref\": \"pkg:npm/body-parser@1.19.0\",\n                \"description\": \"Node.js body parsing middleware\",\n                \"hashes\": [\n                    {\n                        \"alg\": \"SHA-1\",\n                        \"content\": \"96b2709e57c9c4e09a6fd66a8fd979844f69f08a\"\n                    }\n                ],\n                \"licenses\": [\n                    {\n                        \"license\": {\n                            \"id\": \"MIT\"\n                        }\n                    }\n                ],\n                \"name\": \"body-parser\",\n                \"purl\": \"pkg:npm/body-parser@1.19.0\",\n                \"type\": \"library\",\n                \"version\": \"1.19.0\"\n            }\n        }\n    },\n    {\n        \"type\": \"unique\",\n        \"field\": \"components\",\n        \"context\": \"(root).components\",\n        \"description\": \"array items[2,4] must be unique\",\n        \"value\": {\n            \"type\": \"array\",\n            \"index\": 2,\n            \"item\": {\n                \"bom-ref\": \"pkg:npm/body-parser@1.19.0\",\n                \"description\": \"Node.js body parsing middleware\",\n                \"hashes\": [\n                    {\n                        \"alg\": \"SHA-1\",\n                        \"content\": \"96b2709e57c9c4e09a6fd66a8fd979844f69f08a\"\n                    }\n                ],\n                \"licenses\": [\n                    {\n                        \"license\": {\n                            \"id\": \"MIT\"\n                        }\n                    }\n                ],\n                \"name\": \"body-parser\",\n                \"purl\": \"pkg:npm/body-parser@1.19.0\",\n                \"type\": \"library\",\n                \"version\": \"1.19.0\"\n            }\n        }\n    }\n]\n```\n\n###### Reducing output size using `error-value=false` flag\n\nIn 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`.\n\nRerunning the same command with this flag set to false yields a reduced set of information.\n\n```bash\n./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json --error-value=false -q\n```\n\n```json\n[\n    {\n        \"type\": \"unique\",\n        \"field\": \"components\",\n        \"context\": \"(root).components\",\n        \"description\": \"array items[1,2] must be unique\"\n    },\n    {\n        \"type\": \"unique\",\n        \"field\": \"components\",\n        \"context\": \"(root).components\",\n        \"description\": \"array items[2,4] must be unique\"\n    }\n]\n```\n\n---\n\n### Trim\n\nThis 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.\n\n#### Trim supported output formats\n\nThis command is used to output, using the [`--output-file` flag](#output-flag), a \"trimmed\" BOM in JSON format.\n\n- `json` (default)\n\n#### Trim flags\n\nTrim 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:\n\n##### Trim `--keys` flag\n\nA comma-separated list of JSON map keys. Similar to the [query command's `--select` flag](#query---select-flag) syntax.\n\n##### Trim `--from` flag\n\nA comma-separated list of JSON document paths using the same syntax as the [query command's `--from` flag](#query---from-flag).\n\n##### Trim `--normalize` flag\n\nA flag that normalizes the BOM data after trimming and prior to output.\n\nThis flag invokes custom code that sorts all components, services, licenses, vulnerabilities, properties, external references, hashes and *most* other BOM data using custom comparators.\n\nEach comparator uses `required` fields and other identifying fields to create *\"composite keys\"* for each unique data structure.\n\n#### Trim examples\n\nThe original BOM used for these examples can be found here:\n\n- [test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json](test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json)\n\n##### Example: Trim `properties` from entire JSON BOM\n\nValidating the \"juice shop\" SBOM (CycloneDX 1.2) example provided in this repository.\n\n```bash\n./sbom-utility trim -i ./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=properties\n```\n\nOriginal BOM with `properties`:\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"serialNumber\": \"urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9\",\n  \"components\": [\n    {\n      \"type\": \"library\",\n      \"bom-ref\": \"pkg:npm/sample@2.0.0\",\n      \"purl\": \"pkg:npm/sample@2.0.0\",\n      \"name\": \"sample\",\n      \"version\": \"2.0.0\",\n      \"description\": \"Node.js Sampler package\",\n      \"properties\": [\n        {\n          \"name\": \"foo\",\n          \"value\": \"bar\"\n        }\n      ]\n    },\n    {\n      \"type\": \"library\",\n      \"bom-ref\": \"pkg:npm/body-parser@1.19.0\",\n      \"purl\": \"pkg:npm/body-parser@1.19.0\",\n      \"name\": \"body-parser\",\n      \"version\": \"1.19.0\",\n      \"description\": \"Node.js body parsing middleware\",\n      \"hashes\": [\n        {\n          \"alg\": \"SHA-1\",\n          \"content\": \"96b2709e57c9c4e09a6fd66a8fd979844f69f08a\"\n        }\n      ]\n    }\n  ],\n  \"properties\": [\n    {\n      \"name\": \"abc\",\n      \"value\": \"123\"\n    }\n  ]\n}\n```\n\nOutput BOM results without `properties`:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"serialNumber\": \"urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9\",\n    \"version\": 1,\n    \"components\": [\n        {\n            \"type\": \"library\",\n            \"bom-ref\": \"pkg:npm/sample@2.0.0\",\n            \"name\": \"sample\",\n            \"version\": \"2.0.0\",\n            \"description\": \"Node.js Sampler package\",\n            \"purl\": \"pkg:npm/sample@2.0.0\"\n        },\n        {\n            \"type\": \"library\",\n            \"bom-ref\": \"pkg:npm/body-parser@1.19.0\",\n            \"name\": \"body-parser\",\n            \"version\": \"1.19.0\",\n            \"description\": \"Node.js body parsing middleware\",\n            \"hashes\": [\n                {\n                    \"alg\": \"SHA-1\",\n                    \"content\": \"96b2709e57c9c4e09a6fd66a8fd979844f69f08a\"\n                }\n            ],\n            \"purl\": \"pkg:npm/body-parser@1.19.0\"\n        }\n    ]\n}\n```\n\n##### Example: Trim `name` and `description` from entire JSON BOM\n\n```bash\n./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=name,description -q\n```\n\nOutput BOM results without `name` or `description`:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"serialNumber\": \"urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9\",\n    \"version\": 1,\n    \"components\": [\n        {\n            \"type\": \"library\",\n            \"bom-ref\": \"pkg:npm/sample@2.0.0\",\n            \"version\": \"2.0.0\",\n            \"purl\": \"pkg:npm/sample@2.0.0\",\n            \"properties\": [\n                {\n                    \"value\": \"bar\"\n                }\n            ]\n        },\n        {\n            \"type\": \"library\",\n            \"bom-ref\": \"pkg:npm/body-parser@1.19.0\",\n            \"version\": \"1.19.0\",\n            \"hashes\": [\n                {\n                    \"alg\": \"SHA-1\",\n                    \"content\": \"96b2709e57c9c4e09a6fd66a8fd979844f69f08a\"\n                }\n            ],\n            \"purl\": \"pkg:npm/body-parser@1.19.0\"\n        }\n    ],\n    \"properties\": [\n        {\n            \"value\": \"123\"\n        }\n    ]\n}\n```\n\n##### Example: Trim `properties` from only `components` path\n\n```bash\n./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-small-components-only.sbom.json --keys=properties --from components -q\n```\n\nOutput BOM results with `properties` removed from all `components`:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"serialNumber\": \"urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9\",\n    \"version\": 1,\n    \"components\": [\n        {\n            \"type\": \"library\",\n            \"bom-ref\": \"pkg:npm/sample@2.0.0\",\n            \"name\": \"sample\",\n            \"version\": \"2.0.0\",\n            \"description\": \"Node.js Sampler package\",\n            \"purl\": \"pkg:npm/sample@2.0.0\"\n        },\n        {\n            \"type\": \"library\",\n            \"bom-ref\": \"pkg:npm/body-parser@1.19.0\",\n            \"name\": \"body-parser\",\n            \"version\": \"1.19.0\",\n            \"description\": \"Node.js body parsing middleware\",\n            \"hashes\": [\n                {\n                    \"alg\": \"SHA-1\",\n                    \"content\": \"96b2709e57c9c4e09a6fd66a8fd979844f69f08a\"\n                }\n            ],\n            \"purl\": \"pkg:npm/body-parser@1.19.0\"\n        }\n    ],\n    \"properties\": [\n        {\n            \"name\": \"abc\",\n            \"value\": \"123\"\n        }\n    ]\n}\n```\n\n---\n\n##### Example: Trim `bom-ref` and normalize output\n\n```bash\n./sbom-utility trim -i test/trim/trim-cdx-1-5-sample-components-normalize.sbom.json --keys=\"bom-ref\" --normalize -q\n```\n\n**Note** If you do not want to remove any keys and simply normalize output, set keys to an empty string: `--keys=\"\"`.\n\nUse the trim command to remove all `bom-ref` fields and normalize output:\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"components\": [\n    {\n      \"type\": \"library\",\n      \"bom-ref\": \"pkg:npm/sample@2.0.0\",\n      \"purl\": \"pkg:npm/sample@2.0.0\",\n      \"name\": \"sample\",\n      \"version\": \"2.0.0\",\n      \"licenses\": [\n        {\n          \"license\": {\n            \"id\": \"GPL-2.0-or-later\"\n          }\n        },\n        {\n          \"license\": {\n            \"id\": \"LGPL-2.0-or-later\"\n          }\n        },\n        {\n          \"license\": {\n            \"id\": \"GPL-2.0-only\"\n          }\n        }\n      ],\n      \"properties\": [\n        {\n          \"name\": \"moo\",\n          \"value\": \"cow\"\n        },\n        {\n          \"name\": \"foo\",\n          \"value\": \"bar\"\n        }\n      ]\n    },\n    {\n      \"type\": \"library\",\n      \"bom-ref\": \"pkg:npm/body-parser@1.19.0\",\n      \"purl\": \"pkg:npm/body-parser@1.19.0\",\n      \"name\": \"body-parser\",\n      \"version\": \"1.19.0\",\n      \"hashes\": [\n        {\n          \"alg\": \"SHA-256\",\n          \"content\": \"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\"\n        },\n        {\n          \"alg\": \"SHA-1\",\n          \"content\": \"96b2709e57c9c4e09a6fd66a8fd979844f69f08a\"\n        }\n      ],\n      \"licenses\": [\n        {\n          \"license\": {\n            \"id\": \"MIT\"\n          }\n        },\n        {\n          \"license\": {\n            \"id\": \"Apache-2.0\"\n          }\n        }\n      ],\n      \"externalReferences\": [\n        {\n          \"type\": \"website\",\n          \"url\": \"https://example.com/website\"\n        },\n        {\n          \"type\": \"support\",\n          \"url\": \"https://example.com/support\"\n        }\n      ]\n    }\n  ]\n}\n```\n\nTrimmed, normalized output:\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"components\": [\n    {\n      \"type\": \"library\",\n      \"name\": \"body-parser\",\n      \"version\": \"1.19.0\",\n      \"hashes\": [\n        {\n          \"alg\": \"SHA-1\",\n          \"content\": \"96b2709e57c9c4e09a6fd66a8fd979844f69f08a\"\n        },\n        {\n          \"alg\": \"SHA-256\",\n          \"content\": \"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\"\n        }\n      ],\n      \"licenses\": [\n        {\n          \"license\": {\n            \"id\": \"Apache-2.0\"\n          }\n        },\n        {\n          \"license\": {\n            \"id\": \"MIT\"\n          }\n        }\n      ],\n      \"purl\": \"pkg:npm/body-parser@1.19.0\",\n      \"externalReferences\": [\n        {\n          \"type\": \"support\",\n          \"url\": \"https://example.com/support\"\n        },\n        {\n          \"type\": \"website\",\n          \"url\": \"https://example.com/website\"\n        }\n      ]\n    },\n    {\n      \"type\": \"library\",\n      \"name\": \"sample\",\n      \"version\": \"2.0.0\",\n      \"licenses\": [\n        {\n          \"license\": {\n            \"id\": \"GPL-2.0-only\"\n          }\n        },\n        {\n          \"license\": {\n            \"id\": \"GPL-2.0-or-later\"\n          }\n        },\n        {\n          \"license\": {\n            \"id\": \"LGPL-2.0-or-later\"\n          }\n        }\n      ],\n      \"purl\": \"pkg:npm/sample@2.0.0\",\n      \"properties\": [\n        {\n          \"name\": \"foo\",\n          \"value\": \"bar\"\n        },\n        {\n          \"name\": \"moo\",\n          \"value\": \"cow\"\n        }\n      ]\n    }\n  ]\n}\n```\n\n---\n\n### Patch\n\nThis *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.\n\nThe current implementation supports the following \"patch\" operations:\n\n- \"add\", \"update\", \"remove\" and \"test\"\n\nAt this time the \"move\" or \"copy\" operations are not supported.\n\nPatches work for both simple (i.e., integer, float, boolean and string) values as well as complex values such as JSON objects, maps and arrays.\n\n#### Patch supported output formats\n\nThis command is used to output, using the [`--output-file` flag](#output-flag), a \"patched\" BOM in JSON format.\n\n- `json` (default)\n\n#### Patch flags\n\nThe 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:\n\n##### Patch `--patch-filename` flag\n\nThe `--patch-file \u003cfilename\u003e` flag is used to provide the relative path to the IETF RFC6902 patch file to applied to the BOM input file.\n\n##### Patch `--normalize` flag\n\nA flag that normalizes the BOM data after patching and prior to output.\n\nThis flag invokes custom code that sorts all components, services, licenses, vulnerabilities, properties, external references, hashes and *most* other BOM data using custom comparators.\n\nEach comparator uses `required` fields and other identifying fields to create *\"composite keys\"* for each unique data structure.\n\n#### Patch examples\n\nThis 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.\n\n- [Example 1: \"add\" BOM `serialNumber`](#patch-example-1-add-bom-serialnumber)\n- [Example 2: \"add\" (update) BOM `version`](#patch-example-2-add-update-bom-version)\n- [Example 3: \"add\" `supplier` object to `metadata`](#patch-example-3-add-supplier-object-to-metadata-object)\n- [Example 4:\"add\" `property` objects to `metadata.properties` array](#patch-example-4-add-property-objects-to-metadataproperties-array)\n  - [Example 4a: Normalize `metadata.properties` after patching](#patch-example-4a---normalize-properties-after-patching)\n- [Example 5: \"replace\" `version` and `timestamp` values](#patch-example-5-replace-bom-version-and-timestamp)\n- [Example 6: \"remove\" `property` from the `metadata.properties` array](#patch-example-6-remove-property-from-the-metadataproperties-array)\n- [Example 7: \"test\" if a `property` exists in the `metadata.properties` array](#patch-example-7-test-property-exists-in-the-metadataproperties-array)\n\n##### Patch example 1: \"add\" BOM `serialNumber`\n\nThis example adds a new top-level key `\"serialNumber\"` and corresponding value to a CycloneDX JSON BOM file.\n\nThe 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:\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"metadata\": {\n      ...\n  }\n}\n```\n\nIETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json):\n\n```json\n[\n  { \"op\": \"add\", \"path\": \"/serialNumber\", \"value\": \"urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9\" }\n]\n```\n\nInvoke the patch command as follows:\n\n```bash\n./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\n```\n\nPatched JSON BOM output file:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"serialNumber\": \"urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9\",\n    \"version\": 1,\n    \"metadata\": {\n        ...\n    }\n}\n```\n\n##### Patch example 2: \"add\" (update) BOM `version`\n\nThis example shows how the patch's \"add\" operation can be used to update existing values which is the specified behavior of RFC6902.\n\nOriginal 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`:\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"metadata\": {\n      ...\n  }\n}\n```\n\nIETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json):\n\n```json\n[\n  { \"op\": \"add\", \"path\": \"/version\", \"value\": 2 }\n]\n```\n\nInvoke the patch command as follows:\n\n```bash\n./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\n```\n\nThe patched, output JSON BOM file which has the changed `version` value of `2`:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"version\": 2,\n    \"metadata\": {\n        ...\n    }\n}\n```\n\n##### Patch example 3: \"add\" `supplier` object to `metadata` object\n\nThis example shows how the patch's \"add\" operation can be used to add a JSON object to an existing object.\n\nOriginal CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"metadata\": {\n    \"timestamp\": \"2023-10-12T19:07:00Z\",\n    \"properties\": [\n      ...\n    ]\n  }\n}\n```\n\nApply 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):\n\n```json\n[\n  { \"op\": \"add\", \"path\": \"/metadata/supplier\", \"value\": {\n      \"name\": \"Example Co. Distribution Dept.\",\n      \"url\": [\n        \"https://example.com/software/\"\n      ]\n    }\n  }\n]\n```\n\nInvoke the patch command as follows:\n\n```bash\n./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\n```\n\nThe patched BOM has the `supplier` object added to the `metadata`:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"version\": 1,\n    \"metadata\": {\n        \"timestamp\": \"2023-10-12T19:07:00Z\",\n        \"supplier\": {\n            \"name\": \"Example Co. Distribution Dept.\",\n            \"url\": [\n                \"https://example.com/software/\"\n            ]\n        },\n        \"properties\": [\n            ...\n        ]\n    }\n}\n```\n\n##### Patch example 4: \"add\" `property` objects to `metadata.properties` array\n\nThis example shows how the patch's \"add\" operation can be used to add `property` objects to an existing `properties` array.\n\nOriginal CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"metadata\": {\n    \"timestamp\": \"2023-10-12T19:07:00Z\",\n    \"properties\": [\n      {\n        \"name\": \"Property 1\",\n        \"value\": \"Value 1\"\n      },\n      {\n        \"name\": \"Property 2\",\n        \"value\": \"Value 2\"\n      }\n    ]\n  }\n}\n```\n\nApply 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):\n\n```json\n[\n  { \"op\": \"add\", \"path\": \"/metadata/properties/-\", \"value\": { \"name\": \"foo\", \"value\": \"bar\" } },\n  { \"op\": \"add\", \"path\": \"/metadata/properties/1\", \"value\": { \"name\": \"rush\", \"value\": \"yyz\" } }\n]\n```\n\nNote 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`.\n\nInvoke the patch command as follows:\n\n```bash\n./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\n```\n\nThe patched, output BOM has the two new properties at the specified indices:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"version\": 1,\n    \"metadata\": {\n        \"timestamp\": \"2023-10-12T19:07:00Z\",\n        \"properties\": [\n            {\n                \"name\": \"Property 1\",\n                \"value\": \"Value 1\"\n            },\n            {\n                \"name\": \"rush\",\n                \"value\": \"yyz\"\n            },\n            {\n                \"name\": \"Property 2\",\n                \"value\": \"Value 2\"\n            },\n            {\n                \"name\": \"foo\",\n                \"value\": \"bar\"\n            }\n        ]\n    }\n}\n```\n\n##### Patch example 4a: `--normalize` properties after patching\n\nThis variant of the previous example also normalizes the output BOM arrays; in this case, normalizing the existing and added properties of the `metadata.properties` array.\n\n```bash\n./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-metadata-properties.json --normalize -q\n```\n\nThe patched and **normalized** `metadata.properties` appear as follows:\n\n```shell\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"version\": 1,\n    \"metadata\": {\n        \"timestamp\": \"2023-10-12T19:07:00Z\",\n        \"properties\": [\n            {\n                \"name\": \"Property 1\",\n                \"value\": \"Value 1\"\n            },\n            {\n                \"name\": \"Property 2\",\n                \"value\": \"Value 2\"\n            },\n            {\n                \"name\": \"foo\",\n                \"value\": \"bar\"\n            },\n            {\n                \"name\": \"rush\",\n                \"value\": \"yyz\"\n            }\n        ]\n    }\n}\n```\n\n##### Patch example 5: \"replace\" BOM `version` and `timestamp`\n\nThis example shows how the patch's \"replace\" operation can be used to update the BOM document's `version` and `timestamp` values.\n\nOriginal CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"metadata\": {\n    \"timestamp\": \"2023-10-12T19:07:00Z\",\n    \"properties\": [\n      ...\n    ]\n  }\n}\n```\n\nApply 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):\n\n```json\n[\n  { \"op\": \"replace\", \"path\": \"/version\", \"value\": 2 },\n  { \"op\": \"replace\", \"path\": \"/metadata/timestamp\", \"value\": \"2024-01-24T22:50:18+00:00\" }\n]\n```\n\nInvoke the patch command as follows:\n\n```bash\n./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\n```\n\nThe patched, output BOM has both an updated `version` and `timestamp`:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"version\": 2,\n    \"metadata\": {\n        \"timestamp\": \"2024-01-24T22:50:18+00:00\",\n        \"properties\": [\n          ...\n    }\n}\n```\n\n##### Patch example 6: \"remove\" `property` from the `metadata.properties` array\n\nThis example shows how the patch's \"remove\" operation can be used to remove a `property` object from the `metadata.properties` array using an index.\n\nOriginal CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"metadata\": {\n    \"timestamp\": \"2023-10-12T19:07:00Z\",\n    \"properties\": [\n      {\n        \"name\": \"Property 1\",\n        \"value\": \"Value 1\"\n      },\n      {\n        \"name\": \"Property 2\",\n        \"value\": \"Value 2\"\n      }\n    ]\n  }\n}\n```\n\nApply 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):\n\n```json\n[\n  { \"op\": \"remove\", \"path\": \"/metadata/properties/1\" }\n]\n```\n\nInvoke the patch command as follows:\n\n```bash\n./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\n```\n\nThe `property` at index `1` of the `metadata.properties` array has been removed:\n\n```json\n{\n    \"bomFormat\": \"CycloneDX\",\n    \"specVersion\": \"1.5\",\n    \"version\": 1,\n    \"metadata\": {\n        \"timestamp\": \"2023-10-12T19:07:00Z\",\n        \"properties\": [\n            {\n                \"name\": \"Property 1\",\n                \"value\": \"Value 1\"\n            }\n        ]\n    }\n}\n```\n\n##### Patch example 7: \"test\" `property` exists in the `metadata.properties` array\n\nThis 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.\n\nOriginal CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json):\n\n```json\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"metadata\": {\n    \"timestamp\": \"2023-10-12T19:07:00Z\",\n    \"properties\": [\n      {\n        \"name\": \"Property 1\",\n        \"value\": \"Value 1\"\n      },\n      {\n        \"name\": \"Property 2\",\n        \"value\": \"Value 2\"\n      }\n    ]\n  }\n}\n```\n\nApply 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):\n\n```json\n[\n  { \"op\": \"test\", \"path\": \"/metadata/properties/1\", \"value\":\n    {\n      \"name\": \"Property 2\",\n      \"value\": \"Value 2\"\n    }\n  }\n]\n```\n\nInvoke the patch command as follows:\n\n```bash\n./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\n```\n\nAn informational (i.e., `[INFO]`) message is logged with `success` since the property object was found in the input BOM:\n\n```json\n[INFO] IETF RFC6902 test operation success. test record: {\n    \"op\": \"test\",\n    \"path\": \"/metadata/properties/1\",\n    \"value\": {\n        \"name\": \"Property 2\",\n        \"value\": \"Value 2\"\n    }\n}\n```\n\nIf instead, we [tested for a different property](test/patch/cdx-patch-example-test-metadata-property-err.json) object:\n\n```json\n[\n  { \"op\": \"test\", \"path\": \"/metadata/properties/1\", \"value\":\n    {\n      \"name\": \"Property 3\",\n      \"value\": \"Value 3\"\n    }\n  }\n]\n```\n\nan error (i.e., `[ERROR]`) would be returned from the utility:\n\n```json\n[ERROR] IETF RFC6902 test operation error. test record: {\n    \"op\": \"test\",\n    \"path\": \"/metadata/properties/1\",\n    \"value\": {\n        \"name\": \"Property 3\",\n        \"value\": \"Value 3\"\n    }\n}\n```\n\n---\n\n### Query\n\nThis 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.\n\n#### Query flags\n\n##### Query `--from` flag\n\nThe `--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.\n\n##### Query `--select` flag\n\nThe `--select` clause is then applied to the `--from` result set to only return the specified properties (names and their values).\n\n##### Query `--where` flag\n\nIf 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).\n\n**Note**: All `query` command results are returned as valid JSON documents.  This includes a `null` value for empty result sets.\n\n#### Query supported formats\n\nThe `query` command only supports JSON output.\n\n- `json` (default)\n\n#### Query result sorting\n\nThe `query` command does not support formatting of output results as JSON format is always returned.\n\n#### Query examples\n\n##### Example: Extract the top-level `component` information from an SBOM\n\nThis example effectively extracts the first-order package manifest from the SBOM.\n\nIn 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.\n\n```bash\n./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --from metadata.component\n```\n\nis equivalent to using the wildcard character (which may need to be enclosed in single or double quotes depending on your shell):\n\n```bash\n./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --select '*' --from metadata.component -q\n```\n\n```json\n{\n  \"name\": \"Example Application v10.0.4\",\n  \"bom-ref\": \"pkg:oci/example.com/product/application@10.0.4.0\",\n  \"description\": \"Example's Do-It-All application\",\n  \"externalReferences\": [\n    {\n      \"type\": \"website\",\n      \"url\": \"https://example.com/application\"\n    }\n  ],\n  \"hashes\": [\n    {\n      \"alg\": \"SHA-1\",\n      \"content\": \"1111aaaa2222cccc3333dddd4444eeee5555ffff\"\n    }\n  ],\n  \"licenses\": [\n    {\n      \"license\": {\n        \"id\": \"Apache-2.0\"\n      }\n    }\n  ],\n  ...\n```\n\n##### Example: Extract the `supplier` of the SBOM\n\nIn this example, the `--from` clause references the top-level `metadata.supplier` object.\n\n```bash\n./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --from metadata.supplier -q\n```\n\n```json\n{\n  \"contact\": [\n    {\n      \"email\": \"distribution@example.com\"\n    }\n  ],\n  \"name\": \"Example Co. Distribution Dept.\",\n  \"url\": [\n    \"https://example.com/software/\"\n  ]\n}\n```\n\n##### Example: Extract just the SBOM component's `name` and `version`\n\nIn 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.\n\n```bash\n./sbom-utility query --select name,version --from metadata.component -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --indent 2 -q\n```\n\nThe result, which also uses the `--indent 2` flag:\n\n```json\n{\n  \"name\": \"juice-shop\",\n  \"version\": \"11.1.2\"\n}\n```\n\n##### Example: Return the JSON array of components\n\nIn this example, the `--from` filter will return the entire JSON components array.\n\n```bash\n./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --from components -q\n```\n\n```json\n[\n  {\n    \"bom-ref\": \"pkg:npm/sample@2.0.0\",\n    \"description\": \"Node.js Sampler package\",\n    \"licenses\": [\n      {\n        \"license\": {\n          \"id\": \"MIT\"\n        }\n      }\n    ],\n    \"name\": \"sample\",\n    \"purl\": \"pkg:npm/sample@2.0.0\",\n    \"type\": \"library\",\n    \"version\": \"2.0.0\"\n  },\n  {\n    \"bom-ref\": \"pkg:npm/body-parser@1.19.0\",\n    \"description\": \"Node.js body parsing middleware\",\n    \"hashes\": [\n      {\n        ...\n      }\n    ],\n    \"licenses\": [\n      {\n        \"license\": {\n          \"id\": \"MIT\"\n        }\n      }\n    ],\n    \"name\": \"body-parser\",\n    \"purl\": \"pkg:npm/body-parser@1.19.0\",\n    \"type\": \"library\",\n    \"version\": \"1.19.0\"\n  }\n]\n```\n\n**Note**: The command for this example only used the `--from` flag and did not need to supply `--select '*'` as this is the default.\n\n##### Example: Filter result entries with a specified value\n\nIn this example, the `--where` filter will be applied to a set of `properties` results to only include entries that match the specified regex.\n\n```bash\n./sbom-utility query -i test/cyclonedx/cdx-1-4-mature-example-1.json --from metadata.properties --where name=urn:example.com:classification -q\n```\n\n```json\n[\n  {\n    \"name\": \"urn:example.com:classification\",\n    \"value\": \"This SBOM is Confidential Information. Do not distribute.\"\n  }\n]\n```\n\nadditionally, you can apply a `--select` clause to simply obtain the matching entry's `value`:\n\n```bash\n./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\n```\n\n```json\n[\n  {\n    \"value\": \"This SBOM is Confidential Information. Do not distribute.\"\n  }\n]\n```\n\n---\n\n### Component\n\nPrimarily, this command is used to extract, filter and list CycloneDX BOM component data using `component list`.\n\n#### Component list supported formats\n\nThis command supports the `--format` flag with any of the following values:\n\n- `txt` (default), `csv`, `md`\n\n#### Component list flags\n\n##### Component list `--summary` flag\n\nUse the `--summary` flag on the `component list` command to produce a summary report with reduced column information.\n\n#### Component list examples\n\n##### Example: `component list`\n\nThis 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.\n\n```bash\n./sbom-utility component list -i test/cyclonedx/1.6/specification/valid-bom-1.6.json -q\n```\n\n```text\nbom-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\n-------                       -----        ----         ----              -------  -----------  ---------  -------------  ------------         -----------------  ----------------     ---------  ----                          -----------                                         ---     ---------  -----     -------------  ---------------  ------------  ------------  --------------  -----------------  --------------  --------  --------  -------------\n                                           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\npkg: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\n                              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\n```\n\n##### Example: `component list` summary only\n\nThe same BOM component information as in the previous example; however, using the summary flag to reduce the number of columns data.\n\n```bash\n./sbom-utility component list -i test/cyclonedx/1.6/specification/valid-bom-1.6.json --summary -q\n```\n\n```text\nbom-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\n-------                       -----        ----         ----              -------  -----------  ---------  -------------  ------------         -----------------  ----------------     ---------  ----                          -----------                                         ---     -------------  ---------------\n                                           application  Acme Application  9.1.1                                                                                                                                                 swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1          0              0\npkg:npm/acme/component@1.0.0  com.acme     library      tomcat-catalina   9.0.14                                                                                                                  pkg:npm/acme/component@1.0.0                                                              4              1\n                              org.example  library      mylibrary         1.0.0                            Example, Inc.  https://example.com  Example-2, Inc.    https://example.org                                                                                                       0              0\n```\n\n---\n\n### License\n\nThis 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`).\n\nThe `license` command supports the following subcommands:\n\n- [list](#license-list-subcommand) - list or create a summarized report of licenses found in input SBOM.\n  - [list with --summary flag](#license-list---summary-flag) - As full license information can be very large, a summary view is often most useful.\n- [policy](#license-policy-subcommand) - list user configured license policies by SPDX license ID, family name and other filters.\n\n---\n\n### License `list` subcommand\n\nThe `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.\n\n#### License list supported formats\n\nThis command supports the `--format` flag with any of the following values:\n\n##### without `--summary` flag\n\nThe output will contain the canonical schema for the CycloneDX `LicenseChoice` data objects.\n\n- `json` (default), `csv`, `md`\n\n###### sample json object output:\n\n```json\n    {\n        \"license\": {\n            \"id\": \"MIT\"\n        }\n    },\n```\n\n*which could be used to edit or rewrite a BOM with a summary of all `LicenseChoice` data.*\n\n##### with `--summary` flag\n\nThe output will contain a simplified, flattened set of key-value information form both the CycloneDX `LicenseChoice` structure, as well as user-customizable, license policy information (see [License policy notes](#license-policy-notes)).\n\n- `txt` (default), `csv`, `md`, `json`\n\n###### sample json object output:\n\n```json\n    {\n        \"bom-location\": \"components\",\n        \"bom-ref\": \"pkg:lib/libraryA@1.0.0\",\n        \"license\": \"MIT\",\n        \"license-type\": \"id\",\n        \"resource-name\": \"Library A\",\n        \"usage-policy\": \"allow\"\n    },\n```\n\n#### License list result sorting\n\n- Results are not sorted for base `license list` subcommand.\n  - using the  `--summary` flag: results are sorted (ascending) by license key which can be one of license `id` (SPDX ID), `name` or `expression`.\n\n#### License list flags\n\n##### License list `--summary` flag\n\nUse 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.\n\n#### License list examples\n\n##### Example: license list JSON\n\nThis example shows a few entries of the JSON output that exhibit the three types of license data described above:\n\n```bash\n./sbom-utility license list -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json --format json -q\n```\n\n```json\n[\n    {\n        \"license\": {\n            \"$comment\": \"by license `id\",\n            \"id\": \"MIT\",\n            \"name\": \"\",\n            \"url\": \"\"\n        }\n    },\n    {\n        \"license\": {\n            \"$comment\": \"by license `expression\",\n            \"id\": \"\",\n            \"name\": \"\",\n            \"url\": \"\"\n        },\n        \"expression\": \"Apache-2.0 AND (MIT OR GPL-2.0-only)\"\n    },\n    {\n        \"license\": {\n            \"$comment\": \"by license `name` with full license encoding\",\n            \"id\": \"\",\n            \"name\": \"Apache 2\",\n            \"text\": {\n                \"contentType\": \"text/plain\",\n                \"encoding\": \"base64\",\n                \"content\": \"CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24 ...\"\n            },\n            \"url\": \"https://www.apache.org/licenses/LICENSE-2.0.txt\"\n        }\n    },\n    ...\n]\n```\n\n###### Example: license list `--summary`\n\nThis example shows the default text output from using the summary flag:\n\n```bash\n./sbom-utility license list -i test/cyclonedx/cdx-1-3-license-list.json --summary -q\n```\n\n```bash\nusage-policy  license-type  license                               resource-name      bom-ref                             bom-location\n------------  ------------  -------                               -------------      -------                             ------------\nneeds-review  id            ADSL                                  Foo                service:example.com/myservices/foo  services\nneeds-review  name          AGPL                                  Library J          pkg:lib/libraryJ@1.0.0              components\nallow         name          Apache                                Library B          pkg:lib/libraryB@1.0.0              components\nallow         id            Apache-1.0                            Library E          pkg:lib/libraryE@1.0.0              components\nallow         id            Apache-2.0                            N/A                N/A                                 metadata.licenses\nallow         id            Apache-2.0                            Library A          pkg:lib/libraryA@1.0.0              components\nallow         id            Apache-2.0                            Library F          pkg:lib/libraryF@1.0.0              components\nallow         expression    Apache-2.0 AND (MIT OR BSD-2-Clause)  Library B          pkg:lib/libraryB@1.0.0              components\nallow         name          BSD                                   Library J          pkg:lib/libraryJ@1.0.0              components\ndeny          name          CC-BY-NC                              Library G          pkg:lib/libraryG@1.0.0              components\nneeds-review  name          GPL                                   Library H          pkg:lib/libraryH@1.0.0              components\nneeds-review  id            GPL-2.0-only                          Library C          pkg:lib/libraryC@1.0.0              components\nneeds-review  id            GPL-3.0-only                          Library D          pkg:lib/libraryD@1.0.0              components\nallow         id            MIT                                   ACME Application   pkg:app/sample@1.0.0                metadata.component\nallow         id            MIT                                   Library A          pkg:lib/libraryA@1.0.0              components\nUNDEFINED     invalid       NOASSERTION                           Library NoLicense  pkg:lib/libraryNoLicense@1.0.0      components\nUNDEFINED     invalid       NOASSERTION                           Bar                service:example.com/myservices/bar  services\nneeds-review  name          UFL                                   ACME Application   pkg:app/sample@1.0.0                metadata.component\n```\n\n- **Notes**\n  - **Usage policy** column values are derived from the `license.json` policy configuration file.\n    - A `usage policy` value of `UNDEFINED` indicates that `license.json` provided no entry that matched the declared license (`id` or `name`) in the SBOM.\n  - **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.\n\n###### Example: license list summary with `--where` filter\n\nThe 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`.\n\nThe following example shows filtering of component licenses using the `license-type` column where the license was described as a `name` value:\n\n```bash\n./sbom-utility license list -i test/cyclonedx/cdx-1-3-license-list.json --summary --where license-type=name -q\n```\n\n```bash\nusage-policy  license-type  license   resource-name     bom-ref                 bom-location\n------------  ------------  -------   -------------     -------                 ------------\nneeds-review  name          AGPL      Library J         pkg:lib/libraryJ@1.0.0  components\nallow         name          Apache    Library B         pkg:lib/libraryB@1.0.0  components\nallow         name          BSD       Library J         pkg:lib/libraryJ@1.0.0  components\ndeny          name          CC-BY-NC  Library G         pkg:lib/libraryG@1.0.0  components\nneeds-review  name          GPL       Library H         pkg:lib/libraryH@1.0.0  components\nneeds-review  name          UFL       ACME Application  pkg:app/sample@1.0.0    metadata.component\n```\n\nIn another example, the list is filtered by the `usage-policy` where the value is `needs-review`:\n\n```bash\n./sbom-utility license list -i test/cyclonedx/cdx-1-3-license-list.json --summary --where usage-policy=needs-review -q\n```\n\n```bash\nusage-policy  license-type  license       resource-name     bom-ref                             bom-location\n------------  ------------  -------       -------------     -------                             ------------\nneeds-review  id            ADSL          Foo               service:example.com/myservices/foo  services\nneeds-review  name          AGPL          Library J         pkg:lib/libraryJ@1.0.0              components\nneeds-review  name          GPL           Library H         pkg:lib/libraryH@1.0.0              components\nneeds-review  id            GPL-2.0-only  Library C         pkg:lib/libraryC@1.0.0              components\nneeds-review  id            GPL-3.0-only  Library D         pkg:lib/libraryD@1.0.0              components\nneeds-review  name          UFL           ACME Application  pkg:app/sample@1.0.0                metadata.component\n```\n\n---\n\n### License `policy` subcommand\n\nTo 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\"`).\n\n#### License policy supported formats\n\nThis command supports the `--format` flag with any of the following values:\n\n- `txt` (default), `csv`, `md`\n\n#### License policy result sorting\n\n- Results are sorted by license policy `family`.\n\n#### License policy flags\n\n##### list `--summary` flag\n\nUse 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).\n\n##### list `--wrap` flag\n\nUse 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`.\n\n#### License policy examples\n\n##### Example: license policy\n\n```bash\n./sbom-utility license policy -q\n```\n\n```bash\nusage-policy  family    id            name                                osi    fsf    deprecated  reference                                    aliases                      annotations                  notes\n------------  ------    --            ----                                ---    ---    ----------  ---------                                    -------                      -----------                  -----\nallow         0BSD      0BSD          BSD Zero Clause License             true   false  false       https://spdx.org/licenses/0BSD.html          Free Public License 1.0.0    APPROVED                     none\nneeds-review  ADSL      ADSL          Amazon Digital Services License     false  false  false       https://spdx.org/licenses/ADSL.html          none                         NEEDS-APPROVAL               none\nallow         AFL       AFL-3.0       Academic Free License v3.0          true   true   false       https://spdx.org/licenses/AFL-3.0.html       none                         APPROVED                     none\nneeds-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\nallow         Adobe     Adobe-2006    Adobe Systems Incorporated CLA      false  false  false       https://spdx.org/licenses/Adobe-2006.html    none                         APPROVED                     none\nallow         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\nallow         Artistic  Artistic-1.0  Artistic License 1.0                true   false  false       https://spdx.org/licenses/Artistic-1.0.html  none                         APPROVED                     none\n...\n```\n\n###### Example: policy with `--summary` flag\n\nWe 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).\n\n```bash\n./sbom-utility license policy --summary -q\n```\n\n```bash\nusage-policy  family    id            name                                osi     fsf     deprecated  reference\n------------  ------    --            ----                                ---     ---     ----------  ---------\nallow         0BSD      0BSD          BSD Zero Clause License             true    false   false       https://spdx.org/licenses/0BSD.html\nneeds-review  ADSL      ADSL          Amazon Digital Services License     false   false   false       https://spdx.org/licenses/ADSL.html\nallow         AFL       AFL-3.0       Academic Free License v3.0          true    true    false       https://spdx.org/licenses/AFL-3.0.html\nneeds-review  AGPL      AGPL-1.0      Affero General Public License v1.0  false   false   true        https://spdx.org/licenses/AGPL-1.0.html\nallow         Adobe     Adobe-2006    Adobe Systems Incorporated CLA      false   false   false       https://spdx.org/licenses/Adobe-2006.html\nallow         Apache    Apache-2.0    Apache License 2.0                  true    true    false       https://spdx.org/licenses/Apache-2.0.html\nallow         Artistic  Artistic-1.0  Artistic License 1.0                true    true    false       https://spdx.org/licenses/Artistic-2.0.html\n...\n```\n\n###### Example: policy with `--where` filter\n\nThe following example shows filtering of  license policies using the `id` column:\n\n```bash\n./sbom-utility license policy --where id=Apache -q\n```\n\n```bash\nusage-policy  family  id          name                osi     fsf     deprecated  reference                                  aliases         annotations  notes\n------------  ------  --          ----                ---     ---     ----------  ---------                                  -------         -----------  -----\nallow         Apache  Apache-1.0  Apache v1.0         false   true    false       https://spdx.org/licenses/Apache-1.0.html  none            APPROVED     none\nallow         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\nallow         Apache  Apache-2.0  Apache License 2.0  true    true    false       https://spdx.org/licenses/Apache-2.0.html  Apache License  APPROVED     none\n\n```\n\n###### Example: policy with `--wrap` flag\n\n```bash\n./sbom-utility license policy --wrap=true -q\n```\n\n```bash\nusage-policy  family    id             name                          osi     fsf     deprecated  reference                                     aliases                           annotations             notes\n------------  ------    --             ----                          ---     ---     ----------  ---------                                     -------                           -----------             -----\nallow         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\nneeds-review  ADSL      ADSL           Amazon Digital Servi (20/31)  false   false   false       https://spdx.org/licenses/ADSL.html                                             NEEDS-APPROVAL          none\nallow         AFL       AFL-3.0        Academic Free Licens (20/26)  true    true    false       https://spdx.org/licenses/AFL-3.0.ht (36/38)                                    APPROVED                none\nneeds-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\n                                                                                                                                                                                 AGPL-WARNING\nneeds-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\nallow         Adobe     Adobe-2006     Adobe Systems Incorp (20/56)  false   false   false       https://spdx.org/licenses/Adobe-2006 (36/41)                                    APPROVED                none\nallow         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\nallow         Artistic  Artistic-2.0   Artistic License 2.0          true    true    false       https://spdx.org/licenses/Artistic-2 (36/43)                                    APPROVED                none\n...\n```\n\n#### License policy notes\n\n- 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.\n  - An issue [12](https://github.com/CycloneDX/sbom-utility/issues/12) is open to add parity.\n- Annotations (tags) and notes can be defined within the `license.json` file and one or more assigned each license entry.\n\u003c!-- - 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). --\u003e\n- For backwards compatibility, the `--where` filter supports the key `spdx-id` as an alias for `id`.\n\n---\n\n### Resource\n\nThe `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.\n\nPrimarily, the command is used to generate lists of resources, by type, that are included in a CycloneDX SBOM by invoking `resource list`.\n\n#### Resource supported output formats\n\nThis command supports the `--format` flag with any of the following values:\n\n- `txt` (default), `csv`, `md`\n\n#### Resource result sorting\n\nCurrently, all `resource list` command results are sorted by resource `type` then by resource `name` (required field).\n\n#### Resource Examples\n\n#### Example: resource list\n\n```bash\n./sbom-utility resource list -i test/cyclonedx/cdx-1-3-resource-list.json -q\n```\n\n```bash\nbom-ref                             resource-type  group   name               version  description\n-------                             -------------  -----   ----               -------  -----------\npkg:app/sample@1.0.0                component              ACME Application   2.0.0    ACME sample application\npkg:lib/libraryA@1.0.0              component              Library A          1.0.0    Library A description\npkg:lib/libraryC@1.0.0              component              Library C          1.0.0    Library C description.\npkg:lib/libraryF@1.0.0              component              Library F          1.0.0    Library F description.\npkg:lib/libraryG@1.0.0              component              Library G          1.0.0    Library G description.\npkg:lib/libraryH@1.0.0              component              Library H          1.0.0    Library H description.\npkg:lib/libraryNoLicense@1.0.0      component              Library NoLicense  1.0.0    Library \"NoLicense\" description.\npkg:lib/libraryB@1.0.0              component      blue    Library B          1.0.0    Library B description.\npkg:lib/libraryE@1.0.0              component      blue    Library E          1.0.0    Library E description.\npkg:lib/libraryD@1.0.0              component      green   Library D          1.0.0    Library D description.\npkg:lib/libraryJ@1.0.0              component      green   Library J          1.0.0    Library J description.\nservice:example.com/myservices/bar  service                Bar                         Bar service\nservice:example.com/myservices/foo  service                Foo                         Foo service\n```\n\n##### Example: resource list using `--type service`\n\nThis 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\".\n\n```bash\n./sbom-utility resource list -i test/cyclonedx/cdx-1-3-resource-list.json --type service -q\n```\n\n```bash\nresource-type  group   name    version  description  bom-ref\n-------------  -----   ----    -------  -----------  -------\nservice                Bar              Bar service  service:example.com/myservices/bar\nservice                Foo              Foo service  service:example.com/myservices/foo\n```\n\n**Note** The results would be equivalent to using the `--where` filter:\n\n```bash\n./sbom-utility resource list -i test/cyclonedx/cdx-1-3-resource-list.json --where \"resource-type=service\" -q\n```\n\n##### Example: list with `name` regex match\n\nThis example uses the `where` filter on the `name` field. In this case we supply an exact \"startswith\" regex. for the `name` filter.\n\n```bash\n./sbom-utility resource list -i test/cyclonedx/cdx-1-3-resource-list.json --where \"name=Library A\" -q\n```\n\n```bash\nresource-type  group   name       version  description            bom-ref\n-------------  -----   ----       -------  -----------            -------\ncomponent              Library A  1.0.0    Library A description  pkg:lib/libraryA@1.0.0\n```\n\n---\n\n### Schema\n\nYou can verify which formats, schemas, versions and variants are available for validation by using the `schema` command.\n\n- **Note**: The `schema` command will default to the `list` subcommand if omitted.\n\n#### Schema supported output formats\n\nThis command supports the `--format` flag with any of the following values:\n\n- `txt` (default), `csv`, `md`\n\n#### Schema result sorting\n\n- Formatted results are sorted by `format` (ascending), `version` (descending) and `schema` (descending)\n\n#### Schema examples\n\n##### Example: schema list\n\n```bash\n./sbom-utility schema list -q\n```\n\n```bash\nname            variant      format     version   file                                             url\n----            -------      ------     -------   ----                                             ---\nCycloneDX v1.6  (latest)     CycloneDX  1.6       schema/cyclonedx/1.6/bom-1.6.schema.json         https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json\nCycloneDX 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\nCycloneDX 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\nCycloneDX v1.4  custom       CycloneDX  1.4       schema/test/bom-1.4-custom.schema.json\nCycloneDX 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\nCycloneDX v1.3  custom       CycloneDX  1.3       schema/test/bom-1.3-custom.schema.json\nCycloneDX 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\nCycloneDX 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\nCycloneDX 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\nSPDX 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\nSPDX 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\nSPDX 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\nSPDX 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\n```\n\n#### Adding schemas\n\nEntries 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.\n\nThese new schema entries will tell the schema loader where to find the JSON schema file locally, relative to the utility's executable.\n\nFor details see the \"[Adding new SBOM formats, schema versions and variants](#adding-new-sbom-formats-schema-versions-and-variants)\" section.\n\n#### Embedding schemas\n\nIf 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.\n\n---\n\n### Vulnerability\n\nThis 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.\n\n#### Vulnerability supported output formats\n\nUse the `--format` flag on the to choose one of the supported output formats:\n\n- txt (default), csv, md\n\n#### Vulnerability result sorting\n\n- `txt`, `csv` and `md` formatted results are sorted by vulnerability `id` (descending) then by `created` date (descending).\n- `json` results are not sorted\n\n#### Vulnerability Examples\n\n##### Example: Vulnerability list\n\nThe `list` subcommand provides a complete view of most top-level, vulnerability fields.\n\n```bash\n./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json -q\n```\n\n```bash\nid              bom-ref  cwe-ids  cvss-severity                                                source-name  source-url                                       published   updated     created     rejected  analysis-state  analysis-justification  description\n--              -------  -------  -------------                                                -----------  ----------                                       ---------   -------     -------     --------  --------------  ----------------------  -----------\nCVE-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.\nCVE-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\nCVE-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.\n```\n\n###### Example: Vulnerability list summary\n\nThis example shows the default text output from using the `--summary` flag:\n\n```bash\n./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --summary -q\n```\n\n```bash\nid              cvss-severity        source-name  published   description\n--              -------------        -----------  ---------   -----------\nCVE-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.\nCVE-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\nCVE-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.\n```\n\n##### Example: Vulnerability list with `--where` filter with `description` key\n\n```bash\n./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --where description=XXE -q\n```\n\n```bash\nid              bom-ref  cwe-ids  cvss-severity                                                source-name  source-url                                       published   updated     created     rejected  analysis-state  analysis-justification  description\n--              -------  -------  -------------                                                -----------  ----------                                       ---------   -------     -------     --------  --------------  ----------------------  -----------\nCVE-2020-25649           611      CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none)  NVD          https://nvd.nist.gov/vuln/","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyclonedx%2Fsbom-utility","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcyclonedx%2Fsbom-utility","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyclonedx%2Fsbom-utility/lists"}