Repository: chainguard-dev/apko
Pull request #1690 (2025-05-28 16:34:23)

Add an OperatingSystem package to our image SBOMs
We are missing some information in our image SBOMs that cause trivy to generate warnings. The missing piece is a package declaring what operating system our images are using.

sil2100: Tested against a locally built image: the sbom seems to be correct and trivy seems to be happy with it. Ship it!

Patch:
diff --git a/pkg/sbom/generator/spdx/spdx.go b/pkg/sbom/generator/spdx/spdx.go
index 1baf2ff..38b8fea 100644
--- a/pkg/sbom/generator/spdx/spdx.go
+++ b/pkg/sbom/generator/spdx/spdx.go
@@ -134,6 +134,9 @@ func (sx *SPDX) Generate(opts *options.Options, path string) error {
 		doc.DocumentDescribes = []string{imagePackage.ID}
 	}
 
+	// Add the operating system package
+	addOperatingSystem(doc, opts)
+
 	if opts.ImageInfo.VCSUrl != "" {
 		if opts.ImageInfo.ImageDigest != "" {
 			addSourcePackage(opts.ImageInfo.VCSUrl, doc, imagePackage, opts)
@@ -623,6 +626,22 @@ func (sx *SPDX) GenerateIndex(opts *options.Options, path string) error {
 	return nil
 }
 
+// addOperatingSystem adds a package describing the operating system
+func addOperatingSystem(doc *Document, opts *options.Options) {
+	osPackage := Package{
+		ID:               fmt.Sprintf("SPDXRef-OperatingSystem-%s", stringToIdentifier(opts.OS.ID)),
+		Name:             opts.OS.ID,
+		Version:          opts.OS.Version,
+		Supplier:         supplier(opts),
+		FilesAnalyzed:    false,
+		Description:      "Operating System",
+		DownloadLocation: NOASSERTION,
+		PrimaryPurpose:   "OPERATING-SYSTEM",
+	}
+
+	doc.Packages = append(doc.Packages, osPackage)
+}
+
 // addSourcePackage creates a package describing the source code
 func addSourcePackage(vcsURL string, doc *Document, parent *Package, opts *options.Options) {
 	version := ""


Test patch:
diff --git a/internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json b/internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json
index 22d85a6..fe78b67 100644
--- a/internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json
+++ b/internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json
@@ -55,6 +55,16 @@
         }
       ]
     },
+    {
+      "SPDXID": "SPDXRef-OperatingSystem-replaces",
+      "name": "replaces",
+      "versionInfo": "1.0.0",
+      "filesAnalyzed": false,
+      "description": "Operating System",
+      "downloadLocation": "NOASSERTION",
+      "supplier": "Organization: Replaces",
+      "primaryPackagePurpose": "OPERATING-SYSTEM"
+    },
     {
       "SPDXID": "SPDXRef-Package-pretend-baselayout-1.0.0-r0",
       "name": "pretend-baselayout",
diff --git a/internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json b/internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json
index 917a618..0ff8e4d 100644
--- a/internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json
+++ b/internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json
@@ -55,6 +55,16 @@
         }
       ]
     },
+    {
+      "SPDXID": "SPDXRef-OperatingSystem-replaces",
+      "name": "replaces",
+      "versionInfo": "1.0.0",
+      "filesAnalyzed": false,
+      "description": "Operating System",
+      "downloadLocation": "NOASSERTION",
+      "supplier": "Organization: Replaces",
+      "primaryPackagePurpose": "OPERATING-SYSTEM"
+    },
     {
       "SPDXID": "SPDXRef-Package-pretend-baselayout-1.0.0-r0",
       "name": "pretend-baselayout",
diff --git a/pkg/sbom/generator/spdx/testdata/expected_image_sboms/custom-license.spdx.json b/pkg/sbom/generator/spdx/testdata/expected_image_sboms/custom-license.spdx.json
index e2666e2..3d1f71e 100644
--- a/pkg/sbom/generator/spdx/testdata/expected_image_sboms/custom-license.spdx.json
+++ b/pkg/sbom/generator/spdx/testdata/expected_image_sboms/custom-license.spdx.json
@@ -32,6 +32,16 @@
         }
       ]
     },
+    {
+      "SPDXID": "SPDXRef-OperatingSystem-unknown",
+      "name": "unknown",
+      "versionInfo": "3.0",
+      "filesAnalyzed": false,
+      "description": "Operating System",
+      "downloadLocation": "NOASSERTION",
+      "supplier": "Organization: unknown",
+      "primaryPackagePurpose": "OPERATING-SYSTEM"
+    },
     {
       "SPDXID": "SPDXRef-Package-font-ubuntu-0.869-r1",
       "name": "font-ubuntu",
diff --git a/pkg/sbom/generator/spdx/testdata/expected_image_sboms/no-supplier.spdx.json b/pkg/sbom/generator/spdx/testdata/expected_image_sboms/no-supplier.spdx.json
index 956d62c..ae20c33 100644
--- a/pkg/sbom/generator/spdx/testdata/expected_image_sboms/no-supplier.spdx.json
+++ b/pkg/sbom/generator/spdx/testdata/expected_image_sboms/no-supplier.spdx.json
@@ -32,6 +32,16 @@
         }
       ]
     },
+    {
+      "SPDXID": "SPDXRef-OperatingSystem-apko-images",
+      "name": "apko-images",
+      "versionInfo": "3.0",
+      "filesAnalyzed": false,
+      "description": "Operating System",
+      "downloadLocation": "NOASSERTION",
+      "supplier": "Organization: Apko Images, Plc",
+      "primaryPackagePurpose": "OPERATING-SYSTEM"
+    },
     {
       "SPDXID": "SPDXRef-Package-libattr1-2.5.1-r2",
       "name": "libattr1",
diff --git a/pkg/sbom/generator/spdx/testdata/expected_image_sboms/package-deduplicating.spdx.json b/pkg/sbom/generator/spdx/testdata/expected_image_sboms/package-deduplicating.spdx.json
index 3db3159..10ab92c 100644
--- a/pkg/sbom/generator/spdx/testdata/expected_image_sboms/package-deduplicating.spdx.json
+++ b/pkg/sbom/generator/spdx/testdata/expected_image_sboms/package-deduplicating.spdx.json
@@ -32,6 +32,16 @@
         }
       ]
     },
+    {
+      "SPDXID": "SPDXRef-OperatingSystem-unknown",
+      "name": "unknown",
+      "versionInfo": "3.0",
+      "filesAnalyzed": false,
+      "description": "Operating System",
+      "downloadLocation": "NOASSERTION",
+      "supplier": "Organization: unknown",
+      "primaryPackagePurpose": "OPERATING-SYSTEM"
+    },
     {
       "SPDXID": "SPDXRef-Package-logstash-8-8.15.3-r4",
       "name": "logstash-8",
diff --git a/pkg/sbom/generator/spdx/testdata/expected_image_sboms/unbound-package-dedupe.spdx.json b/pkg/sbom/generator/spdx/testdata/expected_image_sboms/unbound-package-dedupe.spdx.json
index eeb4474..c64fa66 100644
--- a/pkg/sbom/generator/spdx/testdata/expected_image_sboms/unbound-package-dedupe.spdx.json
+++ b/pkg/sbom/generator/spdx/testdata/expected_image_sboms/unbound-package-dedupe.spdx.json
@@ -32,6 +32,16 @@
         }
       ]
     },
+    {
+      "SPDXID": "SPDXRef-OperatingSystem-unknown",
+      "name": "unknown",
+      "versionInfo": "3.0",
+      "filesAnalyzed": false,
+      "description": "Operating System",
+      "downloadLocation": "NOASSERTION",
+      "supplier": "Organization: unknown",
+      "primaryPackagePurpose": "OPERATING-SYSTEM"
+    },
     {
       "SPDXID": "SPDXRef-Package-unbound-libs-1.23.0-r0",
       "name": "unbound-libs",