Skip to content

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

Open
joejstuart wants to merge 6 commits into
conforma:mainfrom
joejstuart:EC-1957
Open

feat(EC-1957): verify base image release signatures#1780
joejstuart wants to merge 6 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

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

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 rule-data 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.
Signature and deprecation test coverage
policy/release/base_image_registries/base_image_registries_test.rego
Tests successful and failed signature verification, key-only configuration, deprecation warnings, invalid key types, and Sigstore option handling.
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, design/sigstore-verification.md
Documents updated configuration requirements, deprecated prefix matching, ruleset navigation entries, and Sigstore verification behavior.

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 and concisely summarizes the main change: adding base image release signature verification.
Description check ✅ Passed The description covers the change, testing, and ticket, but it does not follow the template headings and lacks an explicit Why section.
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 thread antora/docs/modules/ROOT/pages/release_policy.adoc Outdated
Comment thread policy/release/base_image_registries/base_image_registries.rego
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [edge-case] policy/release/base_image_registries/base_image_registries.rego:184 — When release_public_key is defined, the schema validation for allowed_registry_prefixes is entirely skipped (the not _release_public_key guard). If a user configures both release_public_key AND a malformed allowed_registry_prefixes (e.g., containing integers or duplicates), the malformed prefixes are silently used without any validation error. The first branch of _image_ref_permitted still iterates over allowed_prefixes and calls startswith, so non-string values would silently fail to match rather than producing a clear validation error.
    Remediation: Consider removing the not _release_public_key guard from the schema validation rule, or adding a separate validation rule that always validates allowed_registry_prefixes format when the list is non-empty, regardless of whether release_public_key is set.

Low

  • [authorization-bypass] policy/release/base_image_registries/base_image_registries.rego:174 — When release_public_key is configured, the first branch of _image_ref_permitted still evaluates allowed_registry_prefixes and permits images based on prefix matching alone, without signature verification. Images matching stale or overly-broad prefix entries are permitted without signature checks. This is the intended backward-compatible migration design (the deprecation warning fires as advisory only), but operators who set both release_public_key and allowed_registry_prefixes may not realize prefix matching silently bypasses signature verification.

  • [test-inadequate] policy/release/base_image_registries/base_image_registries_test.rego:429 — The test test_no_release_key_is_noop does not actually test the ‘no release key’ scenario. It does not override data.rule_data, so the image registry.redhat.io/ubi@sha256:abc passes because it matches the default registry.redhat.io/ prefix, not because the absence of a release key is handled correctly. To genuinely test the no-key scenario, explicitly set with data.rule_data as {"allowed_registry_prefixes": ["registry.redhat.io/"]}.

  • [test-inadequate] example/data/rule_data.yml:36 — Adding release_public_key to the example rule data file changes the test environment for existing tests in the base_image_registries package. Existing tests that don’t mock ec.sigstore.verify_image now implicitly invoke the sigstore built-in for images that fail prefix and snapshot checks. In network-isolated test environments this call fails harmlessly, but the dependency is implicit and undocumented.

  • [input-validation] policy/release/base_image_registries/base_image_registries.rego:213 — The rule data validation for release_public_key checks that the value is a string but does not validate PEM format. A malformed key silently degrades the sigstore verification branch to always-deny without a diagnostic error surfaced through _rule_data_errors. Operators who misconfigure the key would see images denied with ‘disallowed registry’ messages rather than a clear configuration error.

  • [scope-coherence] policy/release/base_image_registries/base_image_registries.rego — The deprecation warning rule ships in the same PR that introduces the feature. Users upgrading to this policy version will immediately get deprecation warnings for their existing, previously-valid allowed_registry_prefixes configuration. Since the warning is advisory only (severity ‘warning’, not ‘failure’), this is a minor concern — but consider gating it behind a future effective_on date so users can adopt the new feature at their own pace.

  • [error-handling-idiom] policy/release/base_image_registries/base_image_registries.rego:199 — The deprecation warning message uses a freeform sentence, while other rule data validation messages in this codebase use the "Rule data %s has unexpected format: ..." pattern with the key name. This is a minor style inconsistency — the deprecation warning is semantically different from a schema validation error, so a different format is defensible.


Labels: PR adds sigstore signature verification feature with documentation updates

Previous run

Review

Findings

Medium

  • [logic error - silent validation bypass] policy/release/base_image_registries/base_image_registries.rego:186 — When release_public_key is configured, the not _release_public_key guard on the schema validation rule for allowed_registry_prefixes causes all validation of the prefix list to be skipped entirely. If both release_public_key and a malformed allowed_registry_prefixes (e.g., [42, true, null]) are configured, no validation error is reported, silently hiding the misconfiguration. The intent is to make prefixes optional when a release key is present, but the guard also suppresses type/uniqueness validation when prefixes ARE provided alongside the key.
    Remediation: Split the rule — enforce minItems: 1 only when not _release_public_key, but always validate type/uniqueness constraints when the prefix list is non-empty.

  • [rule data validation pattern] policy/release/base_image_registries/base_image_registries.rego:213 — The release_public_key validation rule uses manual not is_string(val) type checking and a hand-crafted sprintf error message. Every other _rule_data_errors rule in the codebase (across attestation_type, cve, labels, schedule, trusted_task, etc.) uses j.validate_schema() with a JSON Schema definition, producing consistently formatted messages via the shared _severity helper. The manual approach also necessitates the non-obvious val != [] guard to handle rule_data.get()'s empty-list default for absent keys.
    Remediation: Use j.validate_schema(rule_data.get(_release_key_rule_data_key), {"$schema": "http://json-schema.org/draft-07/schema#", "type": "string", "minLength": 1}) to match established patterns.

Low

  • [constant naming convention] policy/release/base_image_registries/base_image_registries.rego:226 — The constant _release_key_rule_data_key drops "public" from the key name release_public_key it references. Consider _release_public_key_rule_data_key for clarity and consistency with the actual key name.

  • [test adequacy] policy/release/base_image_registries/base_image_registries_test.rego — No test covers the case where ec.sigstore.verify_image errors at runtime (network failure, malformed key) as opposed to returning {"success": false}. A test confirming fail-closed behavior on built-in errors would guard against regressions in this security-critical verification path.

Previous run (2)

Review

Findings

Medium

  • [test integrity] example/data/rule_data.yml:35 — Adding release_public_key to the shared test data file causes all existing tests that do not explicitly mock data.rule_data to have _release_public_key defined. Existing tests like test_disallowed_base_images will now reach the sigstore verification branch and call ec.sigstore.verify_image with a k8s:// secret reference in a no-network test environment (unshare -r -n). While the built-in should return failure (preserving test correctness), this introduces an implicit dependency on graceful failure behavior.
    Remediation: Either remove release_public_key from example/data/rule_data.yml and set it only via with data.rule_data in tests that need it, or mock ec.sigstore.verify_image in existing disallowed-image tests.

  • [architectural coherence] policy/release/base_image_registries/base_image_registries.rego:108 — The sigstore verification call constructs its own options object ({"public_key": _release_public_key, "ignore_rekor": false}) rather than using sigstore.opts from policy/lib/sigstore/sigstore.rego. Every other sigstore call in the codebase (source_image.rego, trust.rego) uses sigstore.opts, which centralizes defaults for certificate identity, OIDC issuer, and Rekor URL. Hardcoding options here creates a second source of truth and means deployments that configure data.config.default_sigstore_opts (e.g., custom rekor_url) will have that configuration silently ignored by this call.
    Remediation: Consider extending sigstore.opts or creating a variant that merges the release public key into the shared opts object.

Low

  • [test integrity] policy/release/base_image_registries/base_image_registries_test.rego:411test_no_release_key_is_noop may not exercise its intended code path if release_public_key is present in the shared test data. The image registry.redhat.io/ubi would match default allowed_registry_prefixes regardless.

  • [edge-case] policy/release/base_image_registries/base_image_registries.rego:113 — An empty string release_public_key passes type validation (it is a string) but is rejected by _release_public_key (key != ""), silently falling back to prefix-only mode with no user feedback.

  • [fail-open] policy/release/base_image_registries/base_image_registries.rego:174 — When release_public_key is configured, the not _release_public_key guard skips all allowed_registry_prefixes schema validation. Malformed prefixes won't match (fail-closed for admission), but data-quality errors are masked.

  • [input validation] policy/release/base_image_registries/base_image_registries.rego:110_release_public_key validates the value is a non-empty string but not its format (PEM block or k8s:// URI). A misconfigured value produces cryptic ec.sigstore.verify_image errors rather than a clear rule data validation message.

  • [scope-creep] design/sigstore-verification.md — Introduces a new design/ directory convention not present in the repository. The content is valuable but the convention is worth acknowledging.

  • [comment-conventions] policy/release/base_image_registries/base_image_registries.rego:182 — The diff removes the descriptive # Verify ... comment that preceded the _rule_data_errors rule. Every other sibling package follows this convention. The two new _rule_data_errors rules also lack comments.

  • [naming-convention] policy/release/base_image_registries/base_image_registries.rego:76 — The METADATA title "Allowed base image registry prefixes list or release public key was provided" is unusually long (77 chars) compared to other titles in the file (20–23 chars). Consider shortening to something like "Base image verification data provided."

Previous run (3)

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

fullsend-ai-review[bot]

This comment was marked as outdated.

@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
…tries

Replace _has_sig_errors helper with direct info.success check via
object.get, matching the pattern used in trust.rego. Consolidate
_release_public_key_provided into _release_public_key to eliminate
duplicate rule_data.get calls.

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

fullsend-ai-review Bot commented Jul 27, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 7:37 PM UTC · Ended 7:41 PM UTC
Commit: 87c4a29 · View workflow run →

@github-actions github-actions Bot added size: XL and removed size: L labels Jul 27, 2026
@joejstuart
joejstuart marked this pull request as ready for review July 27, 2026 19:41
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 27, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 7:42 PM UTC · Ended 7:48 PM UTC
Commit: 87c4a29 · View workflow run →

@qodo-for-conforma

Copy link
Copy Markdown

PR Summary by Qodo

Verify base image release signatures via Sigstore (release_public_key)

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Permit base images via Sigstore signature verification using rule data release_public_key.
• Deprecate registry-prefix allowlisting with a warning when used without a release key.
• Add schema validation and tests for new verification and rule-data behaviors.
Diagram

graph TD
  SBOM[("SBOM inputs")] --> POL["base_image_registries.rego"] --> DEC{"Base image permitted?"} --> DENY["deny results"]
  RD[("Rule data")] --> POL
  POL --> SIG{{"ec.sigstore.verify_image"}} --> DEC
  subgraph Legend
    direction LR
    _data[("Data source")] ~~~ _policy["Policy module"] ~~~ _ext{{"External builtin"}} ~~~ _dec{"Decision"} ~~~ _out["Output"]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make signature verification mandatory (remove prefix path now)
  • ➕ Simplifies policy and removes weaker allowlisting path immediately
  • ➕ Reduces ambiguity about the expected security posture
  • ➖ Breaking change for existing users relying on allowed_registry_prefixes
  • ➖ Forces key distribution/management before migration is feasible
2. Support keyless Sigstore verification (Fulcio identity + Rekor)
  • ➕ Avoids managing a long-lived release public key in rule data
  • ➕ Stronger provenance semantics when identity constraints are available
  • ➖ More complex policy inputs/UX (identity constraints, trust roots)
  • ➖ May not fit environments without keyless infrastructure/requirements
3. Make Rekor usage configurable (ignore_rekor toggle)
  • ➕ Better compatibility for air-gapped environments
  • ➕ Allows incremental rollout if Rekor connectivity is intermittent
  • ➖ More configuration surface area and testing permutations
  • ➖ Risk of users disabling transparency guarantees unintentionally

Recommendation: The PR’s approach (add signature-based verification gated by release_public_key and deprecate prefix allowlisting via warnings) is the best migration strategy because it improves security without breaking existing consumers. Consider a follow-up to make Rekor behavior configurable if air-gapped deployments are a target; otherwise keeping ignore_rekor: false is a sensible secure default.

Files changed (7) +258 / -21

Enhancement (1) +44 / -12
base_image_registries.regoPermit base images via Sigstore signature verification and add rule-data warnings/validation +44/-12

Permit base images via Sigstore signature verification and add rule-data warnings/validation

• Extends '_image_ref_permitted' with a signature verification path using 'ec.sigstore.verify_image()' and 'release_public_key'. Updates rule metadata and relaxes the 'allowed registries provided' rule so 'release_public_key' alone is sufficient; adds a warning when prefixes are configured without a release key and validates 'release_public_key' type.

policy/release/base_image_registries/base_image_registries.rego

Tests (1) +128 / -0
base_image_registries_test.regoAdd coverage for signature verification, deprecation warning, and release_public_key validation +128/-0

Add coverage for signature verification, deprecation warning, and release_public_key validation

• Adds tests for success/failure of signature verification, behavior when only a release key is provided, and deprecation warnings when prefixes are used without a key. Adds negative validation coverage for non-string 'release_public_key'.

policy/release/base_image_registries/base_image_registries_test.rego

Documentation (4) +79 / -9
release_base_image_registries.adocDocument signature-based base image verification and prefix deprecation +15/-3

Document signature-based base image verification and prefix deprecation

• Updates rule descriptions to reflect three base-image permission paths (signature, snapshot digest, registry prefix). Adds a new warning rule section describing the deprecation of 'allowed_registry_prefixes' without 'release_public_key'.

antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc

release_policy.adocWire new base-image rule titles and add deprecation warning to policy index +8/-5

Wire new base-image rule titles and add deprecation warning to policy index

• Renames the referenced base-image rule to include release-key support and adds the new registry-prefix deprecation warning to the rule list. Also fixes an xref ordering/labeling issue in the GitHub certificate section.

antora/docs/modules/ROOT/pages/release_policy.adoc

release_policy_nav.adocAdd navigation entry for registry-prefix deprecation warning +2/-1

Add navigation entry for registry-prefix deprecation warning

• Updates nav labels for the allowed-registries rule and includes a new nav item for the deprecation warning rule.

antora/docs/modules/ROOT/partials/release_policy_nav.adoc

sigstore-verification.mdAdd design note for Sigstore builtin typing pitfalls and safe access patterns +54/-0

Add design note for Sigstore builtin typing pitfalls and safe access patterns

• Introduces documentation explaining the return types of 'ec.sigstore.verify_image/verify_attestation' and why 'object.get()' is used to avoid OPA type-checking limitations. Captures recommended patterns used across the policy repo.

design/sigstore-verification.md

Other (1) +7 / -0
rule_data.ymlAdd example configuration for release_public_key +7/-0

Add example configuration for release_public_key

• Adds a commented example of 'release_public_key' showing both inline PEM and k8s:// secret reference usage, and clarifies that signature verification permits images regardless of registry prefixes.

example/data/rule_data.yml

Captures OPA type system constraints discovered through trial and error
when working with ec.sigstore.verify_image. The built-in's return type
is declared in ec-cli (internal/rego/sigstore/sigstore.go) and is not
visible from ec-policies — understanding it required reading the Go
source in the ec-cli repo. Key finding: direct field access and count()
both fail on the typed return; object.get() is the workaround.

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

qodo-for-conforma Bot commented Jul 27, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 15 rules

Grey Divider


Action required

1. Prefixes unchecked when key set 🐞 Bug ☼ Reliability
Description
When release_public_key is configured, schema validation for allowed_registry_prefixes is
skipped, but the policy still evaluates the prefix-matching path first and includes unguarded
operations like count(prefixes) and startswith(...), which assume correct types. As a result,
malformed rule data (e.g., allowed_registry_prefixes: 42) can trigger runtime/type errors instead
of producing structured validation output even when signature verification is enabled.
Code

policy/release/base_image_registries/base_image_registries.rego[R182-186]

_rule_data_errors contains error if {
+	not _release_public_key
	some e in j.validate_schema(
		rule_data.get(_rule_data_key),
		{
Relevance

⭐⭐ Medium

Team often accepts added rule_data validation (PRs 1574, 1740), but has rejected extra
type-safety/edge-case guards before (PR 1728).

PR-#1574
PR-#1740
PR-#1728

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The change described adds a guard that disables allowed_registry_prefixes schema validation when
_release_public_key is defined, yet _image_ref_permitted still iterates over
allowed_registry_prefixes and applies startswith(image_ref, allowed_prefix), which assumes an
array of string prefixes and can fail or behave unexpectedly with malformed data. Additionally, the
deprecation-warning/validation logic retrieves the raw value via rule_data.get(...) and calls
count(prefixes) > 0 without checking that prefixes is an array, which can cause a Rego
evaluation/type error on non-array inputs; this is contrasted with other policies (e.g., maven
repos) that explicitly guard count() with is_array(...) to avoid runtime failures on malformed
configuration.

policy/release/base_image_registries/base_image_registries.rego[98-111]
policy/release/base_image_registries/base_image_registries.rego[182-198]
policy/lib/rule_data/rule_data.rego[176-202]
policy/release/base_image_registries/base_image_registries.rego[200-208]
policy/release/maven_repos/maven_repos.rego[79-90]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
When `_release_public_key` is set, `allowed_registry_prefixes` is no longer schema-validated, but the policy still evaluates logic that assumes `allowed_registry_prefixes` is an array of strings (including `count(prefixes)` and iterating prefixes with `startswith(...)`). This creates an execution path where malformed rule data (e.g., scalar/object instead of array) can raise runtime/type errors rather than returning a structured validation result, even during migration to signature-based verification.

## Issue Context
- `_image_ref_permitted` uses `some allowed_prefix in allowed_prefixes` and `startswith(image_ref, allowed_prefix)`, which assumes `allowed_prefixes` is an array and each `allowed_prefix` is a string.
- Validation for `allowed_registry_prefixes` is currently gated behind `not _release_public_key`, so legacy prefix configuration may go unchecked when signature verification is enabled.
- The deprecation-warning validation calls `count(prefixes)` on `prefixes := rule_data.get(...)` without a type guard; other repo policies (e.g., maven repos) guard `count()` with `is_array(...)` to avoid runtime failures on malformed configuration.

## Fix Focus Areas
- policy/release/base_image_registries/base_image_registries.rego[98-117]
- policy/release/base_image_registries/base_image_registries.rego[182-198]
- policy/release/base_image_registries/base_image_registries.rego[200-208]
- policy/release/maven_repos/maven_repos.rego[79-90]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Docs warning code mismatch ✓ Resolved 🐞 Bug ≡ Correctness
Description
Documentation claims the deprecation warning emits code
base_image_registries.registry_prefix_deprecated, but the implementation (and tests) emit it under
base_image_registries.allowed_registries_provided, which will mislead users/automation relying on
rule codes.
Code

antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc[R54-57]

+* Rule type: [rule-type-indicator warning]#WARNING#
+* WARNING message: `allowed_registry_prefixes is configured without release_public_key. Migrate to signature-based verification by setting release_public_key in rule data.`
+* Code: `base_image_registries.registry_prefix_deprecated`
+* https://github.com/conforma/policy/blob/{page-origin-refhash}/policy/release/base_image_registries/base_image_registries.rego#L99[Source, window="_blank"]
Relevance

⭐⭐⭐ High

Team has merged multiple “docs must match policy behavior/codes” fixes (e.g., PRs 1387, 1676).

PR-#1387
PR-#1676
PR-#1443

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The docs explicitly list base_image_registries.registry_prefix_deprecated as the warning code,
while the policy/test suite shows the warning is produced under the allowed_registries_provided
rule code.

antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc[47-57]
policy/release/base_image_registries/base_image_registries.rego[75-97]
policy/release/base_image_registries/base_image_registries_test.rego[442-455]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The docs introduce a new warning section that specifies code `base_image_registries.registry_prefix_deprecated`, but the policy emits the warning via the existing `allowed_registries_provided` rule metadata/code.

### Issue Context
Tests assert the warning code is `base_image_registries.allowed_registries_provided`.

### Fix Focus Areas
- antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc[47-57]
- policy/release/base_image_registries/base_image_registries.rego[75-97]
- policy/release/base_image_registries/base_image_registries_test.rego[442-455]

### Suggested change
Pick one:
1) Update docs to use the actual emitted code (`base_image_registries.allowed_registries_provided`) and correct the source line reference.
2) Preferably, emit this warning from a dedicated deny rule with its own METADATA short_name `registry_prefix_deprecated` (and update tests accordingly) so the docs' code is real and stable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread policy/release/base_image_registries/base_image_registries.rego
Comment thread antora/docs/modules/ROOT/pages/packages/release_base_image_registries.adoc Outdated
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 27, 2026

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 7:49 PM UTC · Completed 8:08 PM UTC
Commit: 87c4a29 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 27, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 10:06 PM UTC · Ended 10:07 PM UTC
Commit: 87c4a29 · View workflow run →

Use the shared sigstore.opts config as defaults when building verification
options, with release_public_key overriding via object.union. This ensures
deployments with custom default_sigstore_opts (rekor_url, ignore_rekor, etc.)
have those settings respected by base image verification.

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

fullsend-ai-review Bot commented Jul 27, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 10:08 PM UTC · Completed 10:26 PM UTC
Commit: 87c4a29 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed ready-for-merge All reviewers approved — ready to merge labels Jul 27, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 28, 2026

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 4:53 PM UTC · Completed 5:14 PM UTC
Commit: 87c4a29 · View workflow run →

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature requires-manual-review Review requires human judgment size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant