From fac44c2d2e60d96813f383b2de62af80ccd5ae06 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Mon, 7 Aug 2023 14:39:29 -0700 Subject: [PATCH 01/22] rfc for npm cli sbom generation Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 427 ++++++++++++++++++++++++++++++++++ 1 file changed, 427 insertions(+) create mode 100644 accepted/0000-sbom-command.md diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md new file mode 100644 index 00000000..30e73ca1 --- /dev/null +++ b/accepted/0000-sbom-command.md @@ -0,0 +1,427 @@ +# SBOM Generation for npm Projects + +## Summary + +Update the npm CLI with a new command which will generate a Software Bill of Materials (SBOM) for the current project. Users will have the option to generate an SBOM conforming to either the [Software Package Data Exchange (SPDX](https://spdx.github.io/spdx-spec/v2.3/)) or [CycloneDX](https://cyclonedx.org/specification/overview/) specifications. + + +## Motivation + +Finding and remediating vulnerabilities in open source projects is a critical component of securing the software supply chain. However, this requires that enterprises understand what OSS components are used across their infrastructure and applications. When new vulnerabilities are discovered, they need a complete inventory of their software assets in order to properly assess their exposure. Knowing about the critical [Log4j](https://www.cisa.gov/news-events/cybersecurity-advisories/aa21-356a#main) vulnerability doesn’t do you any good unless you can also pinpoint where in your organization you’re running the vulnerable code. + +SBOMs help to solve this problem by providing a standardized way to document the components that comprise a software application. A proper SBOM should tell you exactly which packages you have deployed and which versions of those packages you are using. + +Beyond the security benefit there may be a regulatory requirement to provide SBOMs in some sectors. In response to some recent, high-visibility attacks, The White House has issued an [Executive Order](https://www.whitehouse.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/) which specifically includes directives which would make SBOMs a requirement for any vendor selling to the federal government. + +Adding SBOM generation to the tool which many developers are already using to manage their project dependencies eliminates any friction which may come from having to adopt/learn a separate tool. + + +## Detailed Explanation + +A new `sbom` command will be added to the npm CLI which will generate an SBOM for the current project. The SBOM will use the current project as the root and enumerate all of its dependencies (similar to the way `npm-ls` does) in one of the two supported SBOM formats. See the +[Example SBOMs](#example-sboms) section for sample CycloneDX and SPDX SBOM documents. + +Supported command options: + +`--sbom-format` - SBOM format to use for output. Valid values are “spdx” or “cyclonedx”. + +`--omit` - Dependency types to omit from generated SBOM. Valid values are “dev”, “optional”, and “peer” (can be set multiple times). + +`--package-lock-only` - Constructs the SBOM based on the tree described by the _package-lock.json_, rather than the contents of _node_modules_. Defaults to _false_. If the _node_modules_ folder is not present, this flag will be required in order to generate an SBOM. + +`--workspace` - Runs the command only in the context of the specified workspace (can be set multiple times). + +`--workspaces` - Runs the command in the context of all configured workspaces. + +If the user runs the `sbom` command without first installing the dependencies for the project (i.e. there is no _node_modules_ folder present) an error will be displayed. An SBOM can be generated solely based on the contents of the _package-lock.json_ but requires the user to explicitly specify the `--package-lock-only` flag. + + +## Rationale and Alternatives + +There are a few existing tools which can be used to generate an SBOM from an npm project: + +* [@cyclonedex/cyclonedx-npm](https://www.npmjs.com/package/@cyclonedx/cyclonedx-npm) - A CLI for generating a CycloneDX-style SBOM from an npm project. This project is written in TypeScript and actually invokes npm-ls in order to get dependency information for the project. +* [spdx-sbom-generator](https://github.com/opensbom-generator/spdx-sbom-generator) - A CLI for generating SPDX-style SBOMs for a number of different package managers (including npm). Currently, this tool only works with npm projects using lockfileVersion 1 so it’s not viable for a large number of projects (current lockfileVersion is 3) + +While you can effectively generate the same output we’re proposing with this combination of tools, there is value in having this capability supported directly in npm. Beyond the obvious developer-experience benefit of having SBOM generation baked-in to the CLI, it gives us a future path to do things like automatic-signing of SBOMs or integration of SBOMs into the package publishing process. + + +## Implementation + +The `npm-sbom` command is similar in function to `npm-ls` command and will likely utilize a similar implementation. We’ll use [arborist](https://github.com/npm/cli/tree/latest/workspaces/arborist) to construct the dependency tree and the [treeverse](https://github.com/isaacs/treeverse) library to traverse the tree and assemble the SBOM. + + +### Local (Linked) Dependencies + +The generated SBOM will exclude any dependencies which are referenced via links on the local file system. A warning will be displayed for any linked dependency informing the user that it was omitted from the SBOM. + + +### Format Details + +Both of the SBOM formats present a flat list of dependencies (CycloneDX groups these under a key named `components` while SPDX groups them under a key named `packages`). The following sections describe how a dependency will be presented for the different SBOM formats. + + +#### CycloneDX + +```json +{ + "type": "library", + "name": "debug", + "version": "4.3.4", + "bom-ref": "debug@4.3.4", + "purl": "pkg:npm/debug@4.3.4", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "node_modules/debug" + } + ], + "hashes": [ + { + "alg": "SHA-512", + "content": "3d15851ee494dde0ed4093ef9cd63b..." + } + ] +} +``` + +Scoped packages will have a [group](https://cyclonedx.org/docs/1.5/json/#components_items_group) field which identifies just the scope portion of the package name. For example: + +```json +{ + "type": "library", + "name": "node14", + "group": "@tsconfig", + "version": "1.0.3", + "bom-ref": "@tsconfig/node14@1.0.3" +} +``` + +The [properties](https://cyclonedx.org/docs/1.5/json/#components_items_properties) collection also provides for a standard property under the [npm taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/npm.md) for annotating development dependencies. For any package which was determined to be a development dependency of the root project, we would add the following to the properties collection: + +```json +{ + "name": "cdx:npm:package:development", + "value": true +} +``` + +#### SPDX + +```json +{ + "name": "debug", + "SPDXID": "SPDXRef-Package-debug-4.3.4", + "versionInfo": "4.3.4", + "downloadLocation": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "npm", + "referenceLocator": "debug@4.3.4" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "purl", + "referenceLocator": "pkg:npm/debug@4.3.4" + } + ], + "checksums": [ + { + "algorithm": "SHA512", + "checksumValue": "3d15851ee494dde0ed4093ef9cd63b..." + } + ] +} +``` + +The example record shown above conforms to version 2.3 of the SPDX [Package](https://spdx.github.io/spdx-spec/v2.3/package-information/) specification. + +The [downloadLocation](https://spdx.github.io/spdx-spec/v2.3/package-information/#77-package-download-location-field) field will report the resolved location calculated by Arborist. This may point to a package registry, or a git URL for dependencies referenced directly from git. The top-level project will specify a value of NOASSERTION for the download location as this information is not available. + +All packages will specify a `false` value for the [filesAnaylzed](https://spdx.github.io/spdx-spec/v2.3/package-information/#78-files-analyzed-field) field to signal that no assertions are being made about the files contained within a package. + +The [externalRefs](https://spdx.github.io/spdx-spec/v2.3/package-information/#721-external-reference-field) field will contain two [PACKAGE-MANAGER](https://spdx.github.io/spdx-spec/v2.3/external-repository-identifiers/#f3-package-manager) references, one using the [npm](https://spdx.github.io/spdx-spec/v2.3/external-repository-identifiers/#f32-npm) reference type and the other using the [purl](https://spdx.github.io/spdx-spec/v2.3/external-repository-identifiers/#f35-purl) reference type. + + +## Unresolved Questions and Bikeshedding + +* There’s a case to be made that SBOM generation should just be a flag on the existing `npm-ls` command – an SBOM is really just a different format of the output already generated by `npm-ls` (in fact, the CycloneDX tool described above parses the output from `npm-ls` in order to generate its SBOM). However, many of the arguments supported by `npm-ls` don’t really make sense in the context of SBOM generation (package spec filtering, depth, etc…) so it feels like a bit of an awkward fit. \ + \ +Making it a distinct command allows us to add SBOM-specific features in the future like a `--sign` flag which could be used to generate a signed SBOM. \ + \ +_Recommendation: Add a distinct command for generating an SBOM._ + +* SPDX doesn’t provide a natural way to differentiate between the various npm dependency types like “dev”, “peer”, and “optional”. We might consider using something like the [package comment field](https://spdx.github.io/spdx-spec/v2.3/package-information/#720-package-comment-field) to capture this information. \ + \ + _Recommendation: Skip for the first version of this feature. Wait to see if there is demand for this information and/or if the specification evolves to account for this metadata._ + +* Does `npm-sbom` command have a notion of a “default” SBOM format? Do we give preference to one of CycloneDX/SPDX or do we remain totally neutral (possibly at the expense of DX)? \ + \ +_Recommendation: Default to SPDX if no format is specified._ + +* Both CycloneDX and SPDX support multiple document formats (JSON, XML, Protocol Buffers, etc). Should we support output of multiple formats, or do we stick w/ JSON? \ + \ +_Recommendation: Stick with JSON-only for the first version of this feature._ + + +## Example SBOMs + +The sections below show what the different SBOM formats would look like for a basic npm project with a handful of dependencies. + +The _package.json_ file below describes a “hello-world” application with two direct dependencies: the `debug` package and the `@tsconfig/node14` package (which is listed as a development dependency). The `debug` package itself has a dependency on the `ms` package. + +```json +{ + "name": "hello-world", + "version": "1.0.0", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/example/hello-world.git" + }, + "dependencies": { + "debug": "^4.3.0" + }, + "devDependencies": { + "@tsconfig/node14": "^14.1.0" + } +} +``` + +The complete dependency tree for this project looks like this: + +``` +$ npm ls + +hello-world@1.0.0 +├── @tsconfig/node14@14.1.0 +└─┬ debug@4.3.4 + └── ms@2.1.2 +``` + + +### CycloneDX + +The proposed CycloneDX SBOM generated for the project above would look like the following: + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:1b4cd070-3f4c-4f63-965e-4ab302ad7b41", + "version": 1, + "metadata": { + "timestamp": "2023-08-04T21:37:16.639Z", + "tools": [ + { + "vendor": "npm", + "name": "cli", + "version": "9.8.1" + } + ], + "component": { + "type": "application", + "name": "hello-world", + "version": "1.0.0", + "bom-ref": "hello-world@1.0.0", + "purl": "pkg:npm/hello-world@1.0.0", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "" + } + ] + } + }, + "components": [ + { + "type": "library", + "name": "node14", + "group": "@tsconfig", + "version": "1.0.3", + "bom-ref": "@tsconfig/node14@1.0.3", + "purl": "pkg:npm/%40tsconfig/node14@1.0.3", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "node_modules/@tsconfig/node14" + }, + { + "name": "cdx:npm:package:development", + "value": true + } + ], + "hashes": [ + { + "alg": "SHA-512", + "content": "cac4fc9a1762c562..." + } + ] + }, + { + "type": "library", + "name": "debug", + "version": "4.3.4", + "bom-ref": "debug@4.3.4", + "purl": "pkg:npm/debug@4.3.4", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "node_modules/debug" + } + ], + "hashes": [ + { + "alg": "SHA-512", + "content": "3d15851ee494dde0..." + } + ] + }, + { + "type": "library", + "name": "ms", + "version": "2.1.2", + "bom-ref": "ms@2.1.2", + "purl": "pkg:npm/ms@2.1.2", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "node_modules/ms" + } + ], + "hashes": [ + { + "alg": "SHA-512", + "content": "b0690fc7e56332d9..." + } + ] + } + ] +} +``` + +### SPDX + +The proposed SPDX SBOM generated for the project above would look like the following: + +```json +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPXID": "SPDXRef-DOCUMENT", + "name": "hello-world@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/hello-world-1.0.0-", + "creationInfo": { + "created": "2023-08-04T21:41:02.071Z", + "creators": [ + "Tool: pkg:npm/cli@9.8.1" + ] + }, + "packages": [ + { + "name": "hello-world", + "SPDXID": "SPDXRef-Package-hello-world-1.0.0", + "versionInfo": "1.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "npm", + "referenceLocator": "hello-world@1.0.0" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "purl", + "referenceLocator": "pkg:npm/hello-world@1.0.0" + } + ] + }, + { + "name": "@tsconfig/node14", + "SPDXID": "SPDXRef-Package-tsconfig.node14-1.0.3", + "versionInfo": "1.0.3", + "downloadLocation": "https://registry.npmjs.org/@tsconfig/node14/...", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "npm", + "referenceLocator": "@tsconfig/node14@1.0.3" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "purl", + "referenceLocator": "pkg:npm/%40tsconfig/node14@1.0.3" + } + ], + "checksums": [ + { + "algorithm": "SHA512", + "checksumValue": "cac4fc9a1762c562..." + } + ] + }, + { + "name": "debug", + "SPDXID": "SPDXRef-Package-debug-4.3.4", + "versionInfo": "4.3.4", + "downloadLocation": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "npm", + "referenceLocator": "debug@4.3.4" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "purl", + "referenceLocator": "pkg:npm/debug@4.3.4" + } + ], + "checksums": [ + { + "algorithm": "SHA512", + "checksumValue": "3d15851ee494dde0..." + } + ] + }, + { + "name": "ms", + "SPDXID": "SPDXRef-Package-ms-2.1.2", + "versionInfo": "2.1.2", + "downloadLocation": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "npm", + "referenceLocator": "ms@2.1.2" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referernceType": "purl", + "referenceLocator": "pkg:npm/ms@2.1.2" + } + ], + "checksums": [ + { + "algorithm": "SHA512", + "checksumValue": "b0690fc7e56332d9..." + } + ] + } + ] +} +``` + +## References + +* [NTIA Software Bill of Materials](https://ntia.gov/page/software-bill-materials) +* [OSSF - SBOM Everywhere SIG](https://github.com/ossf/sbom-everywhere) +* [Authoritative Guide to SBOM](https://cyclonedx.org/guides/sbom/OWASP_CycloneDX-SBOM-Guide-en.pdf) +* [SPDX Spec v2.3](https://spdx.github.io/spdx-spec/v2.3/) From 0b6acf767e60bde31b263a99068d7b1f61d7adae Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 8 Aug 2023 16:05:29 -0700 Subject: [PATCH 02/22] sbom rfc refinement Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 30e73ca1..399b0337 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -2,7 +2,7 @@ ## Summary -Update the npm CLI with a new command which will generate a Software Bill of Materials (SBOM) for the current project. Users will have the option to generate an SBOM conforming to either the [Software Package Data Exchange (SPDX](https://spdx.github.io/spdx-spec/v2.3/)) or [CycloneDX](https://cyclonedx.org/specification/overview/) specifications. +Update the npm CLI with a new command which will generate a Software Bill of Materials (SBOM) containing an inventory of the current project's dependencies. Users will have the option to generate an SBOM conforming to either the [Software Package Data Exchange (SPDX](https://spdx.github.io/spdx-spec/v2.3/)) or [CycloneDX](https://cyclonedx.org/specification/overview/) specifications. ## Motivation @@ -23,9 +23,9 @@ A new `sbom` command will be added to the npm CLI which will generate an SBOM fo Supported command options: -`--sbom-format` - SBOM format to use for output. Valid values are “spdx” or “cyclonedx”. +`--sbom-format` - SBOM format to use for output. Valid values are “spdx” or “cyclonedx”. In the future, the set of valid values can be expanded to select differents versions of the supported output formats (e.g. "cyclonedx1.4" vs "cyclonedx1.5") -`--omit` - Dependency types to omit from generated SBOM. Valid values are “dev”, “optional”, and “peer” (can be set multiple times). +`--omit` - Dependency types to omit from generated SBOM. Valid values are “dev”, “optional”, and “peer” (can be set multiple times). By default, all development, optional, and peer dependencies will be included in the generated SBOM unless explicitly excluded. `--package-lock-only` - Constructs the SBOM based on the tree described by the _package-lock.json_, rather than the contents of _node_modules_. Defaults to _false_. If the _node_modules_ folder is not present, this flag will be required in order to generate an SBOM. @@ -35,6 +35,8 @@ Supported command options: If the user runs the `sbom` command without first installing the dependencies for the project (i.e. there is no _node_modules_ folder present) an error will be displayed. An SBOM can be generated solely based on the contents of the _package-lock.json_ but requires the user to explicitly specify the `--package-lock-only` flag. +Initially, we'll support the most widely used versions of the SPDX and CycloneDX specifications (likely v2.3 for SPDX and v1.4 for CycloneDX). Best effort will be made to support new versions as they gain adoption across the ecosystem. + ## Rationale and Alternatives @@ -85,24 +87,12 @@ Both of the SBOM formats present a flat list of dependencies (CycloneDX groups t } ``` -Scoped packages will have a [group](https://cyclonedx.org/docs/1.5/json/#components_items_group) field which identifies just the scope portion of the package name. For example: - -```json -{ - "type": "library", - "name": "node14", - "group": "@tsconfig", - "version": "1.0.3", - "bom-ref": "@tsconfig/node14@1.0.3" -} -``` - -The [properties](https://cyclonedx.org/docs/1.5/json/#components_items_properties) collection also provides for a standard property under the [npm taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/npm.md) for annotating development dependencies. For any package which was determined to be a development dependency of the root project, we would add the following to the properties collection: +The [properties](https://cyclonedx.org/docs/1.4/json/#components_items_properties) collection also provides for a standard property under the [npm taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/npm.md) for annotating development dependencies. For any package which was determined to be a development dependency of the root project, we would add the following to the properties collection: ```json { "name": "cdx:npm:package:development", - "value": true + "value": "true" } ``` @@ -208,9 +198,9 @@ The proposed CycloneDX SBOM generated for the project above would look like the ```json { - "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.4", "serialNumber": "urn:uuid:1b4cd070-3f4c-4f63-965e-4ab302ad7b41", "version": 1, "metadata": { @@ -239,8 +229,7 @@ The proposed CycloneDX SBOM generated for the project above would look like the "components": [ { "type": "library", - "name": "node14", - "group": "@tsconfig", + "name": "@tsconfig/node14", "version": "1.0.3", "bom-ref": "@tsconfig/node14@1.0.3", "purl": "pkg:npm/%40tsconfig/node14@1.0.3", @@ -251,7 +240,7 @@ The proposed CycloneDX SBOM generated for the project above would look like the }, { "name": "cdx:npm:package:development", - "value": true + "value": "true" } ], "hashes": [ @@ -422,6 +411,7 @@ The proposed SPDX SBOM generated for the project above would look like the follo ## References * [NTIA Software Bill of Materials](https://ntia.gov/page/software-bill-materials) +* [Types of Sofware Bill of Materials (SBOM) Documents](https://www.cisa.gov/sites/default/files/2023-04/sbom-types-document-508c.pdf) * [OSSF - SBOM Everywhere SIG](https://github.com/ossf/sbom-everywhere) * [Authoritative Guide to SBOM](https://cyclonedx.org/guides/sbom/OWASP_CycloneDX-SBOM-Guide-en.pdf) * [SPDX Spec v2.3](https://spdx.github.io/spdx-spec/v2.3/) From be514e60b6ef6bddd6128cebe5dc6480f27d5750 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Wed, 9 Aug 2023 07:14:34 -0700 Subject: [PATCH 03/22] spdx example clean-up Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 399b0337..b6fefbd8 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -300,15 +300,18 @@ The proposed SPDX SBOM generated for the project above would look like the follo { "spdxVersion": "SPDX-2.3", "dataLicense": "CC0-1.0", - "SPXID": "SPDXRef-DOCUMENT", + "SPDXID": "SPDXRef-DOCUMENT", "name": "hello-world@1.0.0", "documentNamespace": "http://spdx.org/spdxdocs/hello-world-1.0.0-", "creationInfo": { "created": "2023-08-04T21:41:02.071Z", "creators": [ - "Tool: pkg:npm/cli@9.8.1" + "Tool: npm/cli-9.8.1" ] }, + "documentDescribes": [ + "SPDXRef-Package-hello-world-1.0.0" + ], "packages": [ { "name": "hello-world", @@ -319,7 +322,7 @@ The proposed SPDX SBOM generated for the project above would look like the follo "externalRefs": [ { "referenceCategory": "PACKAGE-MANAGER", - "referernceType": "npm", + "referenceType": "npm", "referenceLocator": "hello-world@1.0.0" }, { From 649fde52fa837825867c1695b523fc82dea15ad3 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Wed, 9 Aug 2023 15:37:17 -0700 Subject: [PATCH 04/22] spdx example clean-up Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 42 +++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index b6fefbd8..4553424c 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -142,10 +142,6 @@ The [externalRefs](https://spdx.github.io/spdx-spec/v2.3/package-informati Making it a distinct command allows us to add SBOM-specific features in the future like a `--sign` flag which could be used to generate a signed SBOM. \ \ _Recommendation: Add a distinct command for generating an SBOM._ - -* SPDX doesn’t provide a natural way to differentiate between the various npm dependency types like “dev”, “peer”, and “optional”. We might consider using something like the [package comment field](https://spdx.github.io/spdx-spec/v2.3/package-information/#720-package-comment-field) to capture this information. \ - \ - _Recommendation: Skip for the first version of this feature. Wait to see if there is demand for this information and/or if the specification evolves to account for this metadata._ * Does `npm-sbom` command have a notion of a “default” SBOM format? Do we give preference to one of CycloneDX/SPDX or do we remain totally neutral (possibly at the expense of DX)? \ \ @@ -304,7 +300,7 @@ The proposed SPDX SBOM generated for the project above would look like the follo "name": "hello-world@1.0.0", "documentNamespace": "http://spdx.org/spdxdocs/hello-world-1.0.0-", "creationInfo": { - "created": "2023-08-04T21:41:02.071Z", + "created": "2023-08-09T22:31:28.107Z", "creators": [ "Tool: npm/cli-9.8.1" ] @@ -327,7 +323,7 @@ The proposed SPDX SBOM generated for the project above would look like the follo }, { "referenceCategory": "PACKAGE-MANAGER", - "referernceType": "purl", + "referenceType": "purl", "referenceLocator": "pkg:npm/hello-world@1.0.0" } ] @@ -341,12 +337,12 @@ The proposed SPDX SBOM generated for the project above would look like the follo "externalRefs": [ { "referenceCategory": "PACKAGE-MANAGER", - "referernceType": "npm", + "referenceType": "npm", "referenceLocator": "@tsconfig/node14@1.0.3" }, { "referenceCategory": "PACKAGE-MANAGER", - "referernceType": "purl", + "referenceType": "purl", "referenceLocator": "pkg:npm/%40tsconfig/node14@1.0.3" } ], @@ -366,12 +362,12 @@ The proposed SPDX SBOM generated for the project above would look like the follo "externalRefs": [ { "referenceCategory": "PACKAGE-MANAGER", - "referernceType": "npm", + "referenceType": "npm", "referenceLocator": "debug@4.3.4" }, { "referenceCategory": "PACKAGE-MANAGER", - "referernceType": "purl", + "referenceType": "purl", "referenceLocator": "pkg:npm/debug@4.3.4" } ], @@ -391,12 +387,12 @@ The proposed SPDX SBOM generated for the project above would look like the follo "externalRefs": [ { "referenceCategory": "PACKAGE-MANAGER", - "referernceType": "npm", + "referenceType": "npm", "referenceLocator": "ms@2.1.2" }, { "referenceCategory": "PACKAGE-MANAGER", - "referernceType": "purl", + "referenceType": "purl", "referenceLocator": "pkg:npm/ms@2.1.2" } ], @@ -407,6 +403,28 @@ The proposed SPDX SBOM generated for the project above would look like the follo } ] } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-hello-world-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-debug-4.3.4", + "relatedSpdxElement": "SPDXRef-Package-hello-world-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-tsconfig.node14-1.0.3", + "relatedSpdxElement": "SPDXRef-Package-hello-world-1.0.0", + "relationshipType": "DEV_DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-ms-2.1.2", + "relatedSpdxElement": "SPDXRef-Package-debug-4.3.4", + "relationshipType": "DEPENDENCY_OF" + } ] } ``` From 677ca7c55d525000fa3f8ab976fc38aa5f101fcb Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Wed, 9 Aug 2023 17:20:54 -0700 Subject: [PATCH 05/22] cyclonedx example clean-up Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 37 ++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 4553424c..e62bf9cb 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -194,13 +194,13 @@ The proposed CycloneDX SBOM generated for the project above would look like the ```json { - "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "$schema": "https://cyclonedx.org/schema/bom-1.4.schema.json", "bomFormat": "CycloneDX", "specVersion": "1.4", - "serialNumber": "urn:uuid:1b4cd070-3f4c-4f63-965e-4ab302ad7b41", + "serialNumber": "urn:uuid:f2fa9eae-72f1-430c-a9b3-986ffe05bc6e", "version": 1, "metadata": { - "timestamp": "2023-08-04T21:37:16.639Z", + "timestamp": "2023-08-10T00:19:08.697Z", "tools": [ { "vendor": "npm", @@ -209,10 +209,10 @@ The proposed CycloneDX SBOM generated for the project above would look like the } ], "component": { + "bom-ref": "hello-world@1.0.0", "type": "application", "name": "hello-world", "version": "1.0.0", - "bom-ref": "hello-world@1.0.0", "purl": "pkg:npm/hello-world@1.0.0", "properties": [ { @@ -224,10 +224,10 @@ The proposed CycloneDX SBOM generated for the project above would look like the }, "components": [ { + "bom-ref": "@tsconfig/node14@1.0.3", "type": "library", "name": "@tsconfig/node14", "version": "1.0.3", - "bom-ref": "@tsconfig/node14@1.0.3", "purl": "pkg:npm/%40tsconfig/node14@1.0.3", "properties": [ { @@ -247,10 +247,10 @@ The proposed CycloneDX SBOM generated for the project above would look like the ] }, { + "bom-ref": "debug@4.3.4", "type": "library", "name": "debug", "version": "4.3.4", - "bom-ref": "debug@4.3.4", "purl": "pkg:npm/debug@4.3.4", "properties": [ { @@ -266,10 +266,10 @@ The proposed CycloneDX SBOM generated for the project above would look like the ] }, { + "bom-ref": "ms@2.1.2", "type": "library", "name": "ms", "version": "2.1.2", - "bom-ref": "ms@2.1.2", "purl": "pkg:npm/ms@2.1.2", "properties": [ { @@ -284,6 +284,29 @@ The proposed CycloneDX SBOM generated for the project above would look like the } ] } + ], + "dependencies": [ + { + "ref": "hello-world@1.0.0", + "dependsOn": [ + "debug@4.3.4", + "@tsconfig/node14@1.0.3" + ] + }, + { + "ref": "@tsconfig/node14@1.0.3", + "dependsOn": [] + }, + { + "ref": "debug@4.3.4", + "dependsOn": [ + "ms@2.1.2" + ] + }, + { + "ref": "ms@2.1.2", + "dependsOn": [] + } ] } ``` From b354cce60b48e061d54b8d5ea0845d3df6cad1ab Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Thu, 10 Aug 2023 13:03:49 -0700 Subject: [PATCH 06/22] spdx example clean-up Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index e62bf9cb..f8a99680 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -434,19 +434,19 @@ The proposed SPDX SBOM generated for the project above would look like the follo "relationshipType": "DESCRIBES" }, { - "spdxElementId": "SPDXRef-Package-debug-4.3.4", - "relatedSpdxElement": "SPDXRef-Package-hello-world-1.0.0", - "relationshipType": "DEPENDENCY_OF" + "spdxElementId": "SPDXRef-Package-hello-world-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-debug-4.3.4", + "relationshipType": "DEPENDS_ON" }, { - "spdxElementId": "SPDXRef-Package-tsconfig.node14-1.0.3", - "relatedSpdxElement": "SPDXRef-Package-hello-world-1.0.0", + "spdxElementId": "SPDXRef-Package-hello-world-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-tsconfig.node14-1.0.3", "relationshipType": "DEV_DEPENDENCY_OF" }, { - "spdxElementId": "SPDXRef-Package-ms-2.1.2", - "relatedSpdxElement": "SPDXRef-Package-debug-4.3.4", - "relationshipType": "DEPENDENCY_OF" + "spdxElementId": "SPDXRef-Package-debug-4.3.4", + "relatedSpdxElement": "SPDXRef-Package-ms-2.1.2", + "relationshipType": "DEPENDS_ON" } ] } From b550c58dfde354fa3d850ce675e0358aab088f04 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Thu, 10 Aug 2023 15:31:54 -0700 Subject: [PATCH 07/22] clarify cyclonedx npm properties Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index f8a99680..7aa2ded0 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -96,6 +96,8 @@ The [properties](https://cyclonedx.org/docs/1.4/json/#components_items_pro } ``` +Similarly, there are named properties defined for identifying things like "bundled", "private", and "extraneous" dependencies. Dependencies will be annotated with this properties as appropriate. + #### SPDX ```json From ab2cea9d60aacdddb5fcff8da41e8bf464092e5b Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Thu, 10 Aug 2023 16:31:26 -0700 Subject: [PATCH 08/22] clarify cyclonedx sbom output Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 7aa2ded0..9cd2b803 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -72,6 +72,13 @@ Both of the SBOM formats present a flat list of dependencies (CycloneDX groups t "version": "4.3.4", "bom-ref": "debug@4.3.4", "purl": "pkg:npm/debug@4.3.4", + "scope": "required", + "externalReferences": [ + { + "type": "distribution", + "url": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + } + ], "properties": [ { "name": "cdx:npm:package:path", @@ -98,6 +105,8 @@ The [properties](https://cyclonedx.org/docs/1.4/json/#components_items_pro Similarly, there are named properties defined for identifying things like "bundled", "private", and "extraneous" dependencies. Dependencies will be annotated with this properties as appropriate. +The CycloneDX specification also provides [fields](https://cyclonedx.org/docs/1.4/json/#components) for capturing other package metadata like author, license, website, etc. Not all packages provide this information, but these fields will be populated when the information is available. + #### SPDX ```json @@ -230,7 +239,14 @@ The proposed CycloneDX SBOM generated for the project above would look like the "type": "library", "name": "@tsconfig/node14", "version": "1.0.3", + "scope": "required", "purl": "pkg:npm/%40tsconfig/node14@1.0.3", + "externalReferences": [ + { + "type": "distribution", + "url": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" + } + ], "properties": [ { "name": "cdx:npm:package:path", @@ -253,7 +269,14 @@ The proposed CycloneDX SBOM generated for the project above would look like the "type": "library", "name": "debug", "version": "4.3.4", + "scope": "required", "purl": "pkg:npm/debug@4.3.4", + "externalReferences": [ + { + "type": "distribution", + "url": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + } + ], "properties": [ { "name": "cdx:npm:package:path", @@ -272,7 +295,14 @@ The proposed CycloneDX SBOM generated for the project above would look like the "type": "library", "name": "ms", "version": "2.1.2", + "scope": "required", "purl": "pkg:npm/ms@2.1.2", + "externalReferences": [ + { + "type": "distribution", + "url": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + } + ], "properties": [ { "name": "cdx:npm:package:path", From 23170c0b4cc26aedc6316c54a8e322690d0a2e77 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Mon, 14 Aug 2023 11:01:54 -0700 Subject: [PATCH 09/22] clarify use of workspace flags Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 9cd2b803..1f3a6380 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -29,9 +29,9 @@ Supported command options: `--package-lock-only` - Constructs the SBOM based on the tree described by the _package-lock.json_, rather than the contents of _node_modules_. Defaults to _false_. If the _node_modules_ folder is not present, this flag will be required in order to generate an SBOM. -`--workspace` - Runs the command only in the context of the specified workspace (can be set multiple times). +`--workspace` - When used with a project utilizing [workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces), generates an SBOM containing only the identified workspaces (the flag can be specified multiple times to capture multiple workspaces). The SBOM will be rooted in the base directory of the project but will only include the specified child workspace(s). -`--workspaces` - Runs the command in the context of all configured workspaces. +`--workspaces` - When used with a project utilizing [workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces), generates an SBOM that includes ONLY the project's child workspaces. Any dependencies which are associated exclusively with the root project will be omitted. If the user runs the `sbom` command without first installing the dependencies for the project (i.e. there is no _node_modules_ folder present) an error will be displayed. An SBOM can be generated solely based on the contents of the _package-lock.json_ but requires the user to explicitly specify the `--package-lock-only` flag. From 0912839602d5279459972c44d9161405ed02858a Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Mon, 14 Aug 2023 11:02:13 -0700 Subject: [PATCH 10/22] mention @cyclonedx/cyclonedx-library package Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 1f3a6380..de902de8 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -107,6 +107,8 @@ Similarly, there are named properties defined for identifying things like "bundl The CycloneDX specification also provides [fields](https://cyclonedx.org/docs/1.4/json/#components) for capturing other package metadata like author, license, website, etc. Not all packages provide this information, but these fields will be populated when the information is available. +For generating the CycloneDX SBOM, we could utilize the [@cyclonedx/cyclonedx-library](https://www.npmjs.com/package/@cyclonedx/cyclonedx-library) (2.9MB unpacked) package which provides data models and serializers for generating valid CycloneDX documents. This library has direct dependencies on [spdx-expression-parse](https://www.npmjs.com/package/spdx-expression-parse) (which is already included as part of the npm CLI) and [packageurl-js](https://www.npmjs.com/package/packageurl-js) (39kB unpacked). + #### SPDX ```json From 52bb0e44478b4306c97e52d3b11deb80e1dfb9a2 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Mon, 14 Aug 2023 13:23:43 -0700 Subject: [PATCH 11/22] mention @cyclonedx/cyclonedx-npm in prior art Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index de902de8..57947a9e 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -147,6 +147,9 @@ All packages will specify a `false` value for the [filesAnaylzed](https:// The [externalRefs](https://spdx.github.io/spdx-spec/v2.3/package-information/#721-external-reference-field) field will contain two [PACKAGE-MANAGER](https://spdx.github.io/spdx-spec/v2.3/external-repository-identifiers/#f3-package-manager) references, one using the [npm](https://spdx.github.io/spdx-spec/v2.3/external-repository-identifiers/#f32-npm) reference type and the other using the [purl](https://spdx.github.io/spdx-spec/v2.3/external-repository-identifiers/#f35-purl) reference type. +## Prior Art + +As it relates to the CycloneDX SBOM format, much of the capability described as part of the new `npm-sbom` command is already available in the [@cyclonedx/cyclonedx-npm](https://www.npmjs.com/package/%40cyclonedx/cyclonedx-npm) project. The `@cyclonedx/cyclonedx-npm` project also includes documentation about deriving SBOM [results](https://github.com/CycloneDX/cyclonedx-node-npm/blob/main/docs/result.md) from an npm project and [component deduplication](https://github.com/CycloneDX/cyclonedx-node-npm/blob/main/docs/component_deduplication.md). ## Unresolved Questions and Bikeshedding From f9738a1a5236117b12e66d55eba44a1a4a274647 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 22 Aug 2023 15:13:13 -0700 Subject: [PATCH 12/22] drop section on linked packages Add description of scenarios which will result in errors Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 57947a9e..02af10ee 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -13,22 +13,22 @@ SBOMs help to solve this problem by providing a standardized way to document the Beyond the security benefit there may be a regulatory requirement to provide SBOMs in some sectors. In response to some recent, high-visibility attacks, The White House has issued an [Executive Order](https://www.whitehouse.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/) which specifically includes directives which would make SBOMs a requirement for any vendor selling to the federal government. -Adding SBOM generation to the tool which many developers are already using to manage their project dependencies eliminates any friction which may come from having to adopt/learn a separate tool. +Adding SBOM generation to the tool which many developers are already using to manage their project dependencies eliminates any friction which may come from having to adopt/learn a separate tool. ## Detailed Explanation -A new `sbom` command will be added to the npm CLI which will generate an SBOM for the current project. The SBOM will use the current project as the root and enumerate all of its dependencies (similar to the way `npm-ls` does) in one of the two supported SBOM formats. See the +A new `sbom` command will be added to the npm CLI which will generate an SBOM for the current project. The SBOM will use the current project as the root and enumerate all of its dependencies (similar to the way `npm-ls` does) in one of the two supported SBOM formats. See the [Example SBOMs](#example-sboms) section for sample CycloneDX and SPDX SBOM documents. -Supported command options: +Supported command options: `--sbom-format` - SBOM format to use for output. Valid values are “spdx” or “cyclonedx”. In the future, the set of valid values can be expanded to select differents versions of the supported output formats (e.g. "cyclonedx1.4" vs "cyclonedx1.5") `--omit` - Dependency types to omit from generated SBOM. Valid values are “dev”, “optional”, and “peer” (can be set multiple times). By default, all development, optional, and peer dependencies will be included in the generated SBOM unless explicitly excluded. `--package-lock-only` - Constructs the SBOM based on the tree described by the _package-lock.json_, rather than the contents of _node_modules_. Defaults to _false_. If the _node_modules_ folder is not present, this flag will be required in order to generate an SBOM. - + `--workspace` - When used with a project utilizing [workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces), generates an SBOM containing only the identified workspaces (the flag can be specified multiple times to capture multiple workspaces). The SBOM will be rooted in the base directory of the project but will only include the specified child workspace(s). `--workspaces` - When used with a project utilizing [workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces), generates an SBOM that includes ONLY the project's child workspaces. Any dependencies which are associated exclusively with the root project will be omitted. @@ -52,13 +52,14 @@ While you can effectively generate the same output we’re proposing with this c The `npm-sbom` command is similar in function to `npm-ls` command and will likely utilize a similar implementation. We’ll use [arborist](https://github.com/npm/cli/tree/latest/workspaces/arborist) to construct the dependency tree and the [treeverse](https://github.com/isaacs/treeverse) library to traverse the tree and assemble the SBOM. +### Errors -### Local (Linked) Dependencies - -The generated SBOM will exclude any dependencies which are referenced via links on the local file system. A warning will be displayed for any linked dependency informing the user that it was omitted from the SBOM. +When using the `node_modules` to render the SBOM (i.e. when NOT using the `--package-lock-only` flag) and of the following conditions will cause an error to be reported and prevent the SBOM from being generated: +- Any missing dependencies which are NOT marked as optional +- Any invalid dependencies (e.g. a mismatch between the `package-lock.json` and the `node_modules`) -### Format Details +### Format Details Both of the SBOM formats present a flat list of dependencies (CycloneDX groups these under a key named `components` while SPDX groups them under a key named `packages`). The following sections describe how a dependency will be presented for the different SBOM formats. @@ -94,7 +95,7 @@ Both of the SBOM formats present a flat list of dependencies (CycloneDX groups t } ``` -The [properties](https://cyclonedx.org/docs/1.4/json/#components_items_properties) collection also provides for a standard property under the [npm taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/npm.md) for annotating development dependencies. For any package which was determined to be a development dependency of the root project, we would add the following to the properties collection: +The [properties](https://cyclonedx.org/docs/1.4/json/#components_items_properties) collection also provides for a standard property under the [npm taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/npm.md) for annotating development dependencies. For any package which was determined to be a development dependency of the root project, we would add the following to the properties collection: ```json { @@ -158,7 +159,7 @@ As it relates to the CycloneDX SBOM format, much of the capability described as Making it a distinct command allows us to add SBOM-specific features in the future like a `--sign` flag which could be used to generate a signed SBOM. \ \ _Recommendation: Add a distinct command for generating an SBOM._ - + * Does `npm-sbom` command have a notion of a “default” SBOM format? Do we give preference to one of CycloneDX/SPDX or do we remain totally neutral (possibly at the expense of DX)? \ \ _Recommendation: Default to SPDX if no format is specified._ @@ -197,7 +198,7 @@ The complete dependency tree for this project looks like this: ``` $ npm ls -hello-world@1.0.0 +hello-world@1.0.0 ├── @tsconfig/node14@14.1.0 └─┬ debug@4.3.4 └── ms@2.1.2 From 070d29faeaf9a4d20d4a6815ab94b8255b1c9a38 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Wed, 23 Aug 2023 16:50:09 -0700 Subject: [PATCH 13/22] update recommendation about format neutrality Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 02af10ee..54194516 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -23,7 +23,7 @@ A new `sbom` command will be added to the npm CLI which will generate an SBOM fo Supported command options: -`--sbom-format` - SBOM format to use for output. Valid values are “spdx” or “cyclonedx”. In the future, the set of valid values can be expanded to select differents versions of the supported output formats (e.g. "cyclonedx1.4" vs "cyclonedx1.5") +`--sbom-format` - SBOM format to use for output. Valid values are “spdx” or “cyclonedx”. In the future, the set of valid values can be expanded to select differents versions of the supported output formats (e.g. "cyclonedx1.4" vs "cyclonedx1.5"). `--omit` - Dependency types to omit from generated SBOM. Valid values are “dev”, “optional”, and “peer” (can be set multiple times). By default, all development, optional, and peer dependencies will be included in the generated SBOM unless explicitly excluded. @@ -162,7 +162,7 @@ _Recommendation: Add a distinct command for generating an SBOM._ * Does `npm-sbom` command have a notion of a “default” SBOM format? Do we give preference to one of CycloneDX/SPDX or do we remain totally neutral (possibly at the expense of DX)? \ \ -_Recommendation: Default to SPDX if no format is specified._ +_Recommendation: Remain neutral with regard to SPDX vs CycloneDX. Make the `--sbom-format` flag mandatory. * Both CycloneDX and SPDX support multiple document formats (JSON, XML, Protocol Buffers, etc). Should we support output of multiple formats, or do we stick w/ JSON? \ \ From 9db5619d1d0f12f090061cc928a72c28ff7f2837 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 13:01:44 -0700 Subject: [PATCH 14/22] add --sbom-type flag Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 54194516..7fe48418 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -25,6 +25,8 @@ Supported command options: `--sbom-format` - SBOM format to use for output. Valid values are “spdx” or “cyclonedx”. In the future, the set of valid values can be expanded to select differents versions of the supported output formats (e.g. "cyclonedx1.4" vs "cyclonedx1.5"). +`--sbom-type` - Type of project for which the SBOM is being generated. Valid values are "library", "application", and "framework". For CycloneDX SBOMs, this value will be recorded as the `type` of the root component. For SPDX SBOMs, this value will be recorded as the `primaryPackagePurpose` of the root package. Defaults to "library". + `--omit` - Dependency types to omit from generated SBOM. Valid values are “dev”, “optional”, and “peer” (can be set multiple times). By default, all development, optional, and peer dependencies will be included in the generated SBOM unless explicitly excluded. `--package-lock-only` - Constructs the SBOM based on the tree described by the _package-lock.json_, rather than the contents of _node_modules_. Defaults to _false_. If the _node_modules_ folder is not present, this flag will be required in order to generate an SBOM. From 617337e712ec22669c7106bc275403f3211d0fe7 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 13:02:26 -0700 Subject: [PATCH 15/22] add info about cdx lifecycle phase Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 7fe48418..fdcbf9cf 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -29,7 +29,7 @@ Supported command options: `--omit` - Dependency types to omit from generated SBOM. Valid values are “dev”, “optional”, and “peer” (can be set multiple times). By default, all development, optional, and peer dependencies will be included in the generated SBOM unless explicitly excluded. -`--package-lock-only` - Constructs the SBOM based on the tree described by the _package-lock.json_, rather than the contents of _node_modules_. Defaults to _false_. If the _node_modules_ folder is not present, this flag will be required in order to generate an SBOM. +`--package-lock-only` - Constructs the SBOM based on the tree described by the _package-lock.json_, rather than the contents of _node_modules_. For CycloneDX SBOMs, the [lifecycle phase](https://cyclonedx.org/guides/sbom/lifecycle_phases/) will be set to "pre-build" when this option is _true_. Defaults to _false_. If the _node_modules_ folder is not present, this flag will be required in order to generate an SBOM. `--workspace` - When used with a project utilizing [workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces), generates an SBOM containing only the identified workspaces (the flag can be specified multiple times to capture multiple workspaces). The SBOM will be rooted in the base directory of the project but will only include the specified child workspace(s). @@ -220,6 +220,9 @@ The proposed CycloneDX SBOM generated for the project above would look like the "version": 1, "metadata": { "timestamp": "2023-08-10T00:19:08.697Z", + "lifecycles": [ + { "phase": "build" } + ], "tools": [ { "vendor": "npm", From fd7783d9d124bd7a97283d16971dfeb632dec347 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 13:03:31 -0700 Subject: [PATCH 16/22] add info about negated --workspaces command Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index fdcbf9cf..38796e3c 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -33,7 +33,7 @@ Supported command options: `--workspace` - When used with a project utilizing [workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces), generates an SBOM containing only the identified workspaces (the flag can be specified multiple times to capture multiple workspaces). The SBOM will be rooted in the base directory of the project but will only include the specified child workspace(s). -`--workspaces` - When used with a project utilizing [workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces), generates an SBOM that includes ONLY the project's child workspaces. Any dependencies which are associated exclusively with the root project will be omitted. +`--workspaces` - When used with a project utilizing [workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces), generates an SBOM that includes ONLY the project's child workspaces. Any dependencies which are associated exclusively with the root project will be omitted. This flag can be negated (`--no-workspaces`) to filter out all of the project's workspaces. If the user runs the `sbom` command without first installing the dependencies for the project (i.e. there is no _node_modules_ folder present) an error will be displayed. An SBOM can be generated solely based on the contents of the _package-lock.json_ but requires the user to explicitly specify the `--package-lock-only` flag. From 7da3739d5057e5dcdcb44c19018a7538e43631d2 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 13:04:15 -0700 Subject: [PATCH 17/22] switch recommended cdx format to 1.5 Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 38796e3c..02287bbf 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -37,7 +37,7 @@ Supported command options: If the user runs the `sbom` command without first installing the dependencies for the project (i.e. there is no _node_modules_ folder present) an error will be displayed. An SBOM can be generated solely based on the contents of the _package-lock.json_ but requires the user to explicitly specify the `--package-lock-only` flag. -Initially, we'll support the most widely used versions of the SPDX and CycloneDX specifications (likely v2.3 for SPDX and v1.4 for CycloneDX). Best effort will be made to support new versions as they gain adoption across the ecosystem. +Initially, we'll support the most widely used versions of the SPDX and CycloneDX specifications (likely v2.3 for SPDX and v1.5 for CycloneDX). Best effort will be made to support new versions as they gain adoption across the ecosystem. ## Rationale and Alternatives @@ -97,7 +97,7 @@ Both of the SBOM formats present a flat list of dependencies (CycloneDX groups t } ``` -The [properties](https://cyclonedx.org/docs/1.4/json/#components_items_properties) collection also provides for a standard property under the [npm taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/npm.md) for annotating development dependencies. For any package which was determined to be a development dependency of the root project, we would add the following to the properties collection: +The [properties](https://cyclonedx.org/docs/1.5/json/#components_items_properties) collection also provides for a standard property under the [npm taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy/blob/main/cdx/npm.md) for annotating development dependencies. For any package which was determined to be a development dependency of the root project, we would add the following to the properties collection: ```json { @@ -108,7 +108,7 @@ The [properties](https://cyclonedx.org/docs/1.4/json/#components_items_pro Similarly, there are named properties defined for identifying things like "bundled", "private", and "extraneous" dependencies. Dependencies will be annotated with this properties as appropriate. -The CycloneDX specification also provides [fields](https://cyclonedx.org/docs/1.4/json/#components) for capturing other package metadata like author, license, website, etc. Not all packages provide this information, but these fields will be populated when the information is available. +The CycloneDX specification also provides [fields](https://cyclonedx.org/docs/1.5/json/#components) for capturing other package metadata like author, license, website, etc. Not all packages provide this information, but these fields will be populated when the information is available. For generating the CycloneDX SBOM, we could utilize the [@cyclonedx/cyclonedx-library](https://www.npmjs.com/package/@cyclonedx/cyclonedx-library) (2.9MB unpacked) package which provides data models and serializers for generating valid CycloneDX documents. This library has direct dependencies on [spdx-expression-parse](https://www.npmjs.com/package/spdx-expression-parse) (which is already included as part of the npm CLI) and [packageurl-js](https://www.npmjs.com/package/packageurl-js) (39kB unpacked). @@ -213,9 +213,9 @@ The proposed CycloneDX SBOM generated for the project above would look like the ```json { - "$schema": "https://cyclonedx.org/schema/bom-1.4.schema.json", + "$schema": "https://cyclonedx.org/schema/bom-1.5.schema.json", "bomFormat": "CycloneDX", - "specVersion": "1.4", + "specVersion": "1.5", "serialNumber": "urn:uuid:f2fa9eae-72f1-430c-a9b3-986ffe05bc6e", "version": 1, "metadata": { From 777f3dca673c5c10844002a292f7bc0007464c55 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 13:05:11 -0700 Subject: [PATCH 18/22] update impl description Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 02287bbf..4999e9ac 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -52,11 +52,11 @@ While you can effectively generate the same output we’re proposing with this c ## Implementation -The `npm-sbom` command is similar in function to `npm-ls` command and will likely utilize a similar implementation. We’ll use [arborist](https://github.com/npm/cli/tree/latest/workspaces/arborist) to construct the dependency tree and the [treeverse](https://github.com/isaacs/treeverse) library to traverse the tree and assemble the SBOM. +The `npm-sbom` command will use [arborist](https://github.com/npm/cli/tree/latest/workspaces/arborist) to construct the dependency tree for the current project and then invoke `querySelectorAll` to select the set of nodes to be included in the SBOM. ### Errors -When using the `node_modules` to render the SBOM (i.e. when NOT using the `--package-lock-only` flag) and of the following conditions will cause an error to be reported and prevent the SBOM from being generated: +When using the `node_modules` to render the SBOM (i.e. when NOT using the `--package-lock-only` flag) any of the following conditions will cause an error to be reported and prevent the SBOM from being generated: - Any missing dependencies which are NOT marked as optional - Any invalid dependencies (e.g. a mismatch between the `package-lock.json` and the `node_modules`) From 1ff7335097b682978d4a03f38baea50e8545f987 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 13:05:51 -0700 Subject: [PATCH 19/22] remove bikeshedding about re-using npm-ls Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 4999e9ac..52f48fb2 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -156,12 +156,6 @@ As it relates to the CycloneDX SBOM format, much of the capability described as ## Unresolved Questions and Bikeshedding -* There’s a case to be made that SBOM generation should just be a flag on the existing `npm-ls` command – an SBOM is really just a different format of the output already generated by `npm-ls` (in fact, the CycloneDX tool described above parses the output from `npm-ls` in order to generate its SBOM). However, many of the arguments supported by `npm-ls` don’t really make sense in the context of SBOM generation (package spec filtering, depth, etc…) so it feels like a bit of an awkward fit. \ - \ -Making it a distinct command allows us to add SBOM-specific features in the future like a `--sign` flag which could be used to generate a signed SBOM. \ - \ -_Recommendation: Add a distinct command for generating an SBOM._ - * Does `npm-sbom` command have a notion of a “default” SBOM format? Do we give preference to one of CycloneDX/SPDX or do we remain totally neutral (possibly at the expense of DX)? \ \ _Recommendation: Remain neutral with regard to SPDX vs CycloneDX. Make the `--sbom-format` flag mandatory. From d20e4c5d3e219f09b3cde32c74ea30474254225a Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 13:09:42 -0700 Subject: [PATCH 20/22] formatting fixup Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 52f48fb2..01db8b48 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -158,11 +158,11 @@ As it relates to the CycloneDX SBOM format, much of the capability described as * Does `npm-sbom` command have a notion of a “default” SBOM format? Do we give preference to one of CycloneDX/SPDX or do we remain totally neutral (possibly at the expense of DX)? \ \ -_Recommendation: Remain neutral with regard to SPDX vs CycloneDX. Make the `--sbom-format` flag mandatory. +_Recommendation:_ Remain neutral with regard to SPDX vs CycloneDX. Make the `--sbom-format` flag mandatory. * Both CycloneDX and SPDX support multiple document formats (JSON, XML, Protocol Buffers, etc). Should we support output of multiple formats, or do we stick w/ JSON? \ \ -_Recommendation: Stick with JSON-only for the first version of this feature._ +_Recommendation:_ Stick with JSON-only for the first version of this feature. ## Example SBOMs From 4f140b90d6a41418729b3d10c755e4f14faabcc4 Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 14:36:50 -0700 Subject: [PATCH 21/22] update spdx exmample Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 50 ++++++++++++++++------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 01db8b48..837fb2bb 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -360,9 +360,9 @@ The proposed SPDX SBOM generated for the project above would look like the follo "name": "hello-world@1.0.0", "documentNamespace": "http://spdx.org/spdxdocs/hello-world-1.0.0-", "creationInfo": { - "created": "2023-08-09T22:31:28.107Z", + "created": "2023-09-12T21:32:11.984Z", "creators": [ - "Tool: npm/cli-9.8.1" + "Tool: npm/cli-10.1.0" ] }, "documentDescribes": [ @@ -373,14 +373,13 @@ The proposed SPDX SBOM generated for the project above would look like the follo "name": "hello-world", "SPDXID": "SPDXRef-Package-hello-world-1.0.0", "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", "downloadLocation": "NOASSERTION", "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "ISC", "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "npm", - "referenceLocator": "hello-world@1.0.0" - }, { "referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", @@ -390,26 +389,25 @@ The proposed SPDX SBOM generated for the project above would look like the follo }, { "name": "@tsconfig/node14", - "SPDXID": "SPDXRef-Package-tsconfig.node14-1.0.3", - "versionInfo": "1.0.3", + "SPDXID": "SPDXRef-Package-tsconfig.node14-14.1.0", + "versionInfo": "14.1.0", + "packageFileName": "node_modules/@tsconfig/node14", + "description": "A base TSConfig for working with Node 14.", "downloadLocation": "https://registry.npmjs.org/@tsconfig/node14/...", "filesAnalyzed": false, + "homepage": "https://github.com/tsconfig/bases#readme", + "licenseDeclared": "MIT", "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "npm", - "referenceLocator": "@tsconfig/node14@1.0.3" - }, { "referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", - "referenceLocator": "pkg:npm/%40tsconfig/node14@1.0.3" + "referenceLocator": "pkg:npm/%40tsconfig/node14@14.1.0" } ], "checksums": [ { "algorithm": "SHA512", - "checksumValue": "cac4fc9a1762c562..." + "checksumValue": "566b021b4e18479f..." } ] }, @@ -417,14 +415,13 @@ The proposed SPDX SBOM generated for the project above would look like the follo "name": "debug", "SPDXID": "SPDXRef-Package-debug-4.3.4", "versionInfo": "4.3.4", + "packageFileName": "node_modules/debug", + "description": "Lightweight debugging utility for Node.js and the browser", "downloadLocation": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "filesAnalyzed": false, + "homepage": "https://github.com/debug-js/debug#readme", + "licenseDeclared": "MIT", "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "npm", - "referenceLocator": "debug@4.3.4" - }, { "referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", @@ -442,14 +439,13 @@ The proposed SPDX SBOM generated for the project above would look like the follo "name": "ms", "SPDXID": "SPDXRef-Package-ms-2.1.2", "versionInfo": "2.1.2", + "packageFileName": "node_modules/ms", + "description": "Tiny millisecond conversion utility", "downloadLocation": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "filesAnalyzed": false, + "homepage": "https://github.com/zeit/ms#readme", + "licenseDeclared": "MIT", "externalRefs": [ - { - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "npm", - "referenceLocator": "ms@2.1.2" - }, { "referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", @@ -477,7 +473,7 @@ The proposed SPDX SBOM generated for the project above would look like the follo }, { "spdxElementId": "SPDXRef-Package-hello-world-1.0.0", - "relatedSpdxElement": "SPDXRef-Package-tsconfig.node14-1.0.3", + "relatedSpdxElement": "SPDXRef-Package-tsconfig.node14-14.1.0", "relationshipType": "DEV_DEPENDENCY_OF" }, { From 8370368ebb0903d44e94485a04a94e0eccc542fd Mon Sep 17 00:00:00 2001 From: Brian DeHamer Date: Tue, 12 Sep 2023 14:45:31 -0700 Subject: [PATCH 22/22] update cdx example Signed-off-by: Brian DeHamer --- accepted/0000-sbom-command.md | 128 ++++++++++++++++++++++++++-------- 1 file changed, 100 insertions(+), 28 deletions(-) diff --git a/accepted/0000-sbom-command.md b/accepted/0000-sbom-command.md index 837fb2bb..0ec5dd53 100644 --- a/accepted/0000-sbom-command.md +++ b/accepted/0000-sbom-command.md @@ -207,21 +207,23 @@ The proposed CycloneDX SBOM generated for the project above would look like the ```json { - "$schema": "https://cyclonedx.org/schema/bom-1.5.schema.json", + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", "bomFormat": "CycloneDX", "specVersion": "1.5", - "serialNumber": "urn:uuid:f2fa9eae-72f1-430c-a9b3-986ffe05bc6e", + "serialNumber": "urn:uuid:0ffefc31-0159-4197-8551-26103dd0280f", "version": 1, "metadata": { - "timestamp": "2023-08-10T00:19:08.697Z", + "timestamp": "2023-09-12T21:40:13.091Z", "lifecycles": [ - { "phase": "build" } + { + "phase": "build" + } ], "tools": [ { "vendor": "npm", "name": "cli", - "version": "9.8.1" + "version": "10.1.0" } ], "component": { @@ -229,29 +231,33 @@ The proposed CycloneDX SBOM generated for the project above would look like the "type": "application", "name": "hello-world", "version": "1.0.0", + "scope": "required", "purl": "pkg:npm/hello-world@1.0.0", "properties": [ { "name": "cdx:npm:package:path", "value": "" } + ], + "externalReferences": [], + "licenses": [ + { + "license": { + "id": "ISC" + } + } ] } }, "components": [ { - "bom-ref": "@tsconfig/node14@1.0.3", + "bom-ref": "@tsconfig/node14@14.1.0", "type": "library", "name": "@tsconfig/node14", - "version": "1.0.3", - "scope": "required", - "purl": "pkg:npm/%40tsconfig/node14@1.0.3", - "externalReferences": [ - { - "type": "distribution", - "url": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" - } - ], + "version": "14.1.0", + "scope": "optional", + "description": "A base TSConfig for working with Node 14.", + "purl": "pkg:npm/%40tsconfig/node14@14.1.0", "properties": [ { "name": "cdx:npm:package:path", @@ -262,10 +268,35 @@ The proposed CycloneDX SBOM generated for the project above would look like the "value": "true" } ], + "externalReferences": [ + { + "type": "distribution", + "url": "https://registry.npmjs.org/@tsconfig/node14/-/node14-14.1.0.tgz" + }, + { + "type": "vcs", + "url": "git+https://github.com/tsconfig/bases.git" + }, + { + "type": "website", + "url": "https://github.com/tsconfig/bases#readme" + }, + { + "type": "issue-tracker", + "url": "https://github.com/tsconfig/bases/issues" + } + ], "hashes": [ { "alg": "SHA-512", - "content": "cac4fc9a1762c562..." + "content": "566b021b4e18479f..." + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } } ] }, @@ -275,17 +306,31 @@ The proposed CycloneDX SBOM generated for the project above would look like the "name": "debug", "version": "4.3.4", "scope": "required", + "author": "Josh Junon", + "description": "Lightweight debugging utility for Node.js and the browser", "purl": "pkg:npm/debug@4.3.4", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "node_modules/debug" + } + ], "externalReferences": [ { "type": "distribution", "url": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - } - ], - "properties": [ + }, { - "name": "cdx:npm:package:path", - "value": "node_modules/debug" + "type": "vcs", + "url": "git://github.com/debug-js/debug.git" + }, + { + "type": "website", + "url": "https://github.com/debug-js/debug#readme" + }, + { + "type": "issue-tracker", + "url": "https://github.com/debug-js/debug/issues" } ], "hashes": [ @@ -293,6 +338,13 @@ The proposed CycloneDX SBOM generated for the project above would look like the "alg": "SHA-512", "content": "3d15851ee494dde0..." } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } ] }, { @@ -301,17 +353,30 @@ The proposed CycloneDX SBOM generated for the project above would look like the "name": "ms", "version": "2.1.2", "scope": "required", + "description": "Tiny millisecond conversion utility", "purl": "pkg:npm/ms@2.1.2", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "node_modules/ms" + } + ], "externalReferences": [ { "type": "distribution", "url": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - } - ], - "properties": [ + }, { - "name": "cdx:npm:package:path", - "value": "node_modules/ms" + "type": "vcs", + "url": "git+https://github.com/zeit/ms.git" + }, + { + "type": "website", + "url": "https://github.com/zeit/ms#readme" + }, + { + "type": "issue-tracker", + "url": "https://github.com/zeit/ms/issues" } ], "hashes": [ @@ -319,6 +384,13 @@ The proposed CycloneDX SBOM generated for the project above would look like the "alg": "SHA-512", "content": "b0690fc7e56332d9..." } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } ] } ], @@ -327,11 +399,11 @@ The proposed CycloneDX SBOM generated for the project above would look like the "ref": "hello-world@1.0.0", "dependsOn": [ "debug@4.3.4", - "@tsconfig/node14@1.0.3" + "@tsconfig/node14@14.1.0" ] }, { - "ref": "@tsconfig/node14@1.0.3", + "ref": "@tsconfig/node14@14.1.0", "dependsOn": [] }, {