Skip to content

feat(EC-1957): verify base image release signatures#1780

Draft
joejstuart wants to merge 2 commits into
conforma:mainfrom
joejstuart:EC-1957
Draft

feat(EC-1957): verify base image release signatures#1780
joejstuart wants to merge 2 commits into
conforma:mainfrom
joejstuart:EC-1957

Conversation

@joejstuart

Copy link
Copy Markdown
Contributor

Summary

  • Add signature-based base image verification using ec.sigstore.verify_image() with a release_public_key rule data key
  • Add deprecation warning when allowed_registry_prefixes is configured without release_public_key
  • Guard allowed_registry_prefixes validation so having only release_public_key is sufficient
  • Add rule data validation for release_public_key (must be string when present)
  • Add 8 new tests covering signature verification, deprecation warnings, and validation

Resolves: EC-1957

Test plan

  • make ci passes (1005/1005 tests, 0 lint violations)
  • Review signature verification with a real key against a signed image
  • Verify deprecation warning appears in policy evaluation output

🤖 Generated with Claude Code

…istries

Add a third path in _image_ref_permitted that verifies a base image's
release signature using ec.sigstore.verify_image() with a
release_public_key from rule data. This provides stronger cryptographic
assurance than registry prefix matching.

- Add signature verification clause to _image_ref_permitted
- Relax allowed_registries_provided to pass when only release_public_key
  is configured
- Add deprecation warn rule when prefixes are used without a release key
- Add schema validation for release_public_key (must be a string)
- Update example rule_data.yml with release_public_key entry
- Regenerate docs

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

fullsend-ai-review Bot commented Jul 16, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:11 AM UTC · Completed 2:20 AM UTC
Commit: 87c4a29 · View workflow run →

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: ae45906a-3c8a-4312-b3c9-6a605e04fe16

📥 Commits

Reviewing files that changed from the base of the PR and between 769d8d6 and 8fb2b7f.

📒 Files selected for processing (2)
  • policy/release/base_image_registries/base_image_registries.rego
  • policy/release/base_image_registries/base_image_registries_test.rego
🚧 Files skipped from review as they are similar to previous changes (2)
  • policy/release/base_image_registries/base_image_registries.rego
  • policy/release/base_image_registries/base_image_registries_test.rego

📝 Walkthrough

Walkthrough

Base image release policies now support signature verification through release_public_key, retain digest and registry-prefix checks, validate the new configuration, warn on deprecated prefix matching, and update related examples and documentation.

Changes

Base image signature policy

Layer / File(s) Summary
Signature verification and validation
policy/release/base_image_registries/base_image_registries.rego, example/data/rule_data.yml
Adds release-key configuration, signature-based image permission, key type validation, and warnings for registry-prefix-only configuration.
Policy behavior coverage
policy/release/base_image_registries/base_image_registries_test.rego
Tests successful and failed signature verification, key-only configuration, deprecation warnings, and invalid key types.
Policy documentation and navigation
antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc, antora/docs/modules/ROOT/pages/release_policy.adoc, antora/docs/modules/ROOT/partials/release_policy_nav.adoc
Documents signature verification, updated configuration requirements, deprecated prefix matching, and corresponding ruleset navigation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RuleData
  participant BaseImagePolicy
  participant Sigstore
  participant PolicyResult
  RuleData->>BaseImagePolicy: provide release_public_key
  BaseImagePolicy->>Sigstore: verify image signature
  Sigstore-->>BaseImagePolicy: return verification result
  BaseImagePolicy->>PolicyResult: permit or deny base image
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding base image release signature verification.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the added verification, warnings, and validation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc`:
- Around line 12-16: Update all specified base-image documentation to describe
registry-prefix, snapshot-digest, and release-signature verification. In
antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc lines
12-16, include release_public_key in the solution; in lines 24-28, rename the
rule/title and solution to cover all three verification paths. Update the
permitted-image labels in antora/docs/modules/ROOT/pages/release_policy.adoc
lines 35-38, 119-122, and 345-348, and the corresponding navigation label in
antora/docs/modules/ROOT/partials/release_policy_nav.adoc lines 22-26.

In `@antora/docs/modules/ROOT/pages/release_policy.adoc`:
- Around line 362-363: Update the visible label for the xref targeting
github_certificate__gh_workflow_ref to “GitHub Certificate Checks: GitHub
Workflow Ref”; leave the github_certificate__gh_workflow_repository link label
unchanged.

In `@policy/release/base_image_registries/base_image_registries.rego`:
- Around line 235-238: Update the _rule_data_errors rule to distinguish an
absent release key from a present value before type validation, so an explicitly
provided empty array is rejected as a non-string while a missing key remains
allowed. Validate every present release key value with the existing string
check, and add a regression case covering release_public_key: [].
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 7be5a78f-860d-4e49-8d34-07fcc03095e5

📥 Commits

Reviewing files that changed from the base of the PR and between e562e23 and 769d8d6.

📒 Files selected for processing (6)
  • antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc
  • antora/docs/modules/ROOT/pages/release_policy.adoc
  • antora/docs/modules/ROOT/partials/release_policy_nav.adoc
  • example/data/rule_data.yml
  • policy/release/base_image_registries/base_image_registries.rego
  • policy/release/base_image_registries/base_image_registries_test.rego

Comment on lines +12 to 16
=== link:#base_image_registries__allowed_registries_provided[Allowed base image registry prefixes list or release public key was provided]

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.

*Solution*: Make sure to configure a list of trusted registries as a xref:cli:ROOT:configuration.adoc#_data_sources[data source].

Copy link
Copy Markdown

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_key and 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: document release_public_key in 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-L28
  • antora/docs/modules/ROOT/pages/release_policy.adoc#L35-L38
  • antora/docs/modules/ROOT/pages/release_policy.adoc#L119-L122
  • antora/docs/modules/ROOT/pages/release_policy.adoc#L345-L348
  • antora/docs/modules/ROOT/partials/release_policy_nav.adoc#L22-L26
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc`
around lines 12 - 16, Update all specified base-image documentation to describe
registry-prefix, snapshot-digest, and release-signature verification. In
antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc lines
12-16, include release_public_key in the solution; in lines 24-28, rename the
rule/title and solution to cover all three verification paths. Update the
permitted-image labels in antora/docs/modules/ROOT/pages/release_policy.adoc
lines 35-38, 119-122, and 345-348, and the corresponding navigation label in
antora/docs/modules/ROOT/partials/release_policy_nav.adoc lines 22-26.

Comment on lines 362 to +363
* 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]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the workflow-reference label.

The github_certificate__gh_workflow_ref link is displayed as “GitHub Workflow Repository”; it should say “GitHub Workflow Ref” so the navigation matches its target.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@antora/docs/modules/ROOT/pages/release_policy.adoc` around lines 362 - 363,
Update the visible label for the xref targeting
github_certificate__gh_workflow_ref to “GitHub Certificate Checks: GitHub
Workflow Ref”; leave the github_certificate__gh_workflow_repository link label
unchanged.

Comment on lines +235 to +238
_rule_data_errors contains error if {
val := rule_data.get(_release_key_rule_data_key)
val != []
not is_string(val)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject an explicitly empty-array release key.

release_public_key: [] bypasses this check because val != [] is false, despite being a present non-string value. Distinguish an absent key from a present value, then validate every present value as a string; add a regression case for [].

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@policy/release/base_image_registries/base_image_registries.rego` around lines
235 - 238, Update the _rule_data_errors rule to distinguish an absent release
key from a present value before type validation, so an explicitly provided empty
array is rejected as a non-string while a missing key remains allowed. Validate
every present release key value with the existing string check, and add a
regression case covering release_public_key: [].

@fullsend-ai-review

Copy link
Copy Markdown

Review — approve

Summary

This PR adds signature-based base image verification to the base_image_registries policy package using ec.sigstore.verify_image() with a new release_public_key rule data key. It also introduces a deprecation warning for the allowed_registry_prefixes approach, updates rule data validation so that either mechanism is sufficient, and includes 8 new tests covering the feature end-to-end. Documentation and example data are updated consistently.

Analysis

Correctness — The signature verification logic is structurally sound. The three-branch _image_ref_permitted rule correctly tries prefix matching first, then snapshot digest matching, and falls back to signature verification only when the simpler checks fail. This ordering is efficient and avoids unnecessary network calls. The _has_sig_errors helper correctly checks some _ in info.errors, which evaluates to false on an empty errors array (success) and true when errors are present. The guard not _release_public_key_provided on the first _rule_data_errors correctly allows deployments with only release_public_key configured (no allowed_registry_prefixes). The fail-closed behavior is correct: if ec.sigstore.verify_image returns errors or the built-in itself fails, the entire rule body fails and the image is denied.

Security — The ignore_rekor: false default enforces Rekor transparency log verification, which is the correct security posture for release signing. The public key is retrieved from rule data (which supports k8s:// secret references), keeping key material out of policy source. The _release_public_key_provided helper validates the key is a non-empty string before use. No secrets or credentials are exposed in the diff.

Test adequacy — Eight new tests comprehensively cover: successful signature verification, failed verification, the noop behavior when no key is configured, using only a release key without prefixes, the deprecation warning (presence, absence with key, absence without prefixes), and release_public_key format validation. The mocking approach (with ec.sigstore.verify_image as {"errors": [...]}) is consistent with the existing source_image_test.rego patterns.

Documentation — Antora docs, release policy pages, and nav partials are all updated. The new deprecation rule is documented with its warning message, code, and source link. The example rule_data.yml includes a well-documented release_public_key entry with usage comments.

Observations

ignore_rekor is hardcoded to false (low) — The sigstore options passed to ec.sigstore.verify_image hardcode "ignore_rekor": false. This enforces Rekor transparency log verification, which is a secure default. However, it makes the feature unusable in air-gapped environments where Rekor is not reachable. Consider adding an optional release_signature_ignore_rekor rule data key in a follow-up to provide a configurable escape hatch, similar to how sigstore.opts exposes this setting globally.
File: policy/release/base_image_registries/base_image_registries.rego (line ~139 in the new code)

allowed_registry_prefixes validation is silently skipped when release_public_key is present (low) — The not _release_public_key_provided guard on the first _rule_data_errors rule means that if both release_public_key and a malformed allowed_registry_prefixes are configured, the malformed prefix data is silently accepted without validation errors. This is by design (the prefixes are deprecated), and the malformed entries would harmlessly fail the startswith check without causing safety issues. However, operators may prefer to know about configuration errors even if the deprecated field is being phased out.
File: policy/release/base_image_registries/base_image_registries.rego (line ~217 in the new code)


Labels: PR adds new OPA/Rego policy feature for signature-based base image verification

} else if {
key := rule_data.get(_release_key_rule_data_key)
is_string(key)
key != ""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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.

}

# Verify allowed_registry_prefixes is a non-empty list of strings
_rule_data_errors contains error if {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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.

@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge feature labels Jul 16, 2026
@joejstuart
joejstuart marked this pull request as draft July 16, 2026 02:33
Move the registry prefix deprecation from a standalone warn rule into
_rule_data_errors with warning severity, and rename the deny rule title
to "Base image is permitted" since verification is no longer
registry-specific.

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

fullsend-ai-review Bot commented Jul 16, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 2:58 AM UTC · Ended 2:59 AM UTC
Commit: 87c4a29 · View workflow run →

@joejstuart
joejstuart marked this pull request as ready for review July 16, 2026 02:59
@fullsend-ai-review

Copy link
Copy Markdown

🤖 Review · Started 3:00 AM UTC
Commit: 87c4a29 · View workflow run →

@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
unit-tests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...e/base_image_registries/base_image_registries.rego 100.00% <100.00%> (ø)
...e_image_registries/base_image_registries_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.

@joejstuart
joejstuart marked this pull request as draft July 16, 2026 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature ready-for-merge All reviewers approved — ready to merge size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant