From dec4f8891f6f24d5b50170bb2549903b44479673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Prpi=C4=8D?= Date: Mon, 26 Aug 2024 21:13:13 -0400 Subject: [PATCH 1/3] Cosmetic changes to the mkdocs theme --- docs/stylesheets/extra.css | 3 +++ mkdocs.yml | 15 +++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 docs/stylesheets/extra.css diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..be6bff0 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,3 @@ +.md-typeset { + line-height: 1.4; +} diff --git a/mkdocs.yml b/mkdocs.yml index 939d643..d8e68c8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,7 @@ site_name: Red Hat Security Data Guidelines site_url: https://redhatproductsecurity.github.io/security-data-guidelines/ edit_uri: "https://github.com/RedHatProductSecurity/security-data-guidelines/blob/main/docs" -copyright: Copyright © Red Hat, Inc.  ·  CC BY 4.0 +copyright: Copyright © Red Hat, Inc.  ·  CC-BY-4.0 theme: name: material @@ -19,15 +19,18 @@ theme: language: en favicon: images/favicon.png logo: images/logo.png + font: + text: Red Hat Text + code: Red Hat Mono palette: - scheme: default toggle: - icon: material/toggle-switch-off-outline + icon: material/brightness-4 name: Switch to dark mode primary: black - scheme: slate toggle: - icon: material/toggle-switch + icon: material/brightness-7 name: Switch to light mode primary: black @@ -39,10 +42,13 @@ plugins: - social - search +extra_css: + - stylesheets/extra.css + extra: social: - icon: fontawesome/brands/github-alt - link: https://github.com/RedHatProductSecurity + link: https://github.com/RedHatProductSecurity/security-data-guidelines - icon: fontawesome/regular/envelope link: "mailto:secalert@redhat.com" @@ -55,6 +61,7 @@ markdown_extensions: - attr_list - abbr # https://squidfunk.github.io/mkdocs-material/reference/tooltips/#adding-abbreviations - md_in_html + - def_list # https://squidfunk.github.io/mkdocs-material/reference/lists/#using-definition-lists - pymdownx.superfences - pymdownx.tabbed: alternate_style: true From 1792446b3b649fb76a8558edb1e39049fd092b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Prpi=C4=8D?= Date: Mon, 26 Aug 2024 21:14:15 -0400 Subject: [PATCH 2/3] Change license; use UTC time; add newlines at the ends of files --- ...odule-management-operator-container-1.1.2-25.spdx.json | 6 +++--- ...management-operator-container-1.1.2-25_amd64.spdx.json | 6 +++--- ...management-operator-container-1.1.2-25_arm64.spdx.json | 6 +++--- ...nagement-operator-container-1.1.2-25_ppc64le.spdx.json | 6 +++--- .../examples/container_image/build/remove_release_data.py | 4 +++- .../build/ubi9-micro-container-9.4-6.1716471860.spdx.json | 6 +++--- .../ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json | 6 +++--- .../ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json | 6 +++--- ...bi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json | 6 +++--- .../ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json | 6 +++--- sbom/examples/container_image/release/from_catalog.py | 8 +++++--- ...odule-management-operator-container-1.1.2-25.spdx.json | 6 +++--- ...management-operator-container-1.1.2-25_amd64.spdx.json | 6 +++--- ...management-operator-container-1.1.2-25_arm64.spdx.json | 6 +++--- ...nagement-operator-container-1.1.2-25_ppc64le.spdx.json | 6 +++--- .../ubi9-micro-container-9.4-6.1716471860.spdx.json | 6 +++--- .../ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json | 6 +++--- .../ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json | 6 +++--- ...bi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json | 6 +++--- .../ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json | 6 +++--- sbom/examples/product/rhel-9.2-eus.spdx.json | 8 ++++---- sbom/examples/rpm/build/from-koji.py | 8 +++++--- .../openshift-pipelines-client-1.14.3-11352.el8.spdx.json | 6 +++--- sbom/examples/rpm/build/openssl-3.0.7-18.el9_2.spdx.json | 4 ++-- sbom/examples/rpm/build/poppler-21.01.0-19.el9.spdx.json | 6 +++--- sbom/examples/rpm/release/add_release_data.py | 4 +++- .../openshift-pipelines-client-1.14.3-11352.el8.spdx.json | 6 +++--- .../examples/rpm/release/openssl-3.0.7-18.el9_2.spdx.json | 6 +++--- .../examples/rpm/release/poppler-21.01.0-19.el9.spdx.json | 6 +++--- 29 files changed, 91 insertions(+), 83 deletions(-) diff --git a/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25.spdx.json b/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25.spdx.json index 03a1918..7cbd3e7 100644 --- a/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25.spdx.json +++ b/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -118,4 +118,4 @@ "relatedSpdxElement": "SPDXRef-image-index" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_amd64.spdx.json b/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_amd64.spdx.json index 422c2c9..59ba1b3 100644 --- a/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_amd64.spdx.json +++ b/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_amd64.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -4900,4 +4900,4 @@ "relatedSpdxElement": "SPDXRef-x86_64-zlib" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_arm64.spdx.json b/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_arm64.spdx.json index 4dedecc..676175a 100644 --- a/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_arm64.spdx.json +++ b/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_arm64.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -4900,4 +4900,4 @@ "relatedSpdxElement": "SPDXRef-aarch64-zlib" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_ppc64le.spdx.json b/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_ppc64le.spdx.json index f505a8d..09b2db2 100644 --- a/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_ppc64le.spdx.json +++ b/sbom/examples/container_image/build/kernel-module-management-operator-container-1.1.2-25_ppc64le.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -4900,4 +4900,4 @@ "relatedSpdxElement": "SPDXRef-ppc64le-zlib" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/build/remove_release_data.py b/sbom/examples/container_image/build/remove_release_data.py index cb27f3f..cd47cba 100644 --- a/sbom/examples/container_image/build/remove_release_data.py +++ b/sbom/examples/container_image/build/remove_release_data.py @@ -21,4 +21,6 @@ with open(f"{sbom_name}.spdx.json", "w") as fp: - json.dump(sbom, fp, indent=2) + # Add an extra newline at the end since a lot of editors add one when you save a file, + # and these files get opened and read in editors a lot. + fp.write(json.dumps(sbom, indent=2) + "\n") diff --git a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860.spdx.json b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860.spdx.json index f6b7d8b..500b889 100644 --- a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860.spdx.json +++ b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -169,4 +169,4 @@ "relatedSpdxElement": "SPDXRef-image-index" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json index 9c863e4..eccfbed 100644 --- a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json +++ b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -585,4 +585,4 @@ "relatedSpdxElement": "SPDXRef-noarch-tzdata" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json index 2ccef85..8aa07bd 100644 --- a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json +++ b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -585,4 +585,4 @@ "relatedSpdxElement": "SPDXRef-noarch-tzdata" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json index 5cb1ad0..4ba99a1 100644 --- a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json +++ b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -585,4 +585,4 @@ "relatedSpdxElement": "SPDXRef-noarch-tzdata" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json index 3530283..4f3d611 100644 --- a/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json +++ b/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -585,4 +585,4 @@ "relatedSpdxElement": "SPDXRef-noarch-tzdata" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/from_catalog.py b/sbom/examples/container_image/release/from_catalog.py index 0517311..5d8a15e 100644 --- a/sbom/examples/container_image/release/from_catalog.py +++ b/sbom/examples/container_image/release/from_catalog.py @@ -55,10 +55,10 @@ def create_sbom(image_id, root_package, packages, rel_type): spdx = { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only", ], @@ -70,7 +70,9 @@ def create_sbom(image_id, root_package, packages, rel_type): } with open(f"{image_id}.spdx.json", "w") as fp: - json.dump(spdx, fp, indent=2) + # Add an extra newline at the end since a lot of editors add one when you save a file, + # and these files get opened and read in editors a lot. + fp.write(json.dumps(spdx, indent=2) + "\n") def generate_sboms_for_image(image_nvr): diff --git a/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25.spdx.json b/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25.spdx.json index e3db759..a2d1382 100644 --- a/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25.spdx.json +++ b/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -118,4 +118,4 @@ "relatedSpdxElement": "SPDXRef-image-index" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_amd64.spdx.json b/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_amd64.spdx.json index 21b6623..db4c3d2 100644 --- a/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_amd64.spdx.json +++ b/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_amd64.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -4900,4 +4900,4 @@ "relatedSpdxElement": "SPDXRef-x86_64-zlib" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_arm64.spdx.json b/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_arm64.spdx.json index f581f89..fa1def6 100644 --- a/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_arm64.spdx.json +++ b/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_arm64.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -4900,4 +4900,4 @@ "relatedSpdxElement": "SPDXRef-aarch64-zlib" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_ppc64le.spdx.json b/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_ppc64le.spdx.json index 33eed64..b22fbeb 100644 --- a/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_ppc64le.spdx.json +++ b/sbom/examples/container_image/release/kernel-module-management-operator-container-1.1.2-25_ppc64le.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -4900,4 +4900,4 @@ "relatedSpdxElement": "SPDXRef-ppc64le-zlib" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860.spdx.json b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860.spdx.json index b506245..0af94d8 100644 --- a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860.spdx.json +++ b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -169,4 +169,4 @@ "relatedSpdxElement": "SPDXRef-image-index" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json index 687712f..cc16687 100644 --- a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json +++ b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -585,4 +585,4 @@ "relatedSpdxElement": "SPDXRef-noarch-tzdata" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json index 2d9fc42..178d2b6 100644 --- a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json +++ b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_arm64.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -585,4 +585,4 @@ "relatedSpdxElement": "SPDXRef-noarch-tzdata" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json index c91b099..3fb551a 100644 --- a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json +++ b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_ppc64le.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -585,4 +585,4 @@ "relatedSpdxElement": "SPDXRef-noarch-tzdata" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json index e40936f..0ce6df1 100644 --- a/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json +++ b/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_s390x.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -585,4 +585,4 @@ "relatedSpdxElement": "SPDXRef-noarch-tzdata" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/product/rhel-9.2-eus.spdx.json b/sbom/examples/product/rhel-9.2-eus.spdx.json index 8c461fb..908273c 100644 --- a/sbom/examples/product/rhel-9.2-eus.spdx.json +++ b/sbom/examples/product/rhel-9.2-eus.spdx.json @@ -1,22 +1,22 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] }, "name": "RHEL 9.2 EUS", - "documentNamespace": "https://www.redhat.com/rhel-9.2-eus-6a659023-7a52-4792-a66c-a7f19ec14ba8.spdx.json", + "documentNamespace": "https://www.redhat.com/rhel-9.2-eus.spdx.json", "packages": [ { "SPDXID": "SPDXRef-RHEL-9.2-EUS", "name": "Red Hat Enterprise Linux", "versionInfo": "9.2 EUS", "supplier": "Organization: Red Hat", - "downloadLocation": "https://developers.redhat.com/products/rhel/download", + "downloadLocation": "NOASSERTION", "licenseConcluded": "NOASSERTION", "externalRefs": [ { diff --git a/sbom/examples/rpm/build/from-koji.py b/sbom/examples/rpm/build/from-koji.py index 9a30018..7ccd4ad 100644 --- a/sbom/examples/rpm/build/from-koji.py +++ b/sbom/examples/rpm/build/from-koji.py @@ -381,10 +381,10 @@ def handle_srpm(filename, name): spdx = { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only", ], @@ -397,4 +397,6 @@ def handle_srpm(filename, name): } with open(f"{build_id}.spdx.json", "w") as fp: - json.dump(spdx, fp, indent=2) + # Add an extra newline at the end since a lot of editors add one when you save a file, + # and these files get opened and read in editors a lot. + fp.write(json.dumps(spdx, indent=2) + "\n") diff --git a/sbom/examples/rpm/build/openshift-pipelines-client-1.14.3-11352.el8.spdx.json b/sbom/examples/rpm/build/openshift-pipelines-client-1.14.3-11352.el8.spdx.json index e7d03d2..31f7b1a 100644 --- a/sbom/examples/rpm/build/openshift-pipelines-client-1.14.3-11352.el8.spdx.json +++ b/sbom/examples/rpm/build/openshift-pipelines-client-1.14.3-11352.el8.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -29980,4 +29980,4 @@ "relatedSpdxElement": "SPDXRef-SRPM" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/rpm/build/openssl-3.0.7-18.el9_2.spdx.json b/sbom/examples/rpm/build/openssl-3.0.7-18.el9_2.spdx.json index 7675f6a..2e57478 100644 --- a/sbom/examples/rpm/build/openssl-3.0.7-18.el9_2.spdx.json +++ b/sbom/examples/rpm/build/openssl-3.0.7-18.el9_2.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] diff --git a/sbom/examples/rpm/build/poppler-21.01.0-19.el9.spdx.json b/sbom/examples/rpm/build/poppler-21.01.0-19.el9.spdx.json index 0f3b15b..40391db 100644 --- a/sbom/examples/rpm/build/poppler-21.01.0-19.el9.spdx.json +++ b/sbom/examples/rpm/build/poppler-21.01.0-19.el9.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -2753,4 +2753,4 @@ "relatedSpdxElement": "SPDXRef-SRPM" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/rpm/release/add_release_data.py b/sbom/examples/rpm/release/add_release_data.py index c7f1d3f..a265e13 100644 --- a/sbom/examples/rpm/release/add_release_data.py +++ b/sbom/examples/rpm/release/add_release_data.py @@ -83,4 +83,6 @@ def get_rpm_purl(ext_refs): pkg["externalRefs"] = sorted(new_refs, key=lambda ref: ref["referenceLocator"]) with open(f"{sbom_name}.spdx.json", "w") as fp: - json.dump(sbom, fp, indent=2) + # Add an extra newline at the end since a lot of editors add one when you save a file, + # and these files get opened and read in editors a lot. + fp.write(json.dumps(sbom, indent=2) + "\n") diff --git a/sbom/examples/rpm/release/openshift-pipelines-client-1.14.3-11352.el8.spdx.json b/sbom/examples/rpm/release/openshift-pipelines-client-1.14.3-11352.el8.spdx.json index 0105371..7968036 100644 --- a/sbom/examples/rpm/release/openshift-pipelines-client-1.14.3-11352.el8.spdx.json +++ b/sbom/examples/rpm/release/openshift-pipelines-client-1.14.3-11352.el8.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -29995,4 +29995,4 @@ "relatedSpdxElement": "SPDXRef-SRPM" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/rpm/release/openssl-3.0.7-18.el9_2.spdx.json b/sbom/examples/rpm/release/openssl-3.0.7-18.el9_2.spdx.json index 7a59565..9d1a908 100644 --- a/sbom/examples/rpm/release/openssl-3.0.7-18.el9_2.spdx.json +++ b/sbom/examples/rpm/release/openssl-3.0.7-18.el9_2.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -1745,4 +1745,4 @@ "relatedSpdxElement": "SPDXRef-SRPM" } ] -} \ No newline at end of file +} diff --git a/sbom/examples/rpm/release/poppler-21.01.0-19.el9.spdx.json b/sbom/examples/rpm/release/poppler-21.01.0-19.el9.spdx.json index 417e2bb..e98b5bb 100644 --- a/sbom/examples/rpm/release/poppler-21.01.0-19.el9.spdx.json +++ b/sbom/examples/rpm/release/poppler-21.01.0-19.el9.spdx.json @@ -1,9 +1,9 @@ { "spdxVersion": "SPDX-2.3", - "dataLicense": "CC0-1.0", + "dataLicense": "CC-BY-4.0", "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { - "created": "2006-08-14T02:34:56-06:00", + "created": "2006-08-14T02:34:56Z", "creators": [ "Tool: example SPDX document only" ] @@ -4008,4 +4008,4 @@ "relatedSpdxElement": "SPDXRef-SRPM" } ] -} \ No newline at end of file +} From 6b95bd98d83b4aa2f84bfd726967ffc7a42f1c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Prpi=C4=8D?= Date: Mon, 26 Aug 2024 21:14:27 -0400 Subject: [PATCH 3/3] Add Red Hat SBOM guidelines --- docs/sbom.md | 601 ++++++++++++++++++ mkdocs.yml | 1 + .../container_image/release/from_catalog.py | 2 - 3 files changed, 602 insertions(+), 2 deletions(-) create mode 100644 docs/sbom.md diff --git a/docs/sbom.md b/docs/sbom.md new file mode 100644 index 0000000..1492d06 --- /dev/null +++ b/docs/sbom.md @@ -0,0 +1,601 @@ +# Understanding SBOMs + +A Software Bill of Materials (SBOM) is at its core a listing of software components for a given deliverable. That +deliverable may be a single RPM package, a container image, or an entire product version. There are several use +cases where SBOMs are beneficial: + +- in-depth review of the composition of a particular product for procurement or audit purposes, + +- accurate vulnerability risk assessment when combined with VEX data, + +- or faster incident response when aggregating SBOMs for an entire product portfolio. + +When talking about inventories of components, it's also important to describe what the current design goals of a +comprehensive SBOM are: + +- Provide a complete and accurate listing of software components and their relationships to each other from a + supply chain perspective. + +- Define an accurate identification of components and products usable across all published security data. + +It's also important to cover the qualities of an SBOM that are currently out of scope: + +- Provide a component dependency graph: providing dependency relationships between components as part of an + application or an operating system is currently out of scope. This type of information is varied between different + ecosystems, and it would be difficult to express it correctly in product-level SBOMs. + The relationships currently represented are limited to more direct dependencies, such as those between a container + image and the packages it includes, an operating system and its constituent packages, or a package and its + upstream counterpart. We do not include application-level dependencies, like those where a Python package such as + [`requests`](https://pypi.org/project/requests/) depends on another package like + [`certifi`](https://pypi.org/project/certifi/). + +- Inclusion of complete listings of individual files for each component: for each listed component in an SBOM, it is + assumed that the user can fetch it from its indicated location, and inspect the component itself to list out its + files. For example, when downloading a source RPM, the downloaded archive can be unpacked and inspected to acquire + a list of files contained in it. + +## Formats + +The two most widely used SBOM formats are [SPDX](https://spdx.dev/) and +[CycloneDX](https://cyclonedx.org/). Both offer similar features and data fields, and can be used to represent +complex inventories of components, their metadata (such as provenance or licensing), and additional document properties. + +Most of this document focuses on Red Hat's use of SPDX 2.3 in its published SBOMs. In the future, we may add similar +guidelines for CycloneDX and SPDX 3.0. + +## Types + +Depending on how an SBOM is generated, it will contain varying levels of information. The sections below highlight +different viewpoints of when an SBOM is created and what type of data it includes. + +### Build vs Release + +_Build-time_ SBOMs are created during the initial build process of an artifact (for example, when an RPM is created +from source files or a container image is built using [`buildah`](https://buildah.io/)). These SBOMs document the +components used during the build process to produce the final artifact as well as any components used for the build +process itself. This SBOM type also aligns with the _Build_ SBOM type from CISA's guidance on +[Types of SBOM Documents](https://www.cisa.gov/sites/default/files/2023-04/sbom-types-document-508c.pdf). + +_Release-time_ SBOMs are generated when an artifact is released or published. These SBOMs build upon build-time +SBOMs by incorporating additional metadata, such as the repositories or locations where the artifact is +published, and associating it with the relevant product information if there is any. Release-time SBOMs reflect the +state of the software as it is distributed to end users. This SBOM type is close to the _Deployed_ type as defined +by CISA, but it reflects the state of the product that _would_ be installed by a given end user. + +Red Hat's publicly available SBOMs are of the "release-time" type, including details about where an artifact +can be located after being released. + +**Example**: + +- Build-time SBOM of the `ubi9-micro` container image along with all of its installed components (RPMs): + [build/ubi9-micro-container-9.4-6.1716471860_amd64](https://github.com/RedHatProductSecurity/security-data-guidelines/blob/main/sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json) +- Release-time SBOM of the same `ubi9-micro` container image: + [release/ubi9-micro-container-9.4-6.1716471860_amd64](https://github.com/RedHatProductSecurity/security-data-guidelines/blob/main/sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json) + +The difference between these two SBOMs is relatively minor; the release-time SBOM contains information on where the +container image (identified by two distinct purls) itself is available from: + +```diff +--- sbom/examples/container_image/build/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json ++++ sbom/examples/container_image/release/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json +@@ -22,12 +22,12 @@ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", +- "referenceLocator": "pkg:oci/ubi-micro@sha256%3A1c84[...]?arch=amd64" ++ "referenceLocator": "pkg:oci/ubi-micro@sha256%3A1c84[...]?arch=amd64&repository_url=registry.access.redhat.com/ubi9/ubi-micro&tag=9.4-6.1716471860" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", +- "referenceLocator": "pkg:oci/ubi9-micro@sha256%3A1c84[...]?arch=amd64" ++ "referenceLocator": "pkg:oci/ubi9-micro@sha256%3A1c84[...]?arch=amd64&repository_url=registry.access.redhat.com/ubi9-micro&tag=9.4-6.1716471860" + } + ], +``` + +### Component-Level vs Product-Level + +_Component-level_ SBOMs describe individual components, such as a single RPM package or a container +image. They document the full listing of individual components, libraries, and other relevant +software that went into building that component. Component-level SBOMs also include provenance metadata for certain +components. For example, a component-level SBOM of an RPM will point to the upstream sources that that RPM is based on. + +_Product-level_ SBOMs describe an entire product and the subset of its components that were built and included in +the final product. A product-level SBOM may cover one or more component-level SBOMs, providing a way to connect each +release component to its parent product. + +**Example**: + +- Component-level SBOM of the `openssl-3.0.7-18.el9_2` RPM package: + [release/openssl-3.0.7-18.el9_2](https://github.com/RedHatProductSecurity/security-data-guidelines/blob/main/sbom/examples/rpm/release/openssl-3.0.7-18.el9_2.spdx.json) + +- Product-level SBOM of the `openssl-3.0.7-18.el9_2` RPM package as included in RHEL 9.2 EUS repositories: + [product/rhel-9.2-eus](https://github.com/RedHatProductSecurity/security-data-guidelines/blob/main/sbom/examples/product/rhel-9.2-eus.spdx.json) + +Note that the root package described by the component-level SBOM, the OpenSSL Source RPM (SRPM), is the only +reference present in the product-level SBOM to not duplicate information between the two SBOMs. The purl +reference from the SRPM package can be used to discover the component-level SBOM from the product-level SBOM. + +### Shallow vs Complete + +_Shallow_ SBOMs describe only the current layer of components that were used to build a specific artifact. They +focus on the immediate components without necessarily documenting their origins. The benefit of this approach is +smaller SBOM files, and the ability to make incremental changes in select SBOMs while others remain unchanged when +composing multiple SBOMs into a larger set (to describe a product, for example). + +_Complete_ SBOMs provide a full, in-depth representation of all levels of the build process in a single file. A +Complete SBOM includes all component layers and their dependencies, offering a complete view of a product's composition. +These types of SBOMs are mostly used for procurement and audit purposes. + +Red Hat aims to publish Complete SBOMs at +[https://security.access.redhat.com/data/sbom/](https://security.access.redhat.com/data/sbom/) while Shallow SBOMs +may be published for individual components such as container images. + +## Document Structure + +The following snippet shows a minimal SBOM document: + +=== "SPDX 2.3" + + ```json + { + "spdxVersion": "SPDX-2.3",// (1)! + "dataLicense": "CC-BY-4.0",// (2)! + "SPDXID": "SPDXRef-DOCUMENT",// (3)! + "creationInfo": { + "created": "2006-08-14T02:34:56Z", + "creators": [ + "Tool: example SPDX document only" + ] + }, + "name": "ubi9-micro-container-9.4-6.1716471860_amd64", + "documentNamespace": "https://www.redhat.com/ubi9-micro-container-9.4-6.1716471860_amd64.spdx.json", + "packages": [...], + "files": [], + "relationships": [...] + } + ``` + + 1. SPDX version 2.3 as described at [https://spdx.github.io/spdx-spec/v2.3/](https://spdx.github.io/spdx-spec/v2.3/). + + 2. All Red Hat security data is published under the + [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/). + + 3. [`SPDXID`](https://spdx.github.io/spdx-spec/v2.3/document-creation-information/#63-spdx-identifier-field) + must be set to `SPDXRef-DOCUMENT`. + +A more detailed breakdown of some of the fields: + +`creationInfo` +: This field must contain at least the + [`created`](https://spdx.github.io/spdx-spec/v2.3/document-creation-information/#68-creator-field) and + [`creators`](https://spdx.github.io/spdx-spec/v2.3/document-creation-information/#69-created-field) + fields. The timestamp in the `created` field must be set to an ISO 8601-formatted date and time string using + the UTC timezone. The `creators` field must identify the tool and its version that was used to generate the SBOM + file (for example, `Tool: SBOMer 1.2.3` or even `Tool: pkg:github/project-ncl/sbomer@1.0.0.M3`). + Optionally, the organization responsible for generating the SBOM can be included in a separate string + (for example, `Organization: Red Hat Product Security (secalert@redhat.com)`). + +[`name`](https://spdx.github.io/spdx-spec/v2.3/document-creation-information/#64-document-name-field) +: This is an arbitrary value that should describe the main artifact described by the SBOM document. This can be a + product, a container image, or a specific package. The name should contain a descriptive value for that given + artifact along with a version identifier. This field should only serve as a human-readable value and be shown in + user interfaces for informational purposes. The metadata of the main package (the one _DESCRIBED_ by + the SBOM document) should be used for any automation purposes. Note also that the `name` value may not be unique + to a single SBOM document. + +[`documentNamespace`](https://spdx.github.io/spdx-spec/v2.3/document-creation-information/#65-spdx-document-namespace-field) +: This field uniquely identifies the SPDX SBOM document and must be a valid URI, even though that URI does not + have to be accessible. Red Hat SBOMs can use one of two possible values: + + - A URI that is namespaced to a generic Red Hat location: `https://www.redhat.com/[DocumentID].spdx.json`. + This URI is not accessible and only serves the purpose of identifying the document to its namespace (here, + Red Hat). + + - A URI that is namespaced to `access.redhat.com/security/data`: + `https://security.access.redhat.com/data/sbom/spdx/[DocumentID].spdx.json`. This URI is assumed to be accessible + and the identified SBOM can be downloaded from the specified location. + + The `documentNamespace` value has no direct relationship to the `name` value. + +The `packages` and `relationships` fields are described in depth in the sections below for each respective software +content type. The `files` field is currently unused and will thus either not be present at all, or set to an empty +list. All software components in an SBOM are described as packages; all files are assumed to be a part of _some_ +package and should thus not be listed on their own in the `files` field. + +### Packages and Relationships + +The purpose of listing out all components as separate package objects ensures we can define meaningful relationships +between them. Some packages may for example embed other software components, and other packages may be used only +during the build process of creating a set of packages. Differentiating between these different types of components +allows us to narrow down the scope of responding to vulnerabilities to only the components that are truly affected +by a given vulnerability. + +The following example shows the structure of a package object for a specific component: + +=== "SPDX 2.3" + + ```json + { + "SPDXID": "SPDXRef-[UUID]",// (1)! + "name": "ubi9-micro-container", + "versionInfo": "9.4-6.1716471860", + "supplier": "Organization: Red Hat",// (2)! + "downloadLocation": "NOASSERTION", + "licenseConcluded": "NOASSERTION", + "externalRefs": [...], + "checksums": [...] + } + ``` + + 1. A unique identifier of a given component within this document. This value should only be used to associate + relationships to other components described in an SBOM via their relationships. + + 2. The value `Organization: Red Hat` must be used for all components that are distributed by Red Hat. + +A more detailed breakdown of some of the fields: + +[`name`](https://spdx.github.io/spdx-spec/v2.3/package-information/#71-package-name-field) +: The name of the component. This value may differ for different types of package ecosystems. It is recommended to + use the `name` field of the associated purl string for consistent results. + +[`versionInfo`](https://spdx.github.io/spdx-spec/v2.3/package-information/#73-package-version-field) +: The version of the component. This value may differ for different types of package ecosystems. It is + recommended to use the `version` field of the associated purl string for consistent results. + +[`downloadLocation`](https://spdx.github.io/spdx-spec/v2.3/package-information/#77-package-download-location-field) +: This field is used to point to the VCS that holds the related source code for this component. In most cases, + this field will be set to `NOASSERTION` because the upstream equivalent of a downstream component is represented + with its own package object. + +[`licenseConcluded`](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) +: The concluded license of the package, based on the information available during the build. If during the build, + this information cannot be determined, the value `NOASSERTION` should be used. + +[`externalRefs`](https://spdx.github.io/spdx-spec/v2.3/package-information/#722-external-reference-comment-field) +: At least one of the references must include a Package URL (purl) unless the object is describing a product. + [Identifying Red Hat components using Package URL](./purl.md) documents what purl strings for different types of + components should look like. Note that multiple purls may be used for a single package to identify multiple + locations from where the package can be accessed. + +[`checksums`](https://spdx.github.io/spdx-spec/v2.3/package-information/#710-package-checksum-field) +: The checksums of the component. The type of checksum used will depend on the type of the component. See below + sections for more information. + + +#### Container Image + +A container image can be represented by a package object using the following data: + +=== "SPDX 2.3" + + ```json + { + "SPDXID": "SPDXRef-image-index", + "name": "ubi9-micro-container",// (1)! + "versionInfo": "9.4-6.1716471860", + "supplier": "Organization: Red Hat", + "downloadLocation": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:oci/ubi-micro@sha256%3A1c8483e0fda0e990175eb9855a5f15e0910d2038dd397d9e2b357630f0321e6d?repository_url=registry.access.redhat.com/ubi9&tag=9.4-6.1716471860" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:oci/ubi9-micro@sha256%3A1c8483e0fda0e990175eb9855a5f15e0910d2038dd397d9e2b357630f0321e6d?repository_url=registry.access.redhat.com&tag=9.4-6.1716471860" + } + ], + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "1c8483e0fda0e990175eb9855a5f15e0910d2038dd397d9e2b357630f0321e6d" + } + ], + } + ``` + + 1. The name does not necessarily have to reflect what the container image is named in the container registry; + the name component of the associated purl identifier should be used instead. + +[`checksums`](https://spdx.github.io/spdx-spec/v2.3/package-information/#710-package-checksum-field) +: The checksum value for a container image refers to the image digest value as defined in the + [OCI Image Format](https://github.com/opencontainers/image-spec/blob/v1.0.1/descriptor.md#digests). + +purl identifiers +: A container image may have one or more purls, depending on whether the same image is available in different + registries, or different repositories within the same registry. Note that if multiple purls are present, + they should only ever differ in their qualifier values, not the main components such as package type, name, or + version; multiple package objects should be used if those values differ. + +license information +: Licensing information should in most cases be set to `NOASSERTION` since licensing is set on the software + components provided by the container image, and not the image itself. + +[`downloadLocation`](https://spdx.github.io/spdx-spec/v2.3/package-information/#77-package-download-location-field) +: The `downloadlocation` will never be set; container images don't have their own VCS repos. The location from + where the image itself can be downloaded can be acquired from the purl identifier. + +An SBOM should contain representation of both an +[Image Index](https://github.com/opencontainers/image-spec/blob/main/image-index.md) and an architecture-specific +image itself. The following is an example of an SPDX relationship between the two: + +=== "SPDX 2.3" + + ```json + { + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relationshipType": "DESCRIBES", + "relatedSpdxElement": "SPDXRef-image-index" + }, + { + "spdxElementId": "SPDXRef-ubi9-micro-container-ppc64le", + "relationshipType": "VARIANT_OF", + "relatedSpdxElement": "SPDXRef-image-index" + } + ] + } + ``` + +An SBOM that represent a container image must also list out all the components included in that image, and create +relationships to the architecture-specific image that they are included in: + +=== "SPDX 2.3" + + ```json + { + "spdxElementId": "SPDXRef-ubi9-micro-container-amd64", + "relationshipType": "CONTAINS", + "relatedSpdxElement": "SPDXRef-x86_64-bash" + } + ``` + +A container image SBOM must also list its parent container image and any container images that were used in the +process of building the container image (that is, used in a multi-stage build). As an example, consider the following +Dockerfile used to create an image (`example-container`) by building the `foo` and `bar` dependencies using separate +images: + +```Dockerfile +# Dockerfile of example-container +FROM img-a AS stage1 +RUN make foo + +FROM img-b AS stage2 +RUN make bar + +FROM ubi9 +COPY --from=stage1 /work/foo /foo +COPY --from=stage2 /work/bar /bar +``` + +The relationship of `example-container` image to the two container images (`stage1` and `stage2`) that were used to +build `foo` and `bar` so they can be added to the final layers can be represented as: + +=== "SPDX 2.3" + + ```json + { + "spdxElementId": "SPDXRef-stage1-amd64", + "relationshipType": "BUILD_TOOL_OF", + "relatedSpdxElement": "SPDXRef-example-container-container-amd64" + }, + { + "spdxElementId": "SPDXRef-stage2-amd64", + "relationshipType": "BUILD_TOOL_OF", + "relatedSpdxElement": "SPDXRef-example-container-container-amd64" + } + ``` + +The parent image of `example-container` is `ubi9`. Its relationship to `example-container` can be represented as: + +=== "SPDX 2.3" + + ```json + { + "spdxElementId": "SPDXRef-example-container-amd64", + "relationshipType": "DESCENDANT_OF", + "relatedSpdxElement": "SPDXRef-ubi9-amd64" + } + ``` + + + +#### RPM + +An architecture-specific RPM built by Red Hat can be represented by a package object using the following data: + +=== "SPDX 2.3" + + ```json + { + "SPDXID": "SPDXRef-aarch64-openssl-libs", + "name": "openssl-libs", + "versionInfo": "3.0.7-18.el9_2", + "supplier": "Organization: Red Hat", + "downloadLocation": "NOASSERTION", + "packageFileName": "openssl-libs-3.0.7-18.el9_2.aarch64.rpm", + "licenseConcluded": "Apache-2.0", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:rpm/redhat/openssl-libs@3.0.7-18.el9_2?arch=aarch64&repository_id=rhel-9-for-aarch64-baseos-eus-rpms" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:rpm/redhat/openssl-libs@3.0.7-18.el9_2?arch=aarch64&repository_id=rhel-9-for-aarch64-baseos-aus-rpms" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:rpm/redhat/openssl-libs@3.0.7-18.el9_2?arch=aarch64&repository_id=rhel-9-for-aarch64-baseos-e4s-rpms" + } + ], + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "cae5941219fd64e75c2b29509c6fe712bef77181a586702275a46a5e812d4dd4" + } + ], + "annotations": [ + { + "annotationType": "OTHER", + "annotator": "Tool: example SPDX document only", + "annotationDate": "2006-08-14T02:34:56Z", + "comment": "sigmd5: 4cc665dd3173c8952184293588f9ee46" + } + ] + } + ``` + +[`downloadLocation`](https://spdx.github.io/spdx-spec/v2.3/package-information/#77-package-download-location-field) +: The `downloadlocation` will never be set; container images don't have their own VCS repos. The location from + where the image itself can be downloaded can be acquired from the purl identifier. + +purl identifiers +: A single RPM package may be available from multiple DNF/Yum repositories, in which case it will include a purl + identifier for each repository it can be downloaded from. Note that if multiple purls are present, + they should only ever differ in their qualifier values, not the main components such as package type, name, or + version; multiple package objects should be used if those values differ. + +[`annotations`](https://spdx.github.io/spdx-spec/v2.3/annotations/) +: A list of annotations may provide additional information that is specific to the RPM format. In the example + above, the MD5 checksum the signed header of the RPM package is included. + +Each set of architecture-specific RPMs also have an associated source RPM that bundles all the source code that was +used to build those RPMs. SRPMs should be represented as a separate package object in an SBOM, and their relationship +to architecture-specific RPMs can be represented with: + +=== "SPDX 2.3" + + ```json + { + "spdxElementId": "SPDXRef-ppc64le-openssl-libs", + "relationshipType": "GENERATED_FROM", + "relatedSpdxElement": "SPDXRef-SRPM" + } + ``` + +SRPMs are also linked to one or more upstream sources that were used to build the downstream RPMs. An upstream + +Upstream source: + +=== "SPDX 2.3" + + ```json + { + "SPDXID": "SPDXRef-Source0-origin", + "name": "openssl", + "versionInfo": "3.0.7", + "downloadLocation": "https://openssl.org/source/openssl-3.0.7.tar.gz", + "homepage": "https://openssl-library.org/", + "packageFileName": "openssl-3.0.7.tar.gz", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "83049d042a260e696f62406ac5c08bf706fd84383f945cf21bd61e9ed95c396e" + } + ], + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:generic/openssl@3.0.7?download_url=https://openssl.org/source/openssl-3.0.7.tar.gz&checksum=sha256:83049d042a260e696f62406ac5c08bf706fd84383f945cf21bd61e9ed95c396e" + } + ] + } + ``` + +purl identifiers +: In cases where the upstream source is a package in a registry such as PyPI or NPM, the purl identifier will use + the respective package type. For components that are distributed as standalone bundles (such as OpenSSL in the + example above), `generic` purls should be used with an exact download URL from where a specific bundle of source + code was fetched from, including a checksum (which should also be specified in the `checksums` field). + +Note that provenance metadata may not be available for all components. + +To associate a set of source archives with the SRPM that includes them, use: + +=== "SPDX 2.3" + + ```json + { + "spdxElementId": "SPDXRef-SRPM", + "relationshipType": "CONTAINS", + "relatedSpdxElement": "SPDXRef-Source0" + } + ``` + +#### Product + +Individual components such as packages and container images are almost always provided as part of a specific product. +Products represent a bundle of components that can be purchased, has a life cycle +([example](https://access.redhat.com/support/policy/updates/errata#RHEL8_and_9_Life_Cycle)) defined for it, and +a support policy. + +If one or more components described in a given SBOM are being provided as part of a product, that product should +be represented with its own package object: + +=== "SPDX 2.3" + + ```json + { + "SPDXID": "SPDXRef-RHEL-9.2-EUS", + "name": "Red Hat Enterprise Linux", + "versionInfo": "9.2 EUS", + "supplier": "Organization: Red Hat", + "downloadLocation": "NOASSERTION",// (1)! + "licenseConcluded": "NOASSERTION",// (2)! + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceLocator": "cpe:/a:redhat:rhel_eus:9.2::baseos", + "referenceType": "cpe22Type" + } + ] + } + ``` + + 1. Not used because this product component is not specific enough to an architecture or ISO variant (for example, + workstation vs server) for there to be an exact download location. + + 2. Not set, only components have licenses. + +`name` +: This field must contain a human-readable name of the product. + +`versionInfo` +: This field must contain the most granular version of the product, for which the SBOM was generated. + +`externalRefs` +: External references must contain a unique identifier of the product. Red Hat uses CPE IDs to identify products. + A given product may have one or more of these identifiers, covering all possible variants of a single product + version. + +A relationship between a component and the product it is a part of can be represented as: + +=== "SPDX 2.3" + + ```json + { + "spdxElementId": "SPDXRef-SRPM-1", + "relationshipType": "PACKAGE_OF", + "relatedSpdxElement": "SPDXRef-RHEL-9.2-EUS" + } + ``` + +## Additional Notes + +The guidelines highlighted in this document represent an ideal state across all of Red Hat-published security data +that we want to achieve in the long term. In some SBOMs, components may be missing their provenance data or their +license expressions may not be accurate. Please +[contact Red Hat Product Security](https://access.redhat.com/security/team/contact/) or file a Jira issue in the +[SECDATA project](https://issues.redhat.com/projects/SECDATA) if you find any discrepancies in Red Hat's security data. +Feedback on our SBOM design and publishing is always welcome and appreciated. diff --git a/mkdocs.yml b/mkdocs.yml index d8e68c8..62ddd43 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -36,6 +36,7 @@ theme: nav: - Home: "index.md" + - SBOM: "sbom.md" - purl: "purl.md" plugins: diff --git a/sbom/examples/container_image/release/from_catalog.py b/sbom/examples/container_image/release/from_catalog.py index 5d8a15e..93738fd 100644 --- a/sbom/examples/container_image/release/from_catalog.py +++ b/sbom/examples/container_image/release/from_catalog.py @@ -14,8 +14,6 @@ nvr_api = catalog_url + "images/nvr/" rpm_manifest_api = catalog_url + "images/id/{catalog_image_id}/rpm-manifest" -rpm_sbom_url = "https://access.redhat.com/security/data/sbom/v1/rpm/" - def get_image_data(image_nvr): response = requests.get(nvr_api + image_nvr)