Skip to content

Discover SBOMs attached to images via OCI referrers and tags#1701

Merged
st3penta merged 1 commit intoconforma:mainfrom
st3penta:EC-1655
Mar 25, 2026
Merged

Discover SBOMs attached to images via OCI referrers and tags#1701
st3penta merged 1 commit intoconforma:mainfrom
st3penta:EC-1655

Conversation

@st3penta
Copy link
Copy Markdown
Contributor

Use the new ec.oci.image_referrers and ec.oci.image_tag_refs builtins to discover SBOMs attached directly to the image being validated. Referrers with recognized SBOM artifact types (CycloneDX, SPDX) and legacy cosign .sbom tag references are fetched and parsed alongside the existing SLSA Provenance-based discovery.

Convert SBOM collection rules from arrays to sets for natural deduplication when the same SBOM is discovered via multiple methods.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Ref: https://redhat.atlassian.net/browse/EC-1655

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Go module dependencies updated; SBOM policy refactored to set-based aggregation and extended to discover SBOMs via OCI Referrers API and legacy .sbom image tag refs; many tests adjusted to exercise OCI referrer/tag discovery and to normalize mocked image digests.

Changes

Cohort / File(s) Summary
Root Go Modules
go.mod, acceptance/go.mod
Bumped github.com/conforma/cli and numerous indirect deps (Google Cloud libs, gax, go-openapi, logrus, etc.); removed several indirect requires and added github.com/clipperhouse/*. Review dependency removals/additions for transitive impact.
SBOM Policy Logic
policy/lib/sbom/sbom.rego
Refactored SBOM aggregation to use deduplicated sets; introduced _sbom_artifact_types; replaced older OCI fetch rules with unified _fetch_sboms_from_image that queries ec.oci.image_referrers (filtered by artifactType) and legacy .sbom tag discovery; removed _fetch_oci_sbom pathways.
SBOM Policy Tests
policy/lib/sbom/sbom_test.rego
Updated mocked image digests; added positive/negative tests for OCI referrer-based discovery and .sbom tag-based discovery; added explicit with ec.oci.image_referrers as [] / ec.oci.image_tag_refs as [] bindings where needed.
Release & Related Tests
policy/release/.../sbom*.rego, policy/release/base_image_registries/base_image_registries_test.rego, policy/release/pre_build_script_task/..._test.rego
Many tests now bind ec.oci.image_referrers and ec.oci.image_tag_refs (typically []); normalized image digest values; reformatted helper with clauses and inline ignore comments.
SBOM CycloneDX/SPDX Tests
policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego, policy/release/sbom_spdx/sbom_spdx_test.rego
Added OCI with bindings across assertions; reworked helper rules to include new ec.oci.* context and moved with-outside-test-context comments inline. Focus review on test intent changes and helper rule formatting.

Sequence Diagram(s)

sequenceDiagram
    participant Policy as SBOM Policy
    participant OCI as OCI Referrers API
    participant Tags as Image Tag Refs
    participant Blob as OCI Blob Store
    participant Parser as SBOM Parser

    Policy->>OCI: query ec.oci.image_referrers(image)
    OCI-->>Policy: referrer entries (artifactType, digest)
    alt artifactType ∈ _sbom_artifact_types
        Policy->>Blob: ec.oci.blob(digest)
        Blob-->>Policy: blob payload (JSON)
        Policy->>Parser: json.unmarshal / parse
        Parser-->>Policy: SBOM object (CycloneDX/SPDX)
        Policy->>Policy: add to cyclonedx/spdx sets
    end

    Policy->>Tags: query ec.oci.image_tag_refs(image)
    Tags-->>Policy: tag refs
    alt tag endsWith ".sbom"
        Policy->>Blob: ec.oci.blob(tag)
        Blob-->>Policy: blob payload (JSON)
        Policy->>Parser: parse SBOM
        Parser-->>Policy: SBOM object
        Policy->>Policy: add to cyclonedx/spdx sets
    end

    Policy->>Policy: union/deduplicate sets -> all_sboms
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding SBOM discovery via OCI referrers and tags, which aligns with the primary objective of the PR.
Description check ✅ Passed The description accurately relates to the changeset, explaining the use of new builtins for SBOM discovery, conversion to sets for deduplication, and the overall intent of the changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
policy/lib/sbom/sbom_test.rego (1)

8-12: ⚠️ Potential issue | 🟠 Major

Test expectations use arrays but actual values are now sets.

If cyclonedx_sboms and spdx_sboms are now sets (from the contains ... if rules), then expected values should use set literals {...} rather than array literals [...]. In Rego, {x} == [x] evaluates to false.

Verify that lib.assert_equal handles this type coercion, or update expectations to use set syntax.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@policy/lib/sbom/sbom_test.rego` around lines 8 - 12, The test test_all_sboms
is comparing arrays to values that are now sets (sbom.cyclonedx_sboms and
sbom.spdx_sboms), so update the expectation to use Rego set literals instead of
arrays: replace the expected := ["hurricane","tornado","spandex","latex"] with a
set literal { ... } or otherwise coerce sbom.all_sboms into an array before
calling lib.assert_equal; ensure you reference test_all_sboms, expected,
sbom.cyclonedx_sboms, sbom.spdx_sboms, sbom.all_sboms and lib.assert_equal when
making the change so types match.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@policy/lib/sbom/sbom.rego`:
- Around line 18-40: The refactor turned previously-array SBOM rules into
set-based "contains ... if" rules (cyclonedx_sboms,
_cyclonedx_sboms_from_attestations, _cyclonedx_sboms_from_oci,
_cyclonedx_sboms_from_image, spdx_sboms, _spdx_*), which breaks callers that
expect arrays (array.concat and indexed "some index, s in ..."); restore array
semantics by returning arrays instead of sets for lib.sbom.cyclonedx_sboms and
lib.sbom.spdx_sboms — e.g. change the rules for cyclonedx_sboms and spdx_sboms
and their helpers to produce arrays (array comprehensions or explicit array
construction) so array.concat(lib.sbom.spdx_sboms, lib.sbom.cyclonedx_sboms) and
indexed loops (some index, s in sbom.cyclonedx_sboms) continue to work and
indices remain stable for error messages.

---

Outside diff comments:
In `@policy/lib/sbom/sbom_test.rego`:
- Around line 8-12: The test test_all_sboms is comparing arrays to values that
are now sets (sbom.cyclonedx_sboms and sbom.spdx_sboms), so update the
expectation to use Rego set literals instead of arrays: replace the expected :=
["hurricane","tornado","spandex","latex"] with a set literal { ... } or
otherwise coerce sbom.all_sboms into an array before calling lib.assert_equal;
ensure you reference test_all_sboms, expected, sbom.cyclonedx_sboms,
sbom.spdx_sboms, sbom.all_sboms and lib.assert_equal when making the change so
types match.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 482270c9-bebe-45ca-a844-aada71049e90

📥 Commits

Reviewing files that changed from the base of the PR and between 61ec982 and 6eeaf71.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (3)
  • go.mod
  • policy/lib/sbom/sbom.rego
  • policy/lib/sbom/sbom_test.rego

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego (1)

528-543: ⚠️ Potential issue | 🟡 Minor

Missing OCI mocks in assert_not_allowed helper.

Similar to the SPDX test file, assert_allowed (lines 522-525) was updated with OCI mocks, but assert_not_allowed was not updated. This should be addressed for consistency and to prevent potential test issues.

🐛 Proposed fix
 assert_not_allowed(purl, disallowed_packages) if {
 	expected := {{
 		"code": "sbom_cyclonedx.allowed",
 		"msg": sprintf("Package is not allowed: %s", [purl]),
 	}}
 	att := json.patch(_sbom_1_5_attestation, [{
 		"op": "add",
 		"path": "/statement/predicate/components/0/purl",
 		"value": purl,
 	}])

 	# regal ignore:with-outside-test-context
 	lib.assert_equal_results(sbom_cyclonedx.deny, expected) with input.attestations as [att]
 		# regal ignore:with-outside-test-context
-with 		data.rule_data.disallowed_packages as disallowed_packages
+		with data.rule_data.disallowed_packages as disallowed_packages
+		# regal ignore:with-outside-test-context
+		with ec.oci.image_referrers as []
+		# regal ignore:with-outside-test-context
+		with ec.oci.image_tag_refs as []
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego` around lines 528 -
543, The test helper assert_not_allowed is missing the OCI mock setup that
assert_allowed includes; update assert_not_allowed (used with
sbom_cyclonedx.deny and _sbom_1_5_attestation) to add the same OCI mock context
as assert_allowed so the attestation input includes OCI artifact/component mocks
before calling lib.assert_equal_results; ensure you still patch the purl into
the attestation and keep the with data.rule_data.disallowed_packages as
disallowed_packages binding when invoking the rule.
policy/release/sbom_spdx/sbom_spdx_test.rego (1)

117-132: ⚠️ Potential issue | 🟡 Minor

Missing OCI mocks in assert_not_allowed helper.

The assert_allowed helper (lines 111-114) was updated with ec.oci.image_referrers as [] and ec.oci.image_tag_refs as [], but assert_not_allowed was not. This inconsistency could cause test failures or unintended OCI registry calls.

🐛 Proposed fix
 assert_not_allowed(purl, disallowed_packages) if {
 	expected := {{
 		"code": "sbom_spdx.allowed",
 		"msg": sprintf("Package is not allowed: %s", [purl]),
 	}}
 	att := json.patch(_sbom_attestation, [{
 		"op": "add",
 		"path": "/statement/predicate/packages/0/externalRefs/0/referenceLocator",
 		"value": purl,
 	}])

 	# regal ignore:with-outside-test-context
 	lib.assert_equal_results(sbom_spdx.deny, expected) with input.attestations as [att]
 		# regal ignore:with-outside-test-context
-with 		data.rule_data.disallowed_packages as disallowed_packages
+		with data.rule_data.disallowed_packages as disallowed_packages
+		# regal ignore:with-outside-test-context
+		with ec.oci.image_referrers as []
+		# regal ignore:with-outside-test-context
+		with ec.oci.image_tag_refs as []
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@policy/release/sbom_spdx/sbom_spdx_test.rego` around lines 117 - 132, The
test helper assert_not_allowed is missing OCI mocks which assert_allowed added;
update assert_not_allowed to include the same external context mocks (set
ec.oci.image_referrers as [] and ec.oci.image_tag_refs as []) in the with-input
override used for invoking sbom_spdx.deny so the test uses empty referrer/tag
lists and avoids real OCI calls—apply this change in the same with
input.attestations as [att] ... with data.rule_data.disallowed_packages as
disallowed_packages block that wraps the sbom_spdx.deny assertion involving
_sbom_attestation.
acceptance/go.mod (1)

127-127: ⚠️ Potential issue | 🟠 Major

Update github.com/docker/cli to fix HIGH severity privilege escalation on Windows.

github.com/docker/cli v29.0.3+incompatible contains CVE-2025-15558 (GHSA-p436-gjf2-799p): a local privilege escalation vulnerability where the Docker CLI plugin manager searches for plugins in a writable directory (C:\ProgramData\Docker\cli-plugins on Windows), allowing a low-privileged attacker to inject malicious plugin executables. This is fixed in v29.2.0 and later. Update the dependency or investigate the transitive dependency chain to enable a version upgrade.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acceptance/go.mod` at line 127, The go.mod currently pins
"github.com/docker/cli v29.0.3+incompatible" which is vulnerable; update that
requirement to v29.2.0 or newer to remediate CVE-2025-15558: run a module
upgrade for github.com/docker/cli (e.g. go get github.com/docker/cli@v29.2.0)
and then run go mod tidy and tests; if the dependency is indirect, run go mod
graph to find the direct module that pulls in github.com/docker/cli and update
that module or add a replace directive so the resolved version of
github.com/docker/cli is >= v29.2.0.
🧹 Nitpick comments (1)
policy/release/pre_build_script_task/pre_build_script_task_test.rego (1)

14-16: Inconsistent with clause indentation.

Several with clauses have inconsistent indentation - some use with with a tab character after it (e.g., line 14: with \t\tinput.image), while others follow the standard pattern. This appears to be a formatting artifact.

Also applies to: 42-44, 66-68, 87-89, 98-100, 107-109, 133-135, 142-144, 164-166, 178-180, 201-203

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@policy/release/pre_build_script_task/pre_build_script_task_test.rego` around
lines 14 - 16, The failing/dirty formatting is inconsistent use of a tab after
the with keyword in multiple with clauses (e.g., "with	input.image as {...}",
"with ec.oci.image_referrers as []", "with ec.oci.image_tag_refs as []" in
pre_build_script_task_test.rego); fix by normalizing indentation to a single
space after every with keyword across all occurrences (including the other
reported ranges 42-44, 66-68, 87-89, 98-100, 107-109, 133-135, 142-144, 164-166,
178-180, 201-203) so each clause reads "with <symbol> as <value>" for symbols
like input.image, ec.oci.image_referrers, and ec.oci.image_tag_refs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@acceptance/go.mod`:
- Line 127: The go.mod currently pins "github.com/docker/cli
v29.0.3+incompatible" which is vulnerable; update that requirement to v29.2.0 or
newer to remediate CVE-2025-15558: run a module upgrade for
github.com/docker/cli (e.g. go get github.com/docker/cli@v29.2.0) and then run
go mod tidy and tests; if the dependency is indirect, run go mod graph to find
the direct module that pulls in github.com/docker/cli and update that module or
add a replace directive so the resolved version of github.com/docker/cli is >=
v29.2.0.

In `@policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego`:
- Around line 528-543: The test helper assert_not_allowed is missing the OCI
mock setup that assert_allowed includes; update assert_not_allowed (used with
sbom_cyclonedx.deny and _sbom_1_5_attestation) to add the same OCI mock context
as assert_allowed so the attestation input includes OCI artifact/component mocks
before calling lib.assert_equal_results; ensure you still patch the purl into
the attestation and keep the with data.rule_data.disallowed_packages as
disallowed_packages binding when invoking the rule.

In `@policy/release/sbom_spdx/sbom_spdx_test.rego`:
- Around line 117-132: The test helper assert_not_allowed is missing OCI mocks
which assert_allowed added; update assert_not_allowed to include the same
external context mocks (set ec.oci.image_referrers as [] and
ec.oci.image_tag_refs as []) in the with-input override used for invoking
sbom_spdx.deny so the test uses empty referrer/tag lists and avoids real OCI
calls—apply this change in the same with input.attestations as [att] ... with
data.rule_data.disallowed_packages as disallowed_packages block that wraps the
sbom_spdx.deny assertion involving _sbom_attestation.

---

Nitpick comments:
In `@policy/release/pre_build_script_task/pre_build_script_task_test.rego`:
- Around line 14-16: The failing/dirty formatting is inconsistent use of a tab
after the with keyword in multiple with clauses (e.g., "with	input.image as
{...}", "with ec.oci.image_referrers as []", "with ec.oci.image_tag_refs as []"
in pre_build_script_task_test.rego); fix by normalizing indentation to a single
space after every with keyword across all occurrences (including the other
reported ranges 42-44, 66-68, 87-89, 98-100, 107-109, 133-135, 142-144, 164-166,
178-180, 201-203) so each clause reads "with <symbol> as <value>" for symbols
like input.image, ec.oci.image_referrers, and ec.oci.image_tag_refs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 24076678-eb2b-48f3-a96b-138d4d7b19c5

📥 Commits

Reviewing files that changed from the base of the PR and between 6eeaf71 and 603dc53.

⛔ Files ignored due to path filters (2)
  • acceptance/go.sum is excluded by !**/*.sum
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • acceptance/go.mod
  • go.mod
  • policy/lib/sbom/sbom.rego
  • policy/lib/sbom/sbom_test.rego
  • policy/release/base_image_registries/base_image_registries_test.rego
  • policy/release/pre_build_script_task/pre_build_script_task_test.rego
  • policy/release/sbom/sbom_test.rego
  • policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego
  • policy/release/sbom_spdx/sbom_spdx_test.rego
✅ Files skipped from review due to trivial changes (1)
  • go.mod
🚧 Files skipped from review as they are similar to previous changes (1)
  • policy/lib/sbom/sbom.rego

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
policy/lib/sbom/sbom.rego 100.00% <100.00%> (ø)
policy/lib/sbom/sbom_test.rego 100.00% <100.00%> (ø)
...e_image_registries/base_image_registries_test.rego 100.00% <ø> (ø)
..._build_script_task/pre_build_script_task_test.rego 100.00% <ø> (ø)
policy/release/sbom/sbom_test.rego 100.00% <100.00%> (ø)
...cy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego 100.00% <100.00%> (ø)
policy/release/sbom_spdx/sbom_spdx_test.rego 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

🧹 Nitpick comments (1)
policy/lib/sbom/sbom.rego (1)

84-97: Missing error handling for malformed SBOM blobs.

json.unmarshal will fail if the blob content is not valid JSON. In Rego, a failing builtin causes the rule to not produce a value (which is acceptable), but consider whether logging or surfacing malformed SBOMs would be useful for debugging discovery issues.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@policy/lib/sbom/sbom.rego` around lines 84 - 97, The current SBOM discovery
rules (_sboms_from_referrers and _sboms_from_tag_refs) call json.unmarshal(blob)
but don't record or surface when that builtin fails; add companion rules (e.g.,
_malformed_sboms_from_referrers and _malformed_sboms_from_tag_refs) that iterate
the same sources (ec.oci.image_referrers, ec.oci.image_tag_refs), bind blob :=
ec.oci.blob(...), and capture refs where the unmarshal fails using the "not sbom
:= json.unmarshal(blob)" pattern so malformed blobs are recorded (store ref/blob
or emit into a diagnostic collection) for debugging; keep the original _sboms_*
rules unchanged so valid SBOMs still get produced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@policy/lib/sbom/sbom.rego`:
- Around line 84-97: The current SBOM discovery rules (_sboms_from_referrers and
_sboms_from_tag_refs) call json.unmarshal(blob) but don't record or surface when
that builtin fails; add companion rules (e.g., _malformed_sboms_from_referrers
and _malformed_sboms_from_tag_refs) that iterate the same sources
(ec.oci.image_referrers, ec.oci.image_tag_refs), bind blob := ec.oci.blob(...),
and capture refs where the unmarshal fails using the "not sbom :=
json.unmarshal(blob)" pattern so malformed blobs are recorded (store ref/blob or
emit into a diagnostic collection) for debugging; keep the original _sboms_*
rules unchanged so valid SBOMs still get produced.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 861f71c8-280d-419f-83aa-305eca29533b

📥 Commits

Reviewing files that changed from the base of the PR and between 603dc53 and 5ff8c46.

⛔ Files ignored due to path filters (2)
  • acceptance/go.sum is excluded by !**/*.sum
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • acceptance/go.mod
  • go.mod
  • policy/lib/sbom/sbom.rego
  • policy/lib/sbom/sbom_test.rego
  • policy/release/base_image_registries/base_image_registries_test.rego
  • policy/release/pre_build_script_task/pre_build_script_task_test.rego
  • policy/release/sbom/sbom_test.rego
  • policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego
  • policy/release/sbom_spdx/sbom_spdx_test.rego
✅ Files skipped from review due to trivial changes (2)
  • policy/release/pre_build_script_task/pre_build_script_task_test.rego
  • acceptance/go.mod
🚧 Files skipped from review as they are similar to previous changes (3)
  • policy/release/base_image_registries/base_image_registries_test.rego
  • policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego
  • policy/release/sbom_spdx/sbom_spdx_test.rego

simonbaird
simonbaird previously approved these changes Mar 24, 2026
Copy link
Copy Markdown
Member

@simonbaird simonbaird left a comment

Choose a reason for hiding this comment

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

Lgtm, but consider my naming nitpicks.

simonbaird
simonbaird previously approved these changes Mar 25, 2026
Copy link
Copy Markdown
Member

@simonbaird simonbaird left a comment

Choose a reason for hiding this comment

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

Lgtm, but rebase needed?

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: 1

♻️ Duplicate comments (1)
policy/lib/sbom/sbom.rego (1)

22-29: ⚠️ Potential issue | 🟠 Major

Keep the exported SBOM arrays in a stable order.

Lines 22-29 rebuild cyclonedx_sboms and spdx_sboms from sets. That keeps deduplication, but it drops discovery order, so downstream some index, s in ... consumers get arbitrary indices and the exact-order assertions in policy/lib/sbom/sbom_test.rego become brittle. Deduplicate internally with sets if you want, but materialize the public arrays from an ordered source list so first-seen order stays stable.

#!/bin/bash
echo "=== public SBOM array materialization ==="
sed -n '20,30p' policy/lib/sbom/sbom.rego

echo
echo "=== consumers that use SBOM indices ==="
rg -n -C2 'some\s+index\s*,\s*\w+\s+in\s+sbom\.(cyclonedx_sboms|spdx_sboms)' --glob='*.rego'

echo
echo "=== tests that assert exact SBOM array contents ==="
rg -n -C2 'sbom\.(cyclonedx_sboms|spdx_sboms|all_sboms)' policy/lib/sbom/sbom_test.rego
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@policy/lib/sbom/sbom.rego` around lines 22 - 29, The public arrays
cyclonedx_sboms and spdx_sboms are being built from private set rules
(_cyclonedx_sboms, _spdx_sboms) which loses discovery order; change them to
materialize from an ordered source list (e.g. a concatenation of
_cyclonedx_sboms_from_input, _cyclonedx_sboms_from_pipelinerun,
_cyclonedx_sboms_from_image and similar spdx sources) and perform deduplication
while iterating that ordered list so the first-seen item is kept; update the
rules that reference cyclonedx_sboms/spdx_sboms so they keep stable indices
while internals still use sets for membership if needed (refer to symbols:
cyclonedx_sboms, spdx_sboms, _cyclonedx_sboms_from_input,
_cyclonedx_sboms_from_pipelinerun, _cyclonedx_sboms_from_image,
_spdx_sboms_from_input, _spdx_sboms_from_pipelinerun, _spdx_sboms_from_image,
and _cyclonedx_sboms/_spdx_sboms).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@policy/lib/sbom/sbom_test.rego`:
- Around line 201-205: The tests call the wrong helper module: replace calls to
data.lib.assert_equal with data.lib.assertions.assert_equal so the correct
exported helper is used; update each assertion invocation in sbom_test.rego
(e.g., the calls that use lib.assert_equal wrapping sbom.cyclonedx_sboms,
sbom.sbom_for_image, etc.) to reference data.lib.assertions.assert_equal,
keeping the same arguments and with statements.

---

Duplicate comments:
In `@policy/lib/sbom/sbom.rego`:
- Around line 22-29: The public arrays cyclonedx_sboms and spdx_sboms are being
built from private set rules (_cyclonedx_sboms, _spdx_sboms) which loses
discovery order; change them to materialize from an ordered source list (e.g. a
concatenation of _cyclonedx_sboms_from_input, _cyclonedx_sboms_from_pipelinerun,
_cyclonedx_sboms_from_image and similar spdx sources) and perform deduplication
while iterating that ordered list so the first-seen item is kept; update the
rules that reference cyclonedx_sboms/spdx_sboms so they keep stable indices
while internals still use sets for membership if needed (refer to symbols:
cyclonedx_sboms, spdx_sboms, _cyclonedx_sboms_from_input,
_cyclonedx_sboms_from_pipelinerun, _cyclonedx_sboms_from_image,
_spdx_sboms_from_input, _spdx_sboms_from_pipelinerun, _spdx_sboms_from_image,
and _cyclonedx_sboms/_spdx_sboms).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f5f0359f-f3c1-4a5f-903f-039646ffd34b

📥 Commits

Reviewing files that changed from the base of the PR and between 3176a1d and 571ceec.

⛔ Files ignored due to path filters (2)
  • acceptance/go.sum is excluded by !**/*.sum
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • acceptance/go.mod
  • go.mod
  • policy/lib/sbom/sbom.rego
  • policy/lib/sbom/sbom_test.rego
  • policy/release/base_image_registries/base_image_registries_test.rego
  • policy/release/pre_build_script_task/pre_build_script_task_test.rego
  • policy/release/sbom/sbom_test.rego
  • policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego
  • policy/release/sbom_spdx/sbom_spdx_test.rego
✅ Files skipped from review due to trivial changes (1)
  • policy/release/pre_build_script_task/pre_build_script_task_test.rego
🚧 Files skipped from review as they are similar to previous changes (4)
  • policy/release/base_image_registries/base_image_registries_test.rego
  • policy/release/sbom/sbom_test.rego
  • policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego
  • go.mod

Use the new ec.oci.image_referrers and ec.oci.image_tag_refs builtins
to discover SBOMs attached directly to the image being validated.
Referrers with recognized SBOM artifact types (CycloneDX, SPDX) and
legacy cosign .sbom tag references are fetched and parsed alongside
the existing SLSA Provenance-based discovery.

Convert SBOM collection rules from arrays to sets for natural
deduplication when the same SBOM is discovered via multiple methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Ref: https://redhat.atlassian.net/browse/EC-1655
@st3penta st3penta merged commit f9daefc into conforma:main Mar 25, 2026
7 checks passed
@st3penta st3penta deleted the EC-1655 branch March 25, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants