Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sbom dependency relationship transparency. ref: QSP-15724 #4424

Conversation

barblin
Copy link
Contributor

@barblin barblin commented Feb 6, 2025

Description

This change will fix the flat hierarchy of the current dependency relationships.

The change includes:

How can this be tested?

  • You can build the image locally. For example: ./hack/build/build_image.sh "dynatrace-operator" "0.0.6-jpr" "true"
  • Then execute trivy, same as the github action would: trivy image --skip-dirs /usr/share/dynatrace-operator/third_party_licenses --skip-files /usr/local/bin/dynatrace-operator --format cyclonedx -o result.json dynatrace-operator:0.0.6-jpr
  • You can check the result.json file

If you want to check the sbom that was added to the image, you can do the following:

  • Create container: docker create dynatrace-operator:0.0.6-jpr
  • Export file system: docker cp <CONTAINER_ID>:/usr/local/bin /tmp/dynatrace-operator
  • /tmp/dynatrace-operator should now contain the SBOM for the dynatrace-operator binary

@barblin
Copy link
Contributor Author

barblin commented Feb 6, 2025

This change will fix the flat hierarchy of the current dependency relationships.

The change includes:

@barblin barblin force-pushed the feat/QSP-15724/sbom-dependency-relationship-transparency branch from 0862522 to b04cf83 Compare February 6, 2025 15:32
Dockerfile Outdated Show resolved Hide resolved
@0sewa0
Copy link
Contributor

0sewa0 commented Feb 6, 2025

@barblin could you fill out the PR description? 🙏

I found your comment (after a short period of confusion caused by the missing description) but I am still missing the "How to test" part.

  • Unfortunately, I have no idea what to look for or verify when it comes to the changes 😬 (+ I just want understand it more 😇)

@barblin barblin force-pushed the feat/QSP-15724/sbom-dependency-relationship-transparency branch from b04cf83 to 1dc59d2 Compare February 6, 2025 17:15
@barblin barblin requested a review from 0sewa0 February 6, 2025 17:15
@barblin barblin changed the title feat: sbom dependency relationship transparency. ref: QSP-15728 feat: sbom dependency relationship transparency. ref: QSP-15724 Feb 6, 2025
@barblin barblin force-pushed the feat/QSP-15724/sbom-dependency-relationship-transparency branch from 1dc59d2 to ad2a8bd Compare February 6, 2025 17:18
0sewa0
0sewa0 previously requested changes Feb 7, 2025
Copy link
Contributor

@0sewa0 0sewa0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(my comments gives more context why I think this is necessary, the order Github displays it is a bit meh😅 )
I tried to do a POC on how I think this should be done: (the git diff)

diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index ced57ecd4..8e21bca09 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -20,6 +20,10 @@ jobs:
         id: prep
         run: |
           hack/build/ci/prepare-build-variables.sh
+      - name: Prepare sbom
+        id: sbom
+        run: |
+          make release/gen-sbom
       - name: Docker metadata
         uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
         id: meta
@@ -237,10 +241,8 @@ jobs:
           image-ref: ${{ matrix.url }}/${{ secrets[matrix.repository] }}:${{ needs.prepare.outputs.version }}@${{ needs.manifest.outputs.digest }}
           format: 'cyclonedx'
           output: 'result.json'
-          skip-dirs:
-            - '/usr/share/dynatrace-operator/third_party_licenses'
-          skip-files:
-            - '/usr/local/bin/dynatrace-operator'
+          skip-dirs: '/usr/share/dynatrace-operator/third_party_licenses'
+          skip-files: '/usr/local/bin/dynatrace-operator'
       - name: Upload sbom to ${{matrix.registry}}
         uses: ./.github/actions/upload-sbom
         with:
diff --git a/.gitignore b/.gitignore
index 603b88677..9be34577e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -106,3 +106,4 @@ test/testdata/secrets/*
 local/
 
 permissions.md
+dynatrace-operator-bin-sbom.cdx.json
diff --git a/Dockerfile b/Dockerfile
index 5420da2ab..23081c807 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,7 +14,6 @@ RUN go mod download -x
 
 COPY pkg ./pkg
 COPY cmd ./cmd
-COPY .git /.git
 
 ARG GO_LINKER_ARGS
 ARG GO_BUILD_TAGS
@@ -27,10 +26,6 @@ RUN --mount=type=cache,target="/root/.cache/go-build" \
     go build -tags "${GO_BUILD_TAGS}" -trimpath -ldflags="${GO_LINKER_ARGS}" \
     -o ./build/_output/bin/dynatrace-operator ./cmd/
 
-# Generate binary SBOM - improved hierarchy resolution
-RUN go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@v1.9.0
-RUN cyclonedx-gomod app -licenses -assert-licenses -json -main ./cmd -output ./build/_output/bin/dynatrace-operator-bin-sbom.json
-
 # platform is required, otherwise the copy command will copy the wrong architecture files, don't trust GitHub Actions linting warnings
 FROM --platform=$TARGETPLATFORM registry.access.redhat.com/ubi9-micro:9.5-1738816380@sha256:7e85855f6925e03f91b5c51f07886ff1c18c6ec69b5fc65491428a899da914a2 AS base
 FROM --platform=$TARGETPLATFORM registry.access.redhat.com/ubi9:9.5-1738814488@sha256:be214e191bbe3f4d0f16a5a4f5642e1f32fccd6fae7d2b6c6acb066ba51fb507 AS dependency
@@ -52,9 +47,6 @@ FROM --platform=$TARGETPLATFORM base
 
 COPY --from=dependency /tmp/rootfs-dependency /
 
-# operator sbom
-COPY --from=operator-build /app/build/_output/bin/dynatrace-operator-bin-sbom.json /dynatrace-operator-bin-sbom.cdx.json
-
 # operator binary
 COPY --from=operator-build /app/build/_output/bin /usr/local/bin
 
@@ -65,6 +57,8 @@ COPY --from=registry.k8s.io/sig-storage/livenessprobe:v2.15.0@sha256:2c5f9dc4ea5
 COPY ./third_party_licenses /usr/share/dynatrace-operator/third_party_licenses
 COPY LICENSE /licenses/
 
+COPY ./dynatrace-operator-bin-sbom.cdx.json ./dynatrace-operator-bin-sbom.cdx.json
+
 # custom scripts
 COPY hack/build/bin /usr/local/bin
 
diff --git a/hack/build/build_image.sh b/hack/build/build_image.sh
index 71dfcdf5e..fdfe2091d 100755
--- a/hack/build/build_image.sh
+++ b/hack/build/build_image.sh
@@ -21,6 +21,7 @@ out_image="${image}:${tag}"
 
 # directory required by docker copy command
 mkdir -p third_party_licenses
+touch dynatrace-operator-bin-sbom.cdx.json
 
 if ! command -v docker 2>/dev/null; then
   CONTAINER_CMD=podman
@@ -41,3 +42,4 @@ ${CONTAINER_CMD} build "${OPERATOR_BUILD_PLATFORM}" . -f ./Dockerfile -t "${out_
   --label "quay.expires-after=14d"
 
 rm -rf third_party_licenses
+rm dynatrace-operator-bin-sbom.cdx.json
diff --git a/hack/make/prerequisites.mk b/hack/make/prerequisites.mk
index e2613ec20..38ce0f7a8 100644
--- a/hack/make/prerequisites.mk
+++ b/hack/make/prerequisites.mk
@@ -16,6 +16,8 @@ markdownlint_cli_version=v0.44.0
 helmunittest_version=v0.7.2
 # renovate depName=github.com/princjef/gomarkdoc
 gomarkdoc_version=v1.1.0
+# renovate depName=github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod
+cyclonedx_gomod_version=v1.9.0
 
 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
 ifeq (,$(shell go env GOBIN))
@@ -47,6 +49,9 @@ prerequisites/go-linting: prerequisites/go-deadcode
 prerequisites/go-deadcode:
 	go install golang.org/x/tools/cmd/deadcode@$(golang_tools_version)
 
+prerequisites/release:
+	go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@$(cyclonedx_gomod_version)
+
 ## Install go test coverage
 prerequisites/go-test-coverage:
 	go install github.com/vladopajic/go-test-coverage/v2@latest

A more human readable summary:

  • Created a make release/gen-sbom command that will install the command and generate the sbom
    • the sbom file is part of .gitignore to not pollute the FS
    • added the renovate related boilerplate (hopefully correctly)
    • you easily test it and can look at the sbom so yay :D
  • added an extra step in therelease.yaml in the prep phase to generate this sbom
    • we already have the .git here, so no need to worry about that
    • so we only do this during the release
  • Removed most changes to the Dockerfile, left in the copy, but doing it from the FS to the container
    • I can easily "mock" the SBOM file during the make build similar to the third_party_licenses

Dockerfile Outdated Show resolved Hide resolved
.github/workflows/release.yaml Outdated Show resolved Hide resolved
@barblin barblin force-pushed the feat/QSP-15724/sbom-dependency-relationship-transparency branch from ad2a8bd to a454a17 Compare February 11, 2025 15:05
@barblin barblin requested a review from 0sewa0 February 11, 2025 15:05
@barblin
Copy link
Contributor Author

barblin commented Feb 11, 2025

(my comments gives more context why I think this is necessary, the order Github displays it is a bit meh😅 ) I tried to do a POC on how I think this should be done: (the git diff)

diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index ced57ecd4..8e21bca09 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -20,6 +20,10 @@ jobs:
         id: prep
         run: |
           hack/build/ci/prepare-build-variables.sh
+      - name: Prepare sbom
+        id: sbom
+        run: |
+          make release/gen-sbom
       - name: Docker metadata
         uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
         id: meta
@@ -237,10 +241,8 @@ jobs:
           image-ref: ${{ matrix.url }}/${{ secrets[matrix.repository] }}:${{ needs.prepare.outputs.version }}@${{ needs.manifest.outputs.digest }}
           format: 'cyclonedx'
           output: 'result.json'
-          skip-dirs:
-            - '/usr/share/dynatrace-operator/third_party_licenses'
-          skip-files:
-            - '/usr/local/bin/dynatrace-operator'
+          skip-dirs: '/usr/share/dynatrace-operator/third_party_licenses'
+          skip-files: '/usr/local/bin/dynatrace-operator'
       - name: Upload sbom to ${{matrix.registry}}
         uses: ./.github/actions/upload-sbom
         with:
diff --git a/.gitignore b/.gitignore
index 603b88677..9be34577e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -106,3 +106,4 @@ test/testdata/secrets/*
 local/
 
 permissions.md
+dynatrace-operator-bin-sbom.cdx.json
diff --git a/Dockerfile b/Dockerfile
index 5420da2ab..23081c807 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,7 +14,6 @@ RUN go mod download -x
 
 COPY pkg ./pkg
 COPY cmd ./cmd
-COPY .git /.git
 
 ARG GO_LINKER_ARGS
 ARG GO_BUILD_TAGS
@@ -27,10 +26,6 @@ RUN --mount=type=cache,target="/root/.cache/go-build" \
     go build -tags "${GO_BUILD_TAGS}" -trimpath -ldflags="${GO_LINKER_ARGS}" \
     -o ./build/_output/bin/dynatrace-operator ./cmd/
 
-# Generate binary SBOM - improved hierarchy resolution
-RUN go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@v1.9.0
-RUN cyclonedx-gomod app -licenses -assert-licenses -json -main ./cmd -output ./build/_output/bin/dynatrace-operator-bin-sbom.json
-
 # platform is required, otherwise the copy command will copy the wrong architecture files, don't trust GitHub Actions linting warnings
 FROM --platform=$TARGETPLATFORM registry.access.redhat.com/ubi9-micro:9.5-1738816380@sha256:7e85855f6925e03f91b5c51f07886ff1c18c6ec69b5fc65491428a899da914a2 AS base
 FROM --platform=$TARGETPLATFORM registry.access.redhat.com/ubi9:9.5-1738814488@sha256:be214e191bbe3f4d0f16a5a4f5642e1f32fccd6fae7d2b6c6acb066ba51fb507 AS dependency
@@ -52,9 +47,6 @@ FROM --platform=$TARGETPLATFORM base
 
 COPY --from=dependency /tmp/rootfs-dependency /
 
-# operator sbom
-COPY --from=operator-build /app/build/_output/bin/dynatrace-operator-bin-sbom.json /dynatrace-operator-bin-sbom.cdx.json
-
 # operator binary
 COPY --from=operator-build /app/build/_output/bin /usr/local/bin
 
@@ -65,6 +57,8 @@ COPY --from=registry.k8s.io/sig-storage/livenessprobe:v2.15.0@sha256:2c5f9dc4ea5
 COPY ./third_party_licenses /usr/share/dynatrace-operator/third_party_licenses
 COPY LICENSE /licenses/
 
+COPY ./dynatrace-operator-bin-sbom.cdx.json ./dynatrace-operator-bin-sbom.cdx.json
+
 # custom scripts
 COPY hack/build/bin /usr/local/bin
 
diff --git a/hack/build/build_image.sh b/hack/build/build_image.sh
index 71dfcdf5e..fdfe2091d 100755
--- a/hack/build/build_image.sh
+++ b/hack/build/build_image.sh
@@ -21,6 +21,7 @@ out_image="${image}:${tag}"
 
 # directory required by docker copy command
 mkdir -p third_party_licenses
+touch dynatrace-operator-bin-sbom.cdx.json
 
 if ! command -v docker 2>/dev/null; then
   CONTAINER_CMD=podman
@@ -41,3 +42,4 @@ ${CONTAINER_CMD} build "${OPERATOR_BUILD_PLATFORM}" . -f ./Dockerfile -t "${out_
   --label "quay.expires-after=14d"
 
 rm -rf third_party_licenses
+rm dynatrace-operator-bin-sbom.cdx.json
diff --git a/hack/make/prerequisites.mk b/hack/make/prerequisites.mk
index e2613ec20..38ce0f7a8 100644
--- a/hack/make/prerequisites.mk
+++ b/hack/make/prerequisites.mk
@@ -16,6 +16,8 @@ markdownlint_cli_version=v0.44.0
 helmunittest_version=v0.7.2
 # renovate depName=github.com/princjef/gomarkdoc
 gomarkdoc_version=v1.1.0
+# renovate depName=github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod
+cyclonedx_gomod_version=v1.9.0
 
 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
 ifeq (,$(shell go env GOBIN))
@@ -47,6 +49,9 @@ prerequisites/go-linting: prerequisites/go-deadcode
 prerequisites/go-deadcode:
 	go install golang.org/x/tools/cmd/deadcode@$(golang_tools_version)
 
+prerequisites/release:
+	go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@$(cyclonedx_gomod_version)
+
 ## Install go test coverage
 prerequisites/go-test-coverage:
 	go install github.com/vladopajic/go-test-coverage/v2@latest

A more human readable summary:

  • Created a make release/gen-sbom command that will install the command and generate the sbom

    • the sbom file is part of .gitignore to not pollute the FS
    • added the renovate related boilerplate (hopefully correctly)
    • you easily test it and can look at the sbom so yay :D
  • added an extra step in therelease.yaml in the prep phase to generate this sbom

    • we already have the .git here, so no need to worry about that
    • so we only do this during the release
  • Removed most changes to the Dockerfile, left in the copy, but doing it from the FS to the container

    • I can easily "mock" the SBOM file during the make build similar to the third_party_licenses

Thanks for the detailed improvement suggestions!

@codecov-commenter
Copy link

codecov-commenter commented Feb 11, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 64.91%. Comparing base (e0bdde7) to head (2604f7a).
Report is 1 commits behind head on main.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4424   +/-   ##
=======================================
  Coverage   64.91%   64.91%           
=======================================
  Files         413      413           
  Lines       27248    27248           
=======================================
  Hits        17687    17687           
  Misses       8233     8233           
  Partials     1328     1328           
Flag Coverage Δ
unittests 64.91% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@andriisoldatenko
Copy link
Contributor

@barblin now we need to make it work:

you can check one of the docker build steps are failing:

Dockerfile:60
--------------------
  58 |     COPY LICENSE /licenses/
  59 |     
  60 | >>> COPY ./dynatrace-operator-bin-sbom.cdx.json ./dynatrace-operator-bin-sbom.cdx.json
  61 |     
  62 |     # custom scripts
--------------------
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 8fz4uqqc29i67g0nv8esovlv7::oefa8db2sgvfcwzpiw1d7kss4: "/dynatrace-operator-bin-sbom.cdx.json": not found
Reference

@barblin barblin force-pushed the feat/QSP-15724/sbom-dependency-relationship-transparency branch from 5525da4 to e36cf5e Compare February 11, 2025 16:42
@barblin
Copy link
Contributor Author

barblin commented Feb 11, 2025

@barblin now we need to make it work:

you can check one of the docker build steps are failing:

Dockerfile:60
--------------------
  58 |     COPY LICENSE /licenses/
  59 |     
  60 | >>> COPY ./dynatrace-operator-bin-sbom.cdx.json ./dynatrace-operator-bin-sbom.cdx.json
  61 |     
  62 |     # custom scripts
--------------------
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 8fz4uqqc29i67g0nv8esovlv7::oefa8db2sgvfcwzpiw1d7kss4: "/dynatrace-operator-bin-sbom.cdx.json": not found
Reference

@andriisoldatenko is there a way to verify before getting an approval? I checked what went wrong and pushed a change, but I don't think I can locally validate/test all the build steps (or I didnt see it ;) )

@0sewa0
Copy link
Contributor

0sewa0 commented Feb 12, 2025

@barblin I think your change would make the CI pass, but the SBOM would never land in the release image, because the prepare step (where the SBOM gets created) has a different FS to the build step (I messed this up in my suggestion 😓 )

  • your change to add touch <sbom-file> in the ./.github/actions/build-image action was something I also missed 🙌

Here is what I think should work: (did some simplification on the make targets front)

diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 41aec108..b79da545 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -20,12 +20,6 @@ jobs:
         id: prep
         run: |
           hack/build/ci/prepare-build-variables.sh
-      - name: Install release prerequisites
-        run: make prerequisites/release
-      - name: Prepare SBOM
-        id: sbom
-        run: |
-          make release/gen-sbom
       - name: Docker metadata
         uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
         id: meta
@@ -50,6 +44,10 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+      - name: Prepare SBOM
+        id: sbom
+        run: |
+          make release/gen-sbom
       - name: Build image
         uses: ./.github/actions/build-image
         with:
diff --git a/hack/make/prerequisites.mk b/hack/make/prerequisites.mk
index 7a35ece7..55763466 100644
--- a/hack/make/prerequisites.mk
+++ b/hack/make/prerequisites.mk
@@ -85,5 +85,5 @@ prerequisites/python:
 	python3 -m venv local/.venv && source local/.venv/bin/activate && pip3 install -r hack/requirements.txt
 
 ## Install 'cyclonedx-gomod' if it is missing
-prerequisites/release:
+prerequisites/cyclonedx-gomod:
 	go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@$(cyclonedx_gomod_version)
diff --git a/hack/make/release/release.mk b/hack/make/release/release.mk
index f592af3e..5e6abf3a 100644
--- a/hack/make/release/release.mk
+++ b/hack/make/release/release.mk
@@ -1,3 +1,3 @@
 ## Generates SBOM of binary
-release/gen-sbom:
+release/gen-sbom: prerequisites/cyclonedx-gomod
 	cyclonedx-gomod app -licenses -assert-licenses -json -main cmd/ -output dynatrace-operator-bin-sbom.cdx.json

FYI: the CI / Code security scanning alerts (pull_request) check failing is "normal" for PRs that come from forks. 😅 😬

@barblin barblin force-pushed the feat/QSP-15724/sbom-dependency-relationship-transparency branch from 2c1e417 to bee9cdd Compare February 12, 2025 15:09
@barblin
Copy link
Contributor Author

barblin commented Feb 12, 2025

prerequisites.mk

@0sewa0 branch updated. Thanks for the detailed feedback :)

@0sewa0 0sewa0 dismissed their stale review February 13, 2025 08:22

changes were implemented

Copy link
Contributor

@andriisoldatenko andriisoldatenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code LGMT.

NOTE: if you need a SBOM file in dev env/image:

  1. you need to run make release/gen-sbom
  2. then run make images/build/push

@0sewa0 0sewa0 enabled auto-merge (squash) February 17, 2025 09:07
@0sewa0 0sewa0 merged commit 0e5e7b0 into Dynatrace:main Feb 17, 2025
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants