Skip to content

fix: split monolithic sbom up#6003

Closed
moolen wants to merge 1 commit intomainfrom
mj-fix-reko
Closed

fix: split monolithic sbom up#6003
moolen wants to merge 1 commit intomainfrom
mj-fix-reko

Conversation

@moolen
Copy link
Copy Markdown
Member

@moolen moolen commented Feb 27, 2026

Problem Statement

What is the problem you're trying to solve?

Related Issue

Fixes #...

Proposed Changes

How do you like to solve the issue and why?

Format

Please ensure that your PR follows the following format for the title:

feat(scope): add new feature
fix(scope): fix bug
docs(scope): update documentation
chore(scope): update build tool or dependencies
ref(scope): refactor code
clean(scope): provider cleanup
test(scope): add tests
perf(scope): improve performance
desig(scope): improve design

Where scope is optionally one of:

  • charts
  • release
  • testing
  • security
  • templating

Checklist

  • I have read the contribution guidelines
  • All commits are signed with git commit --signoff
  • My changes have reasonable test coverage
  • All tests pass with make test
  • I ensured my PR is ready for review with make reviewable

Changes

Refactors the SBOM generation workflow to create per-module SBOM files instead of a single monolithic file:

  • SBOM Generation: Updated to discover all go.mod files (excluding vendor), create a temporary workspace for each module, and generate individual SBOM files named sbom.gomod.<module-path>.<IMAGE_TAG>.spdx.json using syft with go-module-file-cataloger.
  • Attestation Workflow: Modified to iterate over all generated per-module SBOMs and attest each one individually, with group name updated from "Attest Go modules SBOM" to "Attest Go modules SBOMs".

File: .github/actions/sign/action.yml (+40/-5 lines)

Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>
@github-actions github-actions bot added component/github-actions kind/bug Categorizes issue or PR as related to a bug. labels Feb 27, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 27, 2026

Walkthrough

The action.yml file is refactored to generate per-module SBOMs from discovered go.mod files instead of producing a single SBOM. Each module receives an individual SBOM file with a naming convention. The attestation workflow is modified to attest each per-module SBOM separately.

Changes

Cohort / File(s) Summary
Per-Module SBOM Workflow
.github/actions/sign/action.yml
Refactors SBOM generation to discover all go.mod files (excluding vendor) and create dedicated SBOM files per module with pattern sbom.gomod.<module-path>.<IMAGE_TAG>.spdx.json. Updates attestation workflow to loop over and attest each per-module SBOM individually. Updates group name to plural form and adds per-module logging.

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/actions/sign/action.yml (1)

141-145: Fail fast when no module SBOM files match before attestation.

With nullglob, this loop can silently do nothing. Add an explicit match-count check so attestation cannot pass as a no-op.

Proposed refactor
         shopt -s nullglob
-        for SBOM_FILE in sbom.gomod.*.${IMAGE_TAG}.spdx.json; do
+        GO_MODULE_SBOMS=(sbom.gomod.*.${IMAGE_TAG}.spdx.json)
+        if [[ ${`#GO_MODULE_SBOMS`[@]} -eq 0 ]]; then
+          echo "No Go module SBOM files found for attestation."
+          exit 1
+        fi
+        for SBOM_FILE in "${GO_MODULE_SBOMS[@]}"; do
           echo "Attesting ${SBOM_FILE}"
           cosign attest --yes --new-bundle-format=false --use-signing-config=false --predicate "${SBOM_FILE}" --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
         done
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/sign/action.yml around lines 141 - 145, The attestation loop
uses `shopt -s nullglob` so it can silently skip when no
sbom.gomod.*.${IMAGE_TAG}.spdx.json files exist; add a pre-check that counts
matching files (e.g., expand into an array like
matches=(sbom.gomod.*.${IMAGE_TAG}.spdx.json)) and if the array is empty, print
an error and exit non‑zero to fail fast before running the `for SBOM_FILE ...`
loop and calling `cosign attest`; keep references to the `SBOM_FILE` variable,
the `IMAGE_TAG`/`IMAGE_NAME`/`CONTAINER_DIGEST` environment variables, and the
existing loop logic unchanged otherwise.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/actions/sign/action.yml:
- Line 106: The find invocation that populates GO_MOD_FILES currently only
excludes vendor dirs at repo root ("./vendor/*"); update the exclusion to ignore
any nested vendor directories by changing the -not -path argument on the find
command used to set GO_MOD_FILES (the line starting with "mapfile -t
GO_MOD_FILES < <(find ... )") to use a glob that matches any vendor path (e.g.
use "*/vendor/*" style pattern) so nested ./foo/vendor/... entries are also
omitted from module discovery.
- Around line 119-120: MODULE_PATH is being flattened into MODULE_PATH_SAFE by
simply replacing '/' with '-' which can produce collisions (e.g., a/b-c vs
a-b/c); update the transformation that sets MODULE_PATH_SAFE so it uses a
collision-safe, reversible encoding of MODULE_PATH (for example percent-encode
slashes as '%2F' or use base64/url-safe base64 of MODULE_PATH) and then build
SBOM_FILE using that encoded MODULE_PATH_SAFE and IMAGE_TAG; adjust the
assignment that references MODULE_PATH_SAFE, MODULE_PATH and SBOM_FILE in the
action.yml accordingly so distinct module paths produce distinct SBOM filenames.

---

Nitpick comments:
In @.github/actions/sign/action.yml:
- Around line 141-145: The attestation loop uses `shopt -s nullglob` so it can
silently skip when no sbom.gomod.*.${IMAGE_TAG}.spdx.json files exist; add a
pre-check that counts matching files (e.g., expand into an array like
matches=(sbom.gomod.*.${IMAGE_TAG}.spdx.json)) and if the array is empty, print
an error and exit non‑zero to fail fast before running the `for SBOM_FILE ...`
loop and calling `cosign attest`; keep references to the `SBOM_FILE` variable,
the `IMAGE_TAG`/`IMAGE_NAME`/`CONTAINER_DIGEST` environment variables, and the
existing loop logic unchanged otherwise.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03f0814 and 97fbed0.

📒 Files selected for processing (1)
  • .github/actions/sign/action.yml

syft dir:. -o spdx-json=sbom.gomod.${IMAGE_TAG}.spdx.json
# Go modules SBOMs (one per go.mod). This avoids a single very large
# monolithic predicate when the repo contains many modules.
mapfile -t GO_MOD_FILES < <(find . -type f -name go.mod -not -path "./vendor/*" | sort)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Broaden vendor exclusion in module discovery.

Line 106 only excludes ./vendor/* at repo root. Nested vendor directories (for example, ./foo/vendor/...) are still included and can pollute Go-module SBOMs.

Proposed fix
-        mapfile -t GO_MOD_FILES < <(find . -type f -name go.mod -not -path "./vendor/*" | sort)
+        mapfile -t GO_MOD_FILES < <(find . -type f -name go.mod -not -path "*/vendor/*" | sort)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mapfile -t GO_MOD_FILES < <(find . -type f -name go.mod -not -path "./vendor/*" | sort)
mapfile -t GO_MOD_FILES < <(find . -type f -name go.mod -not -path "*/vendor/*" | sort)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/sign/action.yml at line 106, The find invocation that
populates GO_MOD_FILES currently only excludes vendor dirs at repo root
("./vendor/*"); update the exclusion to ignore any nested vendor directories by
changing the -not -path argument on the find command used to set GO_MOD_FILES
(the line starting with "mapfile -t GO_MOD_FILES < <(find ... )") to use a glob
that matches any vendor path (e.g. use "*/vendor/*" style pattern) so nested
./foo/vendor/... entries are also omitted from module discovery.

Comment on lines +119 to +120
MODULE_PATH_SAFE="${MODULE_PATH//\//-}"
SBOM_FILE="sbom.gomod.${MODULE_PATH_SAFE}.${IMAGE_TAG}.spdx.json"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid SBOM filename collisions across module paths.

Line 119-Line 120 can generate identical names for distinct module dirs (e.g., a/b-c and a-b/c both become a-b-c), causing overwrite and missing attestations.

Proposed fix
-          MODULE_PATH_SAFE="${MODULE_PATH//\//-}"
-          SBOM_FILE="sbom.gomod.${MODULE_PATH_SAFE}.${IMAGE_TAG}.spdx.json"
+          MODULE_PATH_SAFE="${MODULE_PATH//\//-}"
+          MODULE_PATH_HASH="$(printf '%s' "${MODULE_PATH}" | sha256sum | cut -c1-12)"
+          SBOM_FILE="sbom.gomod.${MODULE_PATH_SAFE}.${MODULE_PATH_HASH}.${IMAGE_TAG}.spdx.json"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MODULE_PATH_SAFE="${MODULE_PATH//\//-}"
SBOM_FILE="sbom.gomod.${MODULE_PATH_SAFE}.${IMAGE_TAG}.spdx.json"
MODULE_PATH_SAFE="${MODULE_PATH//\//-}"
MODULE_PATH_HASH="$(printf '%s' "${MODULE_PATH}" | sha256sum | cut -c1-12)"
SBOM_FILE="sbom.gomod.${MODULE_PATH_SAFE}.${MODULE_PATH_HASH}.${IMAGE_TAG}.spdx.json"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/sign/action.yml around lines 119 - 120, MODULE_PATH is being
flattened into MODULE_PATH_SAFE by simply replacing '/' with '-' which can
produce collisions (e.g., a/b-c vs a-b/c); update the transformation that sets
MODULE_PATH_SAFE so it uses a collision-safe, reversible encoding of MODULE_PATH
(for example percent-encode slashes as '%2F' or use base64/url-safe base64 of
MODULE_PATH) and then build SBOM_FILE using that encoded MODULE_PATH_SAFE and
IMAGE_TAG; adjust the assignment that references MODULE_PATH_SAFE, MODULE_PATH
and SBOM_FILE in the action.yml accordingly so distinct module paths produce
distinct SBOM filenames.

@moolen
Copy link
Copy Markdown
Member Author

moolen commented Feb 27, 2026

closing this one in favour of #6004

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/github-actions kind/bug Categorizes issue or PR as related to a bug. size/s

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant