-
Notifications
You must be signed in to change notification settings - Fork 54
feat(EC-1957): verify base image release signatures #1780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,9 +32,10 @@ Rules included: | |
| * xref:packages/release_attestation_type.adoc#attestation_type__known_attestation_type[Attestation type: Known attestation type found] | ||
| * xref:packages/release_attestation_type.adoc#attestation_type__known_attestation_types_provided[Attestation type: Known attestation types provided] | ||
| * xref:packages/release_attestation_type.adoc#attestation_type__pipelinerun_attestation_found[Attestation type: PipelineRun attestation found] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__allowed_registries_provided[Base image checks: Allowed base image registry prefixes list was provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__allowed_registries_provided[Base image checks: Allowed base image registry prefixes list or release public key was provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__base_image_permitted[Base image checks: Base image comes from permitted registry] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__base_image_info_found[Base image checks: Base images provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__registry_prefix_deprecated[Base image checks: Registry prefix matching is deprecated] | ||
| * xref:packages/release_cve.adoc#cve__cve_blockers[CVE checks: Blocking CVE check] | ||
| * xref:packages/release_cve.adoc#cve__unpatched_cve_blockers[CVE checks: Blocking unpatched CVE check] | ||
| * xref:packages/release_cve.adoc#cve__cve_results_found[CVE checks: CVE scan results found] | ||
|
|
@@ -75,7 +76,7 @@ Rules included: | |
|
|
||
| * xref:packages/release_maven_repos.adoc#maven_repos__policy_data_missing[All maven artifacts have known repository URLs: Policy data validation] | ||
| * xref:packages/release_attestation_type.adoc#attestation_type__known_attestation_types_provided[Attestation type: Known attestation types provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__allowed_registries_provided[Base image checks: Allowed base image registry prefixes list was provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__allowed_registries_provided[Base image checks: Allowed base image registry prefixes list or release public key was provided] | ||
| * xref:packages/release_buildah_build_task.adoc#buildah_build_task__disallowed_platform_patterns_pattern[Buildah build task: disallowed_platform_patterns format] | ||
| * xref:packages/release_cve.adoc#cve__rule_data_provided[CVE checks: Rule data provided] | ||
| * xref:packages/release_external_parameters.adoc#external_parameters__pipeline_run_params_provided[External parameters: PipelineRun params provided] | ||
|
|
@@ -115,9 +116,10 @@ Rules included: | |
| * xref:packages/release_attestation_type.adoc#attestation_type__known_attestation_type[Attestation type: Known attestation type found] | ||
| * xref:packages/release_attestation_type.adoc#attestation_type__known_attestation_types_provided[Attestation type: Known attestation types provided] | ||
| * xref:packages/release_attestation_type.adoc#attestation_type__pipelinerun_attestation_found[Attestation type: PipelineRun attestation found] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__allowed_registries_provided[Base image checks: Allowed base image registry prefixes list was provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__allowed_registries_provided[Base image checks: Allowed base image registry prefixes list or release public key was provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__base_image_permitted[Base image checks: Base image comes from permitted registry] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__base_image_info_found[Base image checks: Base images provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__registry_prefix_deprecated[Base image checks: Registry prefix matching is deprecated] | ||
| * xref:packages/release_buildah_build_task.adoc#buildah_build_task__add_capabilities_param[Buildah build task: ADD_CAPABILITIES parameter] | ||
| * xref:packages/release_buildah_build_task.adoc#buildah_build_task__buildah_uses_local_dockerfile[Buildah build task: Buildah task uses a local Dockerfile] | ||
| * xref:packages/release_buildah_build_task.adoc#buildah_build_task__platform_param[Buildah build task: PLATFORM parameter] | ||
|
|
@@ -340,9 +342,10 @@ Rules included: | |
| * xref:packages/release_attestation_type.adoc#attestation_type__known_attestation_type[Attestation type: Known attestation type found] | ||
| * xref:packages/release_attestation_type.adoc#attestation_type__known_attestation_types_provided[Attestation type: Known attestation types provided] | ||
| * xref:packages/release_attestation_type.adoc#attestation_type__pipelinerun_attestation_found[Attestation type: PipelineRun attestation found] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__allowed_registries_provided[Base image checks: Allowed base image registry prefixes list was provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__allowed_registries_provided[Base image checks: Allowed base image registry prefixes list or release public key was provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__base_image_permitted[Base image checks: Base image comes from permitted registry] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__base_image_info_found[Base image checks: Base images provided] | ||
| * xref:packages/release_base_image_registries.adoc#base_image_registries__registry_prefix_deprecated[Base image checks: Registry prefix matching is deprecated] | ||
| * xref:packages/release_buildah_build_task.adoc#buildah_build_task__add_capabilities_param[Buildah build task: ADD_CAPABILITIES parameter] | ||
| * xref:packages/release_buildah_build_task.adoc#buildah_build_task__buildah_uses_local_dockerfile[Buildah build task: Buildah task uses a local Dockerfile] | ||
| * xref:packages/release_buildah_build_task.adoc#buildah_build_task__privileged_nested_param[Buildah build task: PRIVILEGED_NESTED parameter] | ||
|
|
@@ -356,8 +359,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] | ||
|
Comment on lines
362
to
+363
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Correct the workflow-reference label. The 🤖 Prompt for AI Agents |
||
| * 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] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,15 +16,14 @@ | |
| import data.lib.sbom | ||
|
|
||
| # METADATA | ||
| # title: Base image comes from permitted registry | ||
| # title: Base image is permitted | ||
| # description: >- | ||
| # Verify that the base images used when building a container image come from a known | ||
| # set of trusted registries to reduce potential supply chain attacks. By default this | ||
| # policy defines trusted registries as registries that are fully maintained by Red | ||
| # Hat and only contain content produced by Red Hat. The list of permitted registries | ||
| # can be customized by setting the `allowed_registry_prefixes` list in the rule data. | ||
| # Base images that are found in the snapshot being validated are also allowed since EC | ||
| # will also validate those images individually. | ||
| # Verify that the base images used when building a container image are permitted. | ||
| # Images can be permitted in three ways: by having a valid release signature | ||
| # verified against the `release_public_key` rule data (preferred), by matching | ||
| # a component digest in the snapshot, or by matching a registry prefix from | ||
| # `allowed_registry_prefixes` rule data (deprecated). Registry prefix matching | ||
| # is deprecated and will be removed in a future release. | ||
| # custom: | ||
| # short_name: base_image_permitted | ||
| # failure_msg: Base image %q is from a disallowed registry | ||
|
|
@@ -74,10 +73,11 @@ | |
| } | ||
|
|
||
| # METADATA | ||
| # title: Allowed base image registry prefixes list was provided | ||
| # title: Allowed base image registry prefixes list or release public key was provided | ||
| # description: >- | ||
| # Confirm the `allowed_registry_prefixes` rule data was provided, since it's | ||
| # required by the policy rules in this package. | ||
| # Confirm that either the `allowed_registry_prefixes` or `release_public_key` | ||
| # rule data was provided, since at least one is required by the policy rules | ||
| # in this package. | ||
| # custom: | ||
| # short_name: allowed_registries_provided | ||
| # failure_msg: "%s" | ||
|
|
@@ -105,6 +105,22 @@ | |
| img := image.parse(component.containerImage) | ||
| } | ||
| image.parse(image_ref).digest in allowed_digests | ||
| } else if { | ||
| key := rule_data.get(_release_key_rule_data_key) | ||
| is_string(key) | ||
| key != "" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [low] configurability ignore_rekor is hardcoded to false in ec.sigstore.verify_image options. This enforces Rekor transparency log verification, which is the correct security default, but prevents use in air-gapped environments where Rekor is unreachable. Suggested fix: Consider adding an optional release_signature_ignore_rekor rule data key in a follow-up to allow operators to disable Rekor verification when needed, similar to how sigstore.opts exposes this setting globally. |
||
| info := ec.sigstore.verify_image(image_ref, {"public_key": key, "ignore_rekor": false}) | ||
| not _has_sig_errors(info) | ||
| } | ||
|
|
||
| _has_sig_errors(info) if { | ||
| some _ in info.errors | ||
| } | ||
|
|
||
| _release_public_key_provided if { | ||
| key := rule_data.get(_release_key_rule_data_key) | ||
| is_string(key) | ||
| key != "" | ||
| } | ||
|
|
||
| _cyclonedx_base_images := [_cyclonedx_image_ref(component) | | ||
|
|
@@ -170,8 +186,8 @@ | |
| image_ref := sbom.image_ref_from_purl(purl) | ||
| } | ||
|
|
||
| # Verify allowed_registry_prefixes is a non-empty list of strings | ||
| _rule_data_errors contains error if { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [low] validation When release_public_key is provided, allowed_registry_prefixes schema validation is skipped entirely. If both are configured and the prefixes are malformed, the configuration error is silently ignored. Suggested fix: Consider validating allowed_registry_prefixes regardless of release_public_key presence, to surface configuration errors even for deprecated fields during the migration period. |
||
| not _release_public_key_provided | ||
| some e in j.validate_schema( | ||
| rule_data.get(_rule_data_key), | ||
| { | ||
|
|
@@ -188,4 +204,27 @@ | |
| } | ||
| } | ||
|
|
||
| _rule_data_errors contains error if { | ||
| prefixes := rule_data.get(_rule_data_key) | ||
| count(prefixes) > 0 | ||
| not _release_public_key_provided | ||
| error := { | ||
| "message": "allowed_registry_prefixes is configured without release_public_key. Migrate to signature-based verification by setting release_public_key in rule data.", | ||
| "severity": "warning", | ||
| } | ||
| } | ||
|
|
||
| _rule_data_errors contains error if { | ||
| val := rule_data.get(_release_key_rule_data_key) | ||
| val != [] | ||
| not is_string(val) | ||
|
Comment on lines
+217
to
+220
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Reject an explicitly empty-array release key.
🤖 Prompt for AI Agents |
||
| msg := sprintf( | ||
| "Rule data %s has unexpected format: expected a string, got %s", | ||
| [_release_key_rule_data_key, type_name(val)], | ||
| ) | ||
| error := {"message": msg, "severity": "failure"} | ||
| } | ||
|
|
||
| _rule_data_key := "allowed_registry_prefixes" | ||
|
|
||
| _release_key_rule_data_key := "release_public_key" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Update all base-image documentation to reflect signature and digest paths.
The policy now accepts
release_public_keyand snapshot digest matches, but these descriptions and labels still direct users toward trusted registry prefixes. This can cause operators to configure the deprecated mechanism or misunderstand failures.antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc#L12-L16: documentrelease_public_keyin the solution, not only registry prefixes.antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc#L24-L28: rename the rule/title and solution so they cover registry, digest, and signature verification.antora/docs/modules/ROOT/pages/release_policy.adoc#L35-L38: update the minimal ruleset’s permitted-image label.antora/docs/modules/ROOT/pages/release_policy.adoc#L119-L122: update the redhat ruleset’s permitted-image label.antora/docs/modules/ROOT/pages/release_policy.adoc#L345-L348: update the redhat_security ruleset’s permitted-image label.antora/docs/modules/ROOT/partials/release_policy_nav.adoc#L22-L26: update the navigation label consistently.📍 Affects 3 files
antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc#L12-L16(this comment)antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc#L24-L28antora/docs/modules/ROOT/pages/release_policy.adoc#L35-L38antora/docs/modules/ROOT/pages/release_policy.adoc#L119-L122antora/docs/modules/ROOT/pages/release_policy.adoc#L345-L348antora/docs/modules/ROOT/partials/release_policy_nav.adoc#L22-L26🤖 Prompt for AI Agents