From ddd21abddfeda7d21bce32f21f744159d8fad858 Mon Sep 17 00:00:00 2001 From: jstuart Date: Thu, 29 Oct 2026 12:23:10 -0500 Subject: [PATCH 1/2] fix(sbom): revert Hermeto attribution requirement Remove the CycloneDX and SPDX attribution rules added in EC-2016 because inherited base-image dependencies can trigger false violations. Remove the unused rule data, validation, tests, and generated documentation while preserving other Hermeto policies. Ref: https://redhat.atlassian.net/browse/EC-2224 Assisted-by: Codex --- .../packages/release_sbom_cyclonedx.adoc | 13 -- .../pages/packages/release_sbom_spdx.adoc | 13 -- .../modules/ROOT/pages/release_policy.adoc | 6 - .../ROOT/partials/release_policy_nav.adoc | 2 - policy/lib/rule_data/rule_data.rego | 5 - policy/lib/sbom/sbom.rego | 17 -- policy/release/sbom/sbom_test.rego | 27 --- .../sbom_cyclonedx/sbom_cyclonedx.rego | 45 ----- .../sbom_cyclonedx/sbom_cyclonedx_test.rego | 158 ---------------- policy/release/sbom_spdx/sbom_spdx.rego | 48 ----- policy/release/sbom_spdx/sbom_spdx_test.rego | 173 ------------------ 11 files changed, 507 deletions(-) diff --git a/antora/docs/modules/ROOT/pages/packages/release_sbom_cyclonedx.adoc b/antora/docs/modules/ROOT/pages/packages/release_sbom_cyclonedx.adoc index 66eec0ff3..5d11f427b 100644 --- a/antora/docs/modules/ROOT/pages/packages/release_sbom_cyclonedx.adoc +++ b/antora/docs/modules/ROOT/pages/packages/release_sbom_cyclonedx.adoc @@ -97,19 +97,6 @@ Verify that no components in the CycloneDX SBOM were fetched using an experiment * Effective from: `2026-08-01T00:00:00Z` * https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/sbom_cyclonedx/sbom_cyclonedx.rego#L400[Source, window="_blank"] -[#sbom_cyclonedx__hermeto_attribution_required] -=== link:#sbom_cyclonedx__hermeto_attribution_required[Hermeto attribution required] - -Registry dependencies with a PURL type listed in vendored_purl_types must be processed by Hermeto. When a hermetic build omits prefetch-input for a vendored ecosystem, Hermeto never runs and the SBOM contains only Syft-reported module-level data, which is insufficient for CVE analysis. This rule denies any such component that lacks the hermeto:found_by (or cachi2:found_by) property. - -*Solution*: Set the prefetch-input pipeline parameter to the Hermeto package manager name for the ecosystem (e.g. "gomod" for pkg:golang, "cargo" for pkg:cargo) so Hermeto processes the project's dependencies during the prefetch-dependencies task. - -* Rule type: [rule-type-indicator failure]#FAILURE# -* FAILURE message: `Package %s has PURL type %q which requires Hermeto attribution but was not processed by Hermeto` -* Code: `sbom_cyclonedx.hermeto_attribution_required` -* Effective from: `2027-01-15T00:00:00Z` -* https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/sbom_cyclonedx/sbom_cyclonedx.rego#L435[Source, window="_blank"] - [#sbom_cyclonedx__proxy_metadata_required] === link:#sbom_cyclonedx__proxy_metadata_required[Proxy metadata required] diff --git a/antora/docs/modules/ROOT/pages/packages/release_sbom_spdx.adoc b/antora/docs/modules/ROOT/pages/packages/release_sbom_spdx.adoc index d32c4ca73..43033427c 100644 --- a/antora/docs/modules/ROOT/pages/packages/release_sbom_spdx.adoc +++ b/antora/docs/modules/ROOT/pages/packages/release_sbom_spdx.adoc @@ -121,19 +121,6 @@ Verify that no packages in the SPDX SBOM were fetched using an experimental Herm * Effective from: `2026-08-01T00:00:00Z` * https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/sbom_spdx/sbom_spdx.rego#L373[Source, window="_blank"] -[#sbom_spdx__hermeto_attribution_required] -=== link:#sbom_spdx__hermeto_attribution_required[Hermeto attribution required] - -Registry dependencies with a PURL type listed in vendored_purl_types must be processed by Hermeto. When a hermetic build omits prefetch-input for a vendored ecosystem, Hermeto never runs and the SBOM contains only Syft-reported module-level data, which is insufficient for CVE analysis. This rule denies any such package that lacks the hermeto:found_by (or cachi2:found_by) annotation. - -*Solution*: Set the prefetch-input pipeline parameter to the Hermeto package manager name for the ecosystem (e.g. "gomod" for pkg:golang, "cargo" for pkg:cargo) so Hermeto processes the project's dependencies during the prefetch-dependencies task. - -* Rule type: [rule-type-indicator failure]#FAILURE# -* FAILURE message: `Package %s has PURL type %q which requires Hermeto attribution but was not processed by Hermeto` -* Code: `sbom_spdx.hermeto_attribution_required` -* Effective from: `2027-01-15T00:00:00Z` -* https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/sbom_spdx/sbom_spdx.rego#L408[Source, window="_blank"] - [#sbom_spdx__matches_image] === link:#sbom_spdx__matches_image[Matches image] diff --git a/antora/docs/modules/ROOT/pages/release_policy.adoc b/antora/docs/modules/ROOT/pages/release_policy.adoc index 4c06f19dd..4cae08dcf 100644 --- a/antora/docs/modules/ROOT/pages/release_policy.adoc +++ b/antora/docs/modules/ROOT/pages/release_policy.adoc @@ -92,7 +92,6 @@ 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__hermeto_attribution_required[SBOM CycloneDX: Hermeto attribution required] * xref:packages/release_sbom_cyclonedx.adoc#sbom_cyclonedx__proxy_metadata_required[SBOM CycloneDX: Proxy metadata required] * xref:packages/release_sbom.adoc#sbom__disallowed_packages_provided[SBOM: Disallowed packages list is provided] * xref:packages/release_slsa_build_build_service.adoc#slsa_build_build_service__allowed_builder_ids_provided[SLSA - Build - Build Service: Allowed builder IDs provided] @@ -103,7 +102,6 @@ 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__hermeto_attribution_required[SPDX SBOM: Hermeto attribution required] * xref:packages/release_sbom_spdx.adoc#sbom_spdx__proxy_metadata_required[SPDX SBOM: Proxy metadata required] * xref:packages/release_schedule.adoc#schedule__rule_data_provided[Schedule related checks: Rule data provided] * xref:packages/release_tasks.adoc#tasks__data_provided[Tasks: Data provided] @@ -182,7 +180,6 @@ Rules included: * 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__hermeto_attribution_required[SBOM CycloneDX: Hermeto attribution required] * 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] @@ -215,7 +212,6 @@ Rules included: * 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__hermeto_attribution_required[SPDX SBOM: Hermeto attribution required] * 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] @@ -426,7 +422,6 @@ 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__hermeto_attribution_required[SBOM CycloneDX: Hermeto attribution required] * 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] @@ -460,7 +455,6 @@ Rules included: * xref:packages/release_sbom_spdx.adoc#sbom_spdx__contains_packages[SPDX SBOM: Contains packages] * 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__hermeto_attribution_required[SPDX SBOM: Hermeto attribution required] * xref:packages/release_sbom_spdx.adoc#sbom_spdx__matches_image[SPDX SBOM: Matches image] * 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] diff --git a/antora/docs/modules/ROOT/partials/release_policy_nav.adoc b/antora/docs/modules/ROOT/partials/release_policy_nav.adoc index abaae103e..117347e71 100644 --- a/antora/docs/modules/ROOT/partials/release_policy_nav.adoc +++ b/antora/docs/modules/ROOT/partials/release_policy_nav.adoc @@ -120,7 +120,6 @@ **** 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__hermeto_attribution_required[Hermeto attribution required] **** 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] @@ -158,7 +157,6 @@ **** 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__hermeto_attribution_required[Hermeto attribution required] **** 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] diff --git a/policy/lib/rule_data/rule_data.rego b/policy/lib/rule_data/rule_data.rego index 133e54186..cd3d9cd7a 100644 --- a/policy/lib/rule_data/rule_data.rego +++ b/policy/lib/rule_data/rule_data.rego @@ -165,11 +165,6 @@ defaults := { # e.g., {"maven": ["^https://maven-proxy\\.example\\.com/.*"]} "allowed_proxy_url_patterns": {}, # - # Used in release/sbom_cyclonedx and release/sbom_spdx - # PURL types for ecosystems where vendoring is possible and Hermeto attribution is required - # Current supported vendored types: ["golang", "cargo"] - "vendored_purl_types": ["golang", "cargo"], - # # Used in release/lib/attestations.rego # Allowed provenance buildTypes for PipelineRun attestations (both SLSA v0.2 and v1) "allowed_provenance_build_types": [ diff --git a/policy/lib/sbom/sbom.rego b/policy/lib/sbom/sbom.rego index 56b2bca8b..ad6d375bb 100644 --- a/policy/lib/sbom/sbom.rego +++ b/policy/lib/sbom/sbom.rego @@ -427,23 +427,6 @@ rule_data_errors contains error if { } } -# Verify vendored_purl_types is a list of unique strings. -rule_data_errors contains error if { - some e in j.validate_schema( - rule_data.get("vendored_purl_types"), - { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "array", - "items": {"type": "string"}, - "uniqueItems": true, - }, - ) - error := { - "message": sprintf("Rule data vendored_purl_types has unexpected format: %s", [e.message]), - "severity": e.severity, - } -} - # Verify allowed_proxy_url_patterns is an object mapping strings to arrays of strings. rule_data_errors contains error if { some e in j.validate_schema( diff --git a/policy/release/sbom/sbom_test.rego b/policy/release/sbom/sbom_test.rego index a3d41455f..8f20dac05 100644 --- a/policy/release/sbom/sbom_test.rego +++ b/policy/release/sbom/sbom_test.rego @@ -391,33 +391,6 @@ test_proxy_rule_data_validation if { with data.rule_data as d_bad_regex } -test_vendored_purl_types_rule_data_validation if { - # Valid data - no errors - assertions.assert_empty(sbom.deny) with input.attestations as _sbom_attestation - with lib.sbom._verified_sbom_attestations as _sbom_attestation - with data.rule_data as {"vendored_purl_types": ["golang", "cargo"]} - - # Invalid vendored_purl_types: wrong type and duplicate - d_bad := {"vendored_purl_types": [1, "golang", "golang"]} - expected_bad := { - { - "code": "sbom.disallowed_packages_provided", - # regal ignore:line-length - "msg": "Rule data vendored_purl_types has unexpected format: 0: Invalid type. Expected: string, given: integer", - "severity": "failure", - }, - { - "code": "sbom.disallowed_packages_provided", - # regal ignore:line-length - "msg": "Rule data vendored_purl_types has unexpected format: (Root): array items[1,2] must be unique", - "severity": "failure", - }, - } - assertions.assert_equal_results(expected_bad, sbom.deny) with input.attestations as _sbom_attestation - with lib.sbom._verified_sbom_attestations as _sbom_attestation - with data.rule_data as d_bad -} - test_anchoring_warnings_external_references if { d := { lib.sbom.rule_data_allowed_external_references_key: [ diff --git a/policy/release/sbom_cyclonedx/sbom_cyclonedx.rego b/policy/release/sbom_cyclonedx/sbom_cyclonedx.rego index 68ff6f880..a7461968b 100644 --- a/policy/release/sbom_cyclonedx/sbom_cyclonedx.rego +++ b/policy/release/sbom_cyclonedx/sbom_cyclonedx.rego @@ -432,51 +432,6 @@ deny contains result if { ) } -# METADATA -# title: Hermeto attribution required -# description: >- -# Registry dependencies with a PURL type listed in vendored_purl_types must -# be processed by Hermeto. When a hermetic build omits prefetch-input for a -# vendored ecosystem, Hermeto never runs and the SBOM contains only -# Syft-reported module-level data, which is insufficient for CVE analysis. -# This rule denies any such component that lacks the hermeto:found_by (or -# cachi2:found_by) property. -# custom: -# short_name: hermeto_attribution_required -# failure_msg: >- -# Package %s has PURL type %q which requires Hermeto attribution but was -# not processed by Hermeto -# solution: >- -# Set the prefetch-input pipeline parameter to the Hermeto package manager -# name for the ecosystem (e.g. "gomod" for pkg:golang, "cargo" for -# pkg:cargo) so Hermeto processes the project's dependencies during the -# prefetch-dependencies task. -# collections: -# - redhat -# - policy_data -# - redhat_security -# effective_on: 2027-01-15T00:00:00Z -deny contains result if { - vendored := {t | some t in rule_data.get("vendored_purl_types")} - - some s in sbom.cyclonedx_sboms - some component in s.components - - purl := component.purl - parsed_purl := ec.purl.parse(purl) - parsed_purl.type in vendored - - sbom.is_registry_dependency(parsed_purl, component) - - not sbom.component_found_by_hermeto(component) - - result := metadata.result_helper_with_term( - rego.metadata.chain(), - [purl, parsed_purl.type], - purl, - ) -} - _has_distribution_reference(component) if { some reference in component.externalReferences reference.type == "distribution" diff --git a/policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego b/policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego index 8662090d7..95ef43df4 100644 --- a/policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego +++ b/policy/release/sbom_cyclonedx/sbom_cyclonedx_test.rego @@ -753,7 +753,6 @@ assert_allowed(purl, disallowed_packages) if { with ec.oci.image_referrers as [] # regal ignore:with-outside-test-context with ec.oci.image_tag_refs as [] # regal ignore:with-outside-test-context with data.rule_data.disallowed_packages as disallowed_packages # regal ignore:with-outside-test-context - with data.rule_data.vendored_purl_types as [] # regal ignore:with-outside-test-context } assert_not_allowed(purl, disallowed_packages) if { @@ -773,7 +772,6 @@ assert_not_allowed(purl, disallowed_packages) if { with ec.oci.image_referrers as [] # regal ignore:with-outside-test-context with ec.oci.image_tag_refs as [] # regal ignore:with-outside-test-context with data.rule_data.disallowed_packages as disallowed_packages # regal ignore:with-outside-test-context - with data.rule_data.vendored_purl_types as [] # regal ignore:with-outside-test-context } _sbom_1_5_attestation := {"statement": { @@ -1325,7 +1323,6 @@ test_experimental_hermeto_backend_cdx_denied if { with input.image.ref as "registry.local/spam@sha256:1230000000000000000000000000000000000000000000000000000000000123" with ec.oci.image_referrers as [] with ec.oci.image_tag_refs as [] - with data.rule_data.vendored_purl_types as [] } test_experimental_hermeto_backend_cdx_stable_passes if { @@ -1408,163 +1405,8 @@ test_experimental_hermeto_backend_cdx_mixed_annotations if { with input.image.ref as "registry.local/spam@sha256:1230000000000000000000000000000000000000000000000000000000000123" with ec.oci.image_referrers as [] with ec.oci.image_tag_refs as [] - with data.rule_data.vendored_purl_types as [] } -# hermeto_attribution_required tests - -test_hermeto_attribution_required_cdx_with_hermeto_passes if { - att := json.patch(_sbom_1_5_attestation, [{ - "op": "add", - "path": "/statement/predicate/components/-", - "value": _cdx_vendored_component("pkg:golang/example.com/lib@1.0", true), - }]) - - assertions.assert_empty(sbom_cyclonedx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _vendored_rule_data -} - -test_hermeto_attribution_required_cdx_without_hermeto_denied if { - expected := {{ - "code": "sbom_cyclonedx.hermeto_attribution_required", - "term": "pkg:golang/example.com/lib@1.0", - # regal ignore:line-length - "msg": `Package pkg:golang/example.com/lib@1.0 has PURL type "golang" which requires Hermeto attribution but was not processed by Hermeto`, - }} - - att := json.patch(_sbom_1_5_attestation, [{ - "op": "add", - "path": "/statement/predicate/components/-", - "value": _cdx_vendored_component("pkg:golang/example.com/lib@1.0", false), - }]) - - assertions.assert_equal_results(expected, sbom_cyclonedx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _vendored_rule_data -} - -test_hermeto_attribution_required_cdx_mixed if { - expected := {{ - "code": "sbom_cyclonedx.hermeto_attribution_required", - "term": "pkg:golang/example.com/bad@2.0", - # regal ignore:line-length - "msg": `Package pkg:golang/example.com/bad@2.0 has PURL type "golang" which requires Hermeto attribution but was not processed by Hermeto`, - }} - - att := json.patch(_sbom_1_5_attestation, [ - { - "op": "add", - "path": "/statement/predicate/components/-", - "value": _cdx_vendored_component("pkg:golang/example.com/good@1.0", true), - }, - { - "op": "add", - "path": "/statement/predicate/components/-", - "value": _cdx_vendored_component("pkg:golang/example.com/bad@2.0", false), - }, - ]) - - assertions.assert_equal_results(expected, sbom_cyclonedx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _vendored_rule_data -} - -test_hermeto_attribution_required_cdx_unconfigured_type_passes if { - att := json.patch(_sbom_1_5_attestation, [{ - "op": "add", - "path": "/statement/predicate/components/-", - "value": _cdx_vendored_component("pkg:npm/example-lib@2.0", false), - }]) - - assertions.assert_empty(sbom_cyclonedx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _vendored_rule_data -} - -test_hermeto_attribution_required_cdx_local_dep_passes if { - att := json.patch(_sbom_1_5_attestation, [{ - "op": "add", - "path": "/statement/predicate/components/-", - "value": _cdx_vendored_component("pkg:golang/example.com/lib@1.0?vcs_url=https://github.com/example/lib.git", false), - }]) - - assertions.assert_empty(sbom_cyclonedx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _vendored_rule_data -} - -test_hermeto_attribution_required_cdx_empty_rule_data_passes if { - att := json.patch(_sbom_1_5_attestation, [{ - "op": "add", - "path": "/statement/predicate/components/-", - "value": _cdx_vendored_component("pkg:golang/example.com/lib@1.0", false), - }]) - - assertions.assert_empty(sbom_cyclonedx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as {"vendored_purl_types": []} -} - -test_hermeto_attribution_required_cdx_cargo_denied if { - expected := {{ - "code": "sbom_cyclonedx.hermeto_attribution_required", - "term": "pkg:cargo/serde@1.0.0", - # regal ignore:line-length - "msg": `Package pkg:cargo/serde@1.0.0 has PURL type "cargo" which requires Hermeto attribution but was not processed by Hermeto`, - }} - - att := json.patch(_sbom_1_5_attestation, [{ - "op": "add", - "path": "/statement/predicate/components/-", - "value": _cdx_vendored_component("pkg:cargo/serde@1.0.0", false), - }]) - - assertions.assert_equal_results(expected, sbom_cyclonedx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _vendored_rule_data -} - -_cdx_vendored_component(purl, with_hermeto) := component if { - with_hermeto == true - component := { - "type": "library", - "name": "component", - "purl": purl, - "properties": [{"name": "hermeto:found_by", "value": "hermeto"}], - } -} else := component if { - component := { - "type": "library", - "name": "component", - "purl": purl, - "properties": [], - } -} - -_vendored_rule_data := {"vendored_purl_types": ["golang", "cargo"]} - _cdx_backend_component(purl) := { "bom-ref": purl, "type": "library", diff --git a/policy/release/sbom_spdx/sbom_spdx.rego b/policy/release/sbom_spdx/sbom_spdx.rego index ca32d5961..41e08525f 100644 --- a/policy/release/sbom_spdx/sbom_spdx.rego +++ b/policy/release/sbom_spdx/sbom_spdx.rego @@ -405,54 +405,6 @@ deny contains result if { ) } -# METADATA -# title: Hermeto attribution required -# description: >- -# Registry dependencies with a PURL type listed in vendored_purl_types must -# be processed by Hermeto. When a hermetic build omits prefetch-input for a -# vendored ecosystem, Hermeto never runs and the SBOM contains only -# Syft-reported module-level data, which is insufficient for CVE analysis. -# This rule denies any such package that lacks the hermeto:found_by (or -# cachi2:found_by) annotation. -# custom: -# short_name: hermeto_attribution_required -# failure_msg: >- -# Package %s has PURL type %q which requires Hermeto attribution but was -# not processed by Hermeto -# solution: >- -# Set the prefetch-input pipeline parameter to the Hermeto package manager -# name for the ecosystem (e.g. "gomod" for pkg:golang, "cargo" for -# pkg:cargo) so Hermeto processes the project's dependencies during the -# prefetch-dependencies task. -# collections: -# - redhat -# - policy_data -# - redhat_security -# effective_on: 2027-01-15T00:00:00Z -deny contains result if { - vendored := {t | some t in rule_data.get("vendored_purl_types")} - - some s in sbom.spdx_sboms - some pkg in s.packages - - some externalref in pkg.externalRefs - externalref.referenceType == "purl" - - purl := externalref.referenceLocator - parsed_purl := ec.purl.parse(purl) - parsed_purl.type in vendored - - sbom.is_registry_dependency(parsed_purl, pkg) - - not sbom.package_found_by_hermeto(pkg) - - result := metadata.result_helper_with_term( - rego.metadata.chain(), - [purl, parsed_purl.type], - purl, - ) -} - _package_purl(pkg) := purl if { purls := [ref.referenceLocator | some ref in pkg.externalRefs; ref.referenceType == "purl"] purl := purls[0] diff --git a/policy/release/sbom_spdx/sbom_spdx_test.rego b/policy/release/sbom_spdx/sbom_spdx_test.rego index 09a794f65..eef9684b5 100644 --- a/policy/release/sbom_spdx/sbom_spdx_test.rego +++ b/policy/release/sbom_spdx/sbom_spdx_test.rego @@ -117,7 +117,6 @@ assert_allowed(purl, disallowed_packages) if { assertions.assert_empty(sbom_spdx.deny) with input.attestations as [att] # regal ignore:with-outside-test-context with sbom._verified_sbom_attestations as [att] with data.rule_data.disallowed_packages as disallowed_packages # regal ignore:with-outside-test-context - with data.rule_data.vendored_purl_types as [] # 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 [] # regal ignore:with-outside-test-context } @@ -139,7 +138,6 @@ assert_not_allowed(purl, disallowed_packages) if { with ec.oci.image_referrers as [] # regal ignore:with-outside-test-context with ec.oci.image_tag_refs as [] # regal ignore:with-outside-test-context with data.rule_data.disallowed_packages as disallowed_packages # regal ignore:with-outside-test-context - with data.rule_data.vendored_purl_types as [] # regal ignore:with-outside-test-context } test_external_references_allowed_regex_with_no_rules_is_allowed if { @@ -1183,177 +1181,6 @@ _spdx_backend_package_mixed(purl) := { "checksums": [{"algorithm": "SHA256", "checksumValue": "abc123"}], } -# hermeto_attribution_required tests - -test_hermeto_attribution_required_spdx_with_hermeto_passes if { - att := json.patch(_sbom_attestation, [{ - "op": "add", - "path": "/statement/predicate/packages/-", - "value": _spdx_vendored_package("pkg:golang/example.com/lib@1.0", true), - }]) - - assertions.assert_empty(sbom_spdx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _spdx_vendored_rule_data -} - -test_hermeto_attribution_required_spdx_without_hermeto_denied if { - expected := {{ - "code": "sbom_spdx.hermeto_attribution_required", - "term": "pkg:golang/example.com/lib@1.0", - # regal ignore:line-length - "msg": `Package pkg:golang/example.com/lib@1.0 has PURL type "golang" which requires Hermeto attribution but was not processed by Hermeto`, - }} - - att := json.patch(_sbom_attestation, [{ - "op": "add", - "path": "/statement/predicate/packages/-", - "value": _spdx_vendored_package("pkg:golang/example.com/lib@1.0", false), - }]) - - assertions.assert_equal_results(expected, sbom_spdx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _spdx_vendored_rule_data -} - -test_hermeto_attribution_required_spdx_mixed if { - expected := {{ - "code": "sbom_spdx.hermeto_attribution_required", - "term": "pkg:golang/example.com/bad@2.0", - # regal ignore:line-length - "msg": `Package pkg:golang/example.com/bad@2.0 has PURL type "golang" which requires Hermeto attribution but was not processed by Hermeto`, - }} - - att := json.patch(_sbom_attestation, [ - { - "op": "add", - "path": "/statement/predicate/packages/-", - "value": _spdx_vendored_package("pkg:golang/example.com/good@1.0", true), - }, - { - "op": "add", - "path": "/statement/predicate/packages/-", - "value": _spdx_vendored_package("pkg:golang/example.com/bad@2.0", false), - }, - ]) - - assertions.assert_equal_results(expected, sbom_spdx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _spdx_vendored_rule_data -} - -test_hermeto_attribution_required_spdx_unconfigured_type_passes if { - att := json.patch(_sbom_attestation, [{ - "op": "add", - "path": "/statement/predicate/packages/-", - "value": _spdx_vendored_package("pkg:npm/example-lib@2.0", false), - }]) - - assertions.assert_empty(sbom_spdx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _spdx_vendored_rule_data -} - -test_hermeto_attribution_required_spdx_local_dep_passes if { - att := json.patch(_sbom_attestation, [{ - "op": "add", - "path": "/statement/predicate/packages/-", - "value": _spdx_vendored_package("pkg:golang/example.com/lib@1.0?vcs_url=https://github.com/example/lib.git", false), - }]) - - assertions.assert_empty(sbom_spdx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _spdx_vendored_rule_data -} - -test_hermeto_attribution_required_spdx_empty_rule_data_passes if { - att := json.patch(_sbom_attestation, [{ - "op": "add", - "path": "/statement/predicate/packages/-", - "value": _spdx_vendored_package("pkg:golang/example.com/lib@1.0", false), - }]) - - assertions.assert_empty(sbom_spdx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as {"vendored_purl_types": []} -} - -test_hermeto_attribution_required_spdx_cargo_denied if { - expected := {{ - "code": "sbom_spdx.hermeto_attribution_required", - "term": "pkg:cargo/serde@1.0.0", - # regal ignore:line-length - "msg": `Package pkg:cargo/serde@1.0.0 has PURL type "cargo" which requires Hermeto attribution but was not processed by Hermeto`, - }} - - att := json.patch(_sbom_attestation, [{ - "op": "add", - "path": "/statement/predicate/packages/-", - "value": _spdx_vendored_package("pkg:cargo/serde@1.0.0", false), - }]) - - assertions.assert_equal_results(expected, sbom_spdx.deny) with input.attestations as [att] - with sbom._verified_sbom_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 [] - with data.rule_data as _spdx_vendored_rule_data -} - -_spdx_vendored_package(purl, with_hermeto) := pkg if { - with_hermeto == true - pkg := { - "name": "vendored-package", - "SPDXID": "SPDXRef-vendored-package", - "downloadLocation": "NOASSERTION", - "externalRefs": [{ - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "purl", - "referenceLocator": purl, - }], - "annotations": [{ - "annotator": "Tool: hermeto:jsonencoded", - "comment": "{\"name\":\"hermeto:found_by\",\"value\":\"hermeto\"}", - "annotationDate": "2024-12-09T12:00:00Z", - "annotationType": "OTHER", - }], - "checksums": [{"algorithm": "SHA256", "checksumValue": "abc123"}], - } -} else := pkg if { - pkg := { - "name": "vendored-package", - "SPDXID": "SPDXRef-vendored-package", - "downloadLocation": "NOASSERTION", - "externalRefs": [{ - "referenceCategory": "PACKAGE-MANAGER", - "referenceType": "purl", - "referenceLocator": purl, - }], - "annotations": [], - "checksums": [{"algorithm": "SHA256", "checksumValue": "abc123"}], - } -} - -_spdx_vendored_rule_data := {"vendored_purl_types": ["golang", "cargo"]} - _spdx_backend_package(purl, backend_annotation) := { "name": "backend-package", "SPDXID": "SPDXRef-backend-package", From 597cf672ab4914723af9721c34dccc4a8e95b63e Mon Sep 17 00:00:00 2001 From: jstuart Date: Thu, 29 Oct 2026 13:17:44 -0500 Subject: [PATCH 2/2] docs(policy): retain generated rule index order Keep the index order produced by make generate-docs so the CI clean-tree check passes after the EC-2224 rollback. Ref: https://redhat.atlassian.net/browse/EC-2224 Assisted-by: Codex --- antora/docs/modules/ROOT/pages/release_policy.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/antora/docs/modules/ROOT/pages/release_policy.adoc b/antora/docs/modules/ROOT/pages/release_policy.adoc index 4cae08dcf..80f5ea36b 100644 --- a/antora/docs/modules/ROOT/pages/release_policy.adoc +++ b/antora/docs/modules/ROOT/pages/release_policy.adoc @@ -372,8 +372,8 @@ Rules included: * xref:packages/release_git_branch.adoc#git_branch__git_branch[Git branch checks: Builds have a trusted target branch] * xref:packages/release_github_certificate.adoc#github_certificate__gh_workflow_extensions[GitHub Certificate Checks: GitHub Workflow Certificate Extensions] * xref:packages/release_github_certificate.adoc#github_certificate__gh_workflow_name[GitHub Certificate Checks: GitHub Workflow Name] -* xref:packages/release_github_certificate.adoc#github_certificate__gh_workflow_ref[GitHub Certificate Checks: GitHub Workflow Repository] * xref:packages/release_github_certificate.adoc#github_certificate__gh_workflow_repository[GitHub Certificate Checks: GitHub Workflow Repository] +* xref:packages/release_github_certificate.adoc#github_certificate__gh_workflow_ref[GitHub Certificate Checks: GitHub Workflow Repository] * xref:packages/release_github_certificate.adoc#github_certificate__gh_workflow_trigger[GitHub Certificate Checks: GitHub Workflow Trigger] * xref:packages/release_github_certificate.adoc#github_certificate__rule_data_provided[GitHub Certificate Checks: Rule data provided] * xref:packages/release_hermetic_task.adoc#hermetic_task__hermetic[Hermetic task: Task called with hermetic param set]