Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ Confirm the CycloneDX SBOM contains only packages without disallowed external re
* Effective from: `2024-07-31T00:00:00Z`
* https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/sbom_cyclonedx/sbom_cyclonedx.rego#L197[Source, window="_blank"]

[#sbom_cyclonedx__experimental_hermeto_backend]
=== link:#sbom_cyclonedx__experimental_hermeto_backend[Experimental Hermeto backend]

Verify that no components in the CycloneDX SBOM were fetched using an experimental Hermeto backend. Experimental backends are identified by top-level annotations whose text starts with "hermeto:backend:experimental:".

*Solution*: Use a supported, non-experimental package manager backend in your build process, or request a policy exception.

* Rule type: [rule-type-indicator failure]#FAILURE#
* FAILURE message: `Package %s was fetched using experimental Hermeto backend %q`
* Code: `sbom_cyclonedx.experimental_hermeto_backend`
* Effective from: `2026-08-01T00:00:00Z`
* https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/sbom_cyclonedx/sbom_cyclonedx.rego#L366[Source, window="_blank"]

[#sbom_cyclonedx__proxy_metadata_required]
=== link:#sbom_cyclonedx__proxy_metadata_required[Proxy metadata required]

Expand Down
13 changes: 13 additions & 0 deletions antora/docs/modules/ROOT/pages/packages/release_sbom_spdx.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,19 @@ Confirm the SPDX SBOM contains only packages without disallowed external referen
* Effective from: `2024-07-31T00:00:00Z`
* https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/sbom_spdx/sbom_spdx.rego#L106[Source, window="_blank"]

[#sbom_spdx__experimental_hermeto_backend]
=== link:#sbom_spdx__experimental_hermeto_backend[Experimental Hermeto backend]

Verify that no packages in the SPDX SBOM were fetched using an experimental Hermeto backend. Experimental backends are identified by annotations with annotator "Tool: hermeto:backend" whose comment starts with "hermeto:backend:experimental:".

*Solution*: Use a supported, non-experimental package manager backend in your build process, or request a policy exception.

* Rule type: [rule-type-indicator failure]#FAILURE#
* FAILURE message: `Package %s was fetched using experimental Hermeto backend %q`
* Code: `sbom_spdx.experimental_hermeto_backend`
* Effective from: `2026-08-01T00:00:00Z`
* https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/sbom_spdx/sbom_spdx.rego#L359[Source, window="_blank"]

[#sbom_spdx__matches_image]
=== link:#sbom_spdx__matches_image[Matches image]

Expand Down
6 changes: 6 additions & 0 deletions antora/docs/modules/ROOT/pages/release_policy.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Rules included:
* xref:packages/release_cve.adoc#cve__rule_data_provided[CVE checks: Rule data provided]
* xref:packages/release_provenance_materials.adoc#provenance_materials__git_clone_source_matches_provenance[Provenance Materials: Git clone source matches materials provenance]
* xref:packages/release_provenance_materials.adoc#provenance_materials__git_clone_task_found[Provenance Materials: Git clone task found]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__experimental_hermeto_backend[SBOM CycloneDX: Experimental Hermeto backend]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__cdx_supported_version[SBOM CycloneDX: Supported Version]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__valid_cdx_1_4[SBOM CycloneDX: Valid 1.4]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__valid_cdx_1_5[SBOM CycloneDX: Valid 1.5]
Expand All @@ -57,6 +58,7 @@ Rules included:
* xref:packages/release_slsa_source_correlated.adoc#slsa_source_correlated__rule_data_provided[SLSA - Verification model - Source: Rule data provided]
* xref:packages/release_slsa_source_correlated.adoc#slsa_source_correlated__source_code_reference_provided[SLSA - Verification model - Source: Source code reference provided]
* xref:packages/release_slsa_source_correlated.adoc#slsa_source_correlated__attested_source_code_reference[SLSA - Verification model - Source: Source reference]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__experimental_hermeto_backend[SPDX SBOM: Experimental Hermeto backend]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__valid[SPDX SBOM: Valid]
* xref:packages/release_tasks.adoc#tasks__pipeline_has_tasks[Tasks: Pipeline run includes at least one task]
* xref:packages/release_tasks.adoc#tasks__successful_pipeline_tasks[Tasks: Successful pipeline tasks]
Expand Down Expand Up @@ -171,6 +173,7 @@ Rules included:
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__allowed_proxy_urls[SBOM CycloneDX: Allowed proxy URLs]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__disallowed_package_attributes[SBOM CycloneDX: Disallowed package attributes]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__disallowed_package_external_references[SBOM CycloneDX: Disallowed package external references]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__experimental_hermeto_backend[SBOM CycloneDX: Experimental Hermeto backend]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__proxy_metadata_required[SBOM CycloneDX: Proxy metadata required]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__cdx_supported_version[SBOM CycloneDX: Supported Version]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__valid_cdx_1_4[SBOM CycloneDX: Valid 1.4]
Expand Down Expand Up @@ -200,6 +203,7 @@ Rules included:
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__allowed_proxy_urls[SPDX SBOM: Allowed proxy URLs]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__disallowed_package_attributes[SPDX SBOM: Disallowed package attributes]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__disallowed_package_external_references[SPDX SBOM: Disallowed package external references]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__experimental_hermeto_backend[SPDX SBOM: Experimental Hermeto backend]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__proxy_metadata_required[SPDX SBOM: Proxy metadata required]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__valid[SPDX SBOM: Valid]
* xref:packages/release_schedule.adoc#schedule__date_restriction[Schedule related checks: Date Restriction]
Expand Down Expand Up @@ -280,6 +284,7 @@ Rules included:
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__allowed_package_sources[SBOM CycloneDX: Allowed package sources]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__disallowed_package_attributes[SBOM CycloneDX: Disallowed package attributes]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__disallowed_package_external_references[SBOM CycloneDX: Disallowed package external references]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__experimental_hermeto_backend[SBOM CycloneDX: Experimental Hermeto backend]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__cdx_supported_version[SBOM CycloneDX: Supported Version]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__valid_cdx_1_4[SBOM CycloneDX: Valid 1.4]
* xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__valid_cdx_1_5[SBOM CycloneDX: Valid 1.5]
Expand All @@ -302,6 +307,7 @@ Rules included:
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__allowed_package_sources[SPDX SBOM: Allowed package sources]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__disallowed_package_attributes[SPDX SBOM: Disallowed package attributes]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__disallowed_package_external_references[SPDX SBOM: Disallowed package external references]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__experimental_hermeto_backend[SPDX SBOM: Experimental Hermeto backend]
* xref:packages/release_sbom_spdx.adoc#sbom_spdx__valid[SPDX SBOM: Valid]
* xref:packages/release_tasks.adoc#tasks__required_untrusted_task_found[Tasks: All required tasks are from trusted tasks]
* xref:packages/release_tasks.adoc#tasks__data_provided[Tasks: Data provided]
Expand Down
2 changes: 2 additions & 0 deletions antora/docs/modules/ROOT/partials/release_policy_nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
**** xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__allowed_proxy_urls[Allowed proxy URLs]
**** xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__disallowed_package_attributes[Disallowed package attributes]
**** xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__disallowed_package_external_references[Disallowed package external references]
**** xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__experimental_hermeto_backend[Experimental Hermeto backend]
**** xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__proxy_metadata_required[Proxy metadata required]
**** xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__cdx_supported_version[Supported Version]
**** xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__valid_cdx_1_4[Valid 1.4]
Expand Down Expand Up @@ -148,6 +149,7 @@
**** xref:packages/release_sbom_spdx.adoc#sbom_spdx__contains_packages[Contains packages]
**** xref:packages/release_sbom_spdx.adoc#sbom_spdx__disallowed_package_attributes[Disallowed package attributes]
**** xref:packages/release_sbom_spdx.adoc#sbom_spdx__disallowed_package_external_references[Disallowed package external references]
**** xref:packages/release_sbom_spdx.adoc#sbom_spdx__experimental_hermeto_backend[Experimental Hermeto backend]
**** xref:packages/release_sbom_spdx.adoc#sbom_spdx__matches_image[Matches image]
**** xref:packages/release_sbom_spdx.adoc#sbom_spdx__proxy_metadata_required[Proxy metadata required]
**** xref:packages/release_sbom_spdx.adoc#sbom_spdx__valid[Valid]
Expand Down
35 changes: 35 additions & 0 deletions policy/release/sbom_cyclonedx/sbom_cyclonedx.rego
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,41 @@ deny contains result if {
)
}

# METADATA
# title: Experimental Hermeto backend
# description: >-
# Verify that no components in the CycloneDX SBOM were fetched using an
# experimental Hermeto backend. Experimental backends are identified by
# top-level annotations whose text starts with "hermeto:backend:experimental:".
# custom:
# short_name: experimental_hermeto_backend
# failure_msg: Package %s was fetched using experimental Hermeto backend %q
# solution: >-
# Use a supported, non-experimental package manager backend in your build
# process, or request a policy exception.
# collections:
# - minimal
# - redhat
# - redhat_rpms
# effective_on: 2026-08-01T00:00:00Z
deny contains result if {
some s in sbom.cyclonedx_sboms
some annotation in s.annotations
Comment thread
jsmid1 marked this conversation as resolved.
startswith(annotation.text, "hermeto:backend:experimental:")

some subject in annotation.subjects
some component in s.components
component["bom-ref"] == subject

id := object.get(component, "purl", component.name)

result := metadata.result_helper_with_term(
rego.metadata.chain(),
[id, annotation.text],
id,
)
}

_has_distribution_reference(component) if {
some reference in component.externalReferences
reference.type == "distribution"
Expand Down
128 changes: 128 additions & 0 deletions policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -1195,3 +1195,131 @@ test_proxy_metadata_required_cdx_vcs_url_passes if {
with ec.oci.image_tag_refs as []
with data.rule_data as _proxy_rule_data
}

# experimental_hermeto_backend tests

test_experimental_hermeto_backend_cdx_denied if {
expected := {{
"code": "sbom_cyclonedx.experimental_hermeto_backend",
"term": "pkg:golang/example.com/foo@1.0.0",
# regal ignore:line-length
"msg": `Package pkg:golang/example.com/foo@1.0.0 was fetched using experimental Hermeto backend "hermeto:backend:experimental:x-pnpm"`,
}}

att := json.patch(_sbom_1_5_attestation, [
{
"op": "add",
"path": "/statement/predicate/components/-",
"value": _cdx_backend_component("pkg:golang/example.com/foo@1.0.0"),
},
{
"op": "add",
"path": "/statement/predicate/annotations",
"value": [_cdx_backend_annotation("pkg:golang/example.com/foo@1.0.0", "hermeto:backend:experimental:x-pnpm")],
},
])

assertions.assert_equal_results(expected, sbom_cyclonedx.deny) with input.attestations as [att]
with input.image.ref as "registry.local/spam@sha256:1230000000000000000000000000000000000000000000000000000000000123"
with ec.oci.image_referrers as []
with ec.oci.image_tag_refs as []
}

test_experimental_hermeto_backend_cdx_stable_passes if {
att := json.patch(_sbom_1_5_attestation, [
{
"op": "add",
"path": "/statement/predicate/components/-",
"value": _cdx_backend_component("pkg:golang/example.com/foo@1.0.0"),
},
{
"op": "add",
"path": "/statement/predicate/annotations",
"value": [_cdx_backend_annotation("pkg:golang/example.com/foo@1.0.0", "hermeto:backend:gomod")],
},
])

results := sbom_cyclonedx.deny with input.attestations as [att]
with input.image.ref as "registry.local/spam@sha256:1230000000000000000000000000000000000000000000000000000000000123"
with ec.oci.image_referrers as []
with ec.oci.image_tag_refs as []

count({r | some r in results; r.code == "sbom_cyclonedx.experimental_hermeto_backend"}) == 0
}

test_experimental_hermeto_backend_cdx_no_purl_denied if {
expected := {{
"code": "sbom_cyclonedx.experimental_hermeto_backend",
"term": "component-no-purl",
# regal ignore:line-length
"msg": `Package component-no-purl was fetched using experimental Hermeto backend "hermeto:backend:experimental:x-pnpm"`,
}}

att := json.patch(_sbom_1_5_attestation, [
{
"op": "add",
"path": "/statement/predicate/components/-",
"value": _cdx_backend_component_no_purl,
},
{
"op": "add",
"path": "/statement/predicate/annotations",
"value": [_cdx_backend_annotation("component-no-purl-ref", "hermeto:backend:experimental:x-pnpm")],
},
])

assertions.assert_equal_results(expected, sbom_cyclonedx.deny) with input.attestations as [att]
with input.image.ref as "registry.local/spam@sha256:1230000000000000000000000000000000000000000000000000000000000123"
with ec.oci.image_referrers as []
with ec.oci.image_tag_refs as []
}

test_experimental_hermeto_backend_cdx_mixed_annotations if {
expected := {{
"code": "sbom_cyclonedx.experimental_hermeto_backend",
"term": "pkg:golang/example.com/foo@1.0.0",
# regal ignore:line-length
"msg": `Package pkg:golang/example.com/foo@1.0.0 was fetched using experimental Hermeto backend "hermeto:backend:experimental:x-pnpm"`,
}}

att := json.patch(_sbom_1_5_attestation, [
{
"op": "add",
"path": "/statement/predicate/components/-",
"value": _cdx_backend_component("pkg:golang/example.com/foo@1.0.0"),
},
{
"op": "add",
"path": "/statement/predicate/annotations",
"value": [
_cdx_backend_annotation("pkg:golang/example.com/foo@1.0.0", "hermeto:backend:gomod"),
_cdx_backend_annotation("pkg:golang/example.com/foo@1.0.0", "hermeto:backend:experimental:x-pnpm"),
],
},
])

assertions.assert_equal_results(expected, sbom_cyclonedx.deny) with input.attestations as [att]
with input.image.ref as "registry.local/spam@sha256:1230000000000000000000000000000000000000000000000000000000000123"
with ec.oci.image_referrers as []
with ec.oci.image_tag_refs as []
}

_cdx_backend_component(purl) := {
"bom-ref": purl,
"type": "library",
"name": "component",
"purl": purl,
}

_cdx_backend_component_no_purl := {
"bom-ref": "component-no-purl-ref",
"type": "library",
"name": "component-no-purl",
}

_cdx_backend_annotation(subject, text) := {
"subjects": [subject],
"annotator": {"organization": {"name": "red hat"}},
"timestamp": "2026-05-01T12:00:00Z",
"text": text,
}
40 changes: 40 additions & 0 deletions policy/release/sbom_spdx/sbom_spdx.rego
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,51 @@ deny contains result if {
)
}

# METADATA
# title: Experimental Hermeto backend
# description: >-
# Verify that no packages in the SPDX SBOM were fetched using an experimental
# Hermeto backend. Experimental backends are identified by annotations with
# annotator "Tool: hermeto:backend" whose comment starts with
# "hermeto:backend:experimental:".
# custom:
# short_name: experimental_hermeto_backend
# failure_msg: Package %s was fetched using experimental Hermeto backend %q
# solution: >-
# Use a supported, non-experimental package manager backend in your build
# process, or request a policy exception.
# collections:
# - minimal
# - redhat
# - redhat_rpms
# effective_on: 2026-08-01T00:00:00Z
deny contains result if {
some s in sbom.spdx_sboms
some pkg in s.packages

some annotation in pkg.annotations
annotation.annotator == "Tool: hermeto:backend"
startswith(annotation.comment, "hermeto:backend:experimental:")
Comment thread
jsmid1 marked this conversation as resolved.

id := _spdx_package_id(pkg)

result := metadata.result_helper_with_term(
rego.metadata.chain(),
[id, annotation.comment],
id,
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

_package_purl(pkg) := purl if {
purls := [ref.referenceLocator | some ref in pkg.externalRefs; ref.referenceType == "purl"]
purl := purls[0]
} else := ""

_spdx_package_id(pkg) := purl if {
purl := _package_purl(pkg)
purl != ""
} else := pkg.name

# _with_effective_on annotates the result with the item's effective_on attribute. If the item does
# not have the attribute, result is returned unmodified.
_with_effective_on(result, item) := new_result if {
Expand Down
Loading
Loading