syft icon indicating copy to clipboard operation
syft copied to clipboard

feat: add support for user to flag root package supplier and package supplier inheritance

Open spiffcs opened this issue 11 months ago • 0 comments

Description

This PR adds a new flag to syft called --source-supplier. This flag allows syft users to associate an optional supplier to the root component of the final document. It makes no determination about other packages cataloged by syft.

Formats updated

  • [x] syft-json
  • [x] spdx-json
  • [x] cyclonedx-json
  • [x] spdx
  • [x] cyclonedx

The --source-supplier will be used to determine the supplier of the root component of the SBOM

This allows organizations generating SBOMs who want to produce NTIA compliant documents to assume the supplier field for software/containers they are producing.

Adds supplier to the following outputs:

spdx

go run cmd/syft/main.go -o spdx alpine:latest --source-supplier optional-supplier > test.json

##### Package: alpine

PackageName: alpine
SPDXID: SPDXRef-DocumentRoot-Image-alpine
PackageVersion: sha256:47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337
PackageSupplier: optional-supplier <-----------
PackageDownloadLocation: NOASSERTION
PrimaryPackagePurpose: CONTAINER
FilesAnalyzed: false
PackageChecksum: SHA256: 47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
PackageCopyrightText: NOASSERTION
ExternalRef: PACKAGE-MANAGER purl pkg:oci/alpine@sha256%3A47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337?arch=arm64&tag=latest

spdx-json

go run cmd/syft/main.go -o spdx-json alpine:latest --supplier optional-supplier > test.json

  {
   "name": "alpine",
   "SPDXID": "SPDXRef-DocumentRoot-Image-alpine",
   "versionInfo": "sha256:47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337",
   "supplier": "Organization: optional-supplier", <-----------
   "downloadLocation": "NOASSERTION",
   "filesAnalyzed": false,
   "checksums": [
    {
     "algorithm": "SHA256",
     "checksumValue": "47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337"
    }
   ],
   "licenseConcluded": "NOASSERTION",
   "licenseDeclared": "NOASSERTION",
   "copyrightText": "NOASSERTION",
   "externalRefs": [
    {
     "referenceCategory": "PACKAGE-MANAGER",
     "referenceType": "purl",
     "referenceLocator": "pkg:oci/alpine@sha256%3A47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337?arch=arm64&tag=latest"
    }
   ],
   "primaryPackagePurpose": "CONTAINER"
  }

syft-json

go run cmd/syft/main.go -o json alpine:latest --supplier optional-supplier > test.json

 "source": {
  "id": "47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337",
  "name": "alpine",
  "version": "sha256:47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337",
  "supplier": "optional-supplier", <-----------
  "type": "image",
  "metadata": {
   "userInput": "alpine:latest",
   "imageID": "sha256:7ad00e65ee25911881c06b97a3e562675d255e1265ba4abadd3e906d266c1dcc",
   "manifestDigest": "sha256:47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337",
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "tags": [
    "alpine:latest"
   ],
   "imageSize": 8169605,

cyclonedx-json

Note: for cyclonedx-json we're putting supplier in two spots that the format supports. One is the top level BOM description. The other is for the root component identified in the bom

- `metadata.supplier`
The organization that supplied the component that the BOM describes. 
The supplier may often be the manufacturer, but may also be a distributor or repackager.
- `metadata.component.supplier`
The organization that supplied the component. 
The supplier may often be the manufacturer, but may also be a distributor or repackager.

go run cmd/syft/main.go -o cyclonedx-json alpine:latest --supplier optional-supplier > test.json

  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:f6d124b0-c4ba-48dc-96a4-6b0e12d8eefe",
  "version": 1,
  "metadata": {
    "timestamp": "2025-02-07T12:54:04-05:00",
    "tools": {
      "components": [
        {
          "type": "application",
          "author": "anchore",
          "name": "syft",
          "version": "[not provided]"
        }
      ]
    },
    "component": {
      "bom-ref": "327aecd176f7b31f",
      "type": "container",
      "supplier": {
        "name": "optional-supplier" <------
      },
      "name": "alpine",
      "version": "sha256:47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337"
    },
    "supplier": {
      "name": "optional-supplier" <-------
    }
  },

cyclonedx

<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.6" serialNumber="urn:uuid:64f0a96d-319a-4faa-a13c-5deb1f46f8c9" version="1">
  <metadata>
    <timestamp>2025-02-07T12:59:47-05:00</timestamp>
    <tools>
      <components>
        <component type="application">
          <author>anchore</author>
          <name>syft</name>
          <version>[not provided]</version>
        </component>
      </components>
    </tools>
    <component bom-ref="327aecd176f7b31f" type="container">
      <supplier>
        <name>optional-supplier</name> <------
      </supplier>
      <name>alpine</name>
      <version>sha256:47badde288cf303fe43766ba3c0be01df313b84ad91480c1f21b7e907a7f2337</version>
    </component>
    <supplier>
      <name>optional-supplier</name> <-----
    </supplier>
  </metadata>
  <components>

Fixes

  • #3098

Type of change

  • [x] New feature (non-breaking change which adds functionality)
  • [x] Documentation (updates the documentation)

Checklist:

  • [x] I have added unit tests that cover changed behavior
  • [x] I have tested my code in common scenarios and confirmed there are no regressions
  • [x] I have added comments to my code, particularly in hard-to-understand sections

spiffcs avatar Feb 05 '25 22:02 spiffcs