Skip to content

ART-21572: Add doozer verify-signatures command for image signed check - #3162

Open
tomasdavidorg wants to merge 4 commits into
openshift-eng:mainfrom
tomasdavidorg:ART-21572
Open

ART-21572: Add doozer verify-signatures command for image signed check#3162
tomasdavidorg wants to merge 4 commits into
openshift-eng:mainfrom
tomasdavidorg:ART-21572

Conversation

@tomasdavidorg

@tomasdavidorg tomasdavidorg commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

rh-pre-commit.version: 2.4.0
rh-pre-commit.check-secrets: ENABLED

Summary by CodeRabbit

  • New Features
    • Added a verify-release-signatures CLI pipeline to verify release image signatures across selected architectures, with optional dev/prod sigstore mirror checks.
    • Added human-readable and JSON output showing overall PASS/FAIL and per-architecture mirror status.
    • Exposed signature verification as a public, importable entry point.
  • Bug Fixes
    • Improved signature checking by using dedicated sigstore mirror probing and refactoring legacy verification logic for clearer pass/fail handling.
  • Tests
    • Added end-to-end tests covering digest lookup failures, missing/invalid signatures, mirror-disabled behavior, error propagation, and both output formats.

@tomasdavidorg tomasdavidorg added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 15, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 15, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 15, 2026

Copy link
Copy Markdown

@tomasdavidorg: This pull request references ART-21572 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the sub-task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

…igned Check step

rh-pre-commit.version: 2.4.0
rh-pre-commit.check-secrets: ENABLED

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 15, 2026
@openshift-ci

openshift-ci Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign jupierce for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

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

Adds a verify-release-signatures CLI pipeline that retrieves release image digests, checks signatures on configured mirrors per architecture, renders JSON or text results, and exits unsuccessfully when verification fails. Signature mirror probing is shared with legacy verification.

Changes

Release signature verification

Layer / File(s) Summary
Verification contracts and mirror probing
pyartcd/pyartcd/pipelines/verify_release_signatures.py, pyartcd/pyartcd/signatory.py, pyartcd/tests/pipelines/test_verify_release_signatures.py
Defines verification result models and centralizes sigstore mirror probing, with tests for status handling and result evaluation.
Pipeline execution and output
pyartcd/pyartcd/pipelines/verify_release_signatures.py, pyartcd/tests/pipelines/test_verify_release_signatures.py
Retrieves architecture-specific digests, checks enabled mirrors, aggregates errors, renders JSON or text, and registers the CLI command with execution-failure handling.
Public pipeline wiring
pyartcd/pyartcd/__main__.py, pyartcd/pyartcd/pipelines/__init__.py
Imports and exports the new pipeline through the package and main module.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant VerifyReleaseSignaturesPipeline
  participant get_image_info
  participant SigstoreSignatory
  participant SignatureMirror
  CLI->>VerifyReleaseSignaturesPipeline: run release verification
  VerifyReleaseSignaturesPipeline->>get_image_info: retrieve image digest
  get_image_info-->>VerifyReleaseSignaturesPipeline: return digest
  VerifyReleaseSignaturesPipeline->>SigstoreSignatory: check enabled mirror
  SigstoreSignatory->>SignatureMirror: probe signature files
  SignatureMirror-->>SigstoreSignatory: return HTTP status
  SigstoreSignatory-->>VerifyReleaseSignaturesPipeline: return mirror result
  VerifyReleaseSignaturesPipeline-->>CLI: render PASS or FAIL result
Loading
🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
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.
No-Weak-Crypto ✅ Passed Touched files only use SHA256 digest paths; no MD5/SHA1/weak ciphers, custom crypto, or secret/token comparisons were introduced.
Container-Privileges ✅ Passed HEAD commit only changes pyartcd/pyartcd/signatory.py; no container/K8s manifests or privilege settings (privileged, hostPID, allowPrivilegeEscalation, SYS_ADMIN) were introduced.
No-Sensitive-Data-In-Logs ✅ Passed No new log statements expose secrets/PII/internal hostnames; added logs only mention pullspecs, digests, and public mirror URLs.
No-Hardcoded-Secrets ✅ Passed PASS: Targeted scans of the touched files found no hardcoded secrets, credentialed URLs, or long base64 blobs; only a sha256 digest literal in a docstring.
No-Injection-Vectors ✅ Passed No SQL/shell/eval/pickle/yaml/os.system/dangerous DOM sink appears in the new pipeline or signatory changes; URL building uses aiohttp and constants only.
Ai-Attribution ✅ Passed No explicit AI-tool mention or AI attribution trailers appear in the PR-range commits or description, so no Assisted-by/Generated-by trailer was required.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: adding a verify-signatures command for image signature checking.
✨ 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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
pyartcd/tests/pipelines/test_verify_release_signatures.py (1)

104-169: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the "no digest" and "no mirrors checked" branches.

run() (per the upstream snippet) has an if not digest: branch that appends an error when digest lookup returns a falsy value without raising, and a path where neither check_dev_mirror nor check_prod_mirror is set (leaving an arch result with no mirror flags). Neither is exercised here; only the exception-raising digest failure (test_digest_failure) and dual-mirror-checked (test_all_pass, test_mixed_results) paths are tested.

🤖 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 `@pyartcd/tests/pipelines/test_verify_release_signatures.py` around lines 104 -
169, Add tests in TestPipeline covering a falsy digest returned by
get_digest_for_pullspec, asserting run() fails and records the expected error,
and covering both check_dev_mirror and check_prod_mirror disabled, asserting the
architecture result has no mirror flags while preserving the resulting
pass/failure behavior defined by run().
🤖 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 `@pyartcd/pyartcd/pipelines/verify_release_signatures.py`:
- Around line 105-117: Update the mirror-check logic in run() so each awaited
SigstoreSignatory.check_signature_on_mirror call is independently wrapped in
error handling. On timeout or client failure, append the exception to
result.errors and continue processing the remaining mirror checks and
architectures, preserving normal success and missing-signature logging.

In `@pyartcd/pyartcd/signatory.py`:
- Around line 667-674: Update check_signature_on_mirror so a 404 response
returns False only when no signature has been found, while non-404 non-200
statuses—including 429 and 5xx responses—raise an appropriate HTTP error.
Preserve the existing success behavior for 200 responses and the sig iteration
flow.

---

Nitpick comments:
In `@pyartcd/tests/pipelines/test_verify_release_signatures.py`:
- Around line 104-169: Add tests in TestPipeline covering a falsy digest
returned by get_digest_for_pullspec, asserting run() fails and records the
expected error, and covering both check_dev_mirror and check_prod_mirror
disabled, asserting the architecture result has no mirror flags while preserving
the resulting pass/failure behavior defined by run().
🪄 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: Repository: openshift-eng/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cc9b17e5-dd5f-4963-b1ce-701ec2e53f66

📥 Commits

Reviewing files that changed from the base of the PR and between e56ceaa and 49f474e.

📒 Files selected for processing (5)
  • pyartcd/pyartcd/__main__.py
  • pyartcd/pyartcd/pipelines/__init__.py
  • pyartcd/pyartcd/pipelines/verify_release_signatures.py
  • pyartcd/pyartcd/signatory.py
  • pyartcd/tests/pipelines/test_verify_release_signatures.py

Comment thread pyartcd/pyartcd/pipelines/verify_release_signatures.py Outdated
Comment thread pyartcd/pyartcd/signatory.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@pyartcd/pyartcd/signatory.py`:
- Around line 667-681: Update the signature lookup flow around the aiohttp
request to probe numbered signature files sequentially rather than hard-coding
only signature-1. Return true when any numbered signature exists, return false
only after all supported candidates are absent, and preserve the existing
unexpected-status error handling.

In `@pyartcd/tests/pipelines/test_verify_release_signatures.py`:
- Around line 118-119: Update the test around
SigstoreSignatory.check_signature_on_mirror to assert
aiohttp.ClientResponseError instead of the broad Exception type, while
preserving the existing call and asynchronous assertion behavior.
🪄 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: Repository: openshift-eng/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6d410767-c7d0-493e-a1de-709db28ee4a4

📥 Commits

Reviewing files that changed from the base of the PR and between 49f474e and 40b1b9b.

📒 Files selected for processing (3)
  • pyartcd/pyartcd/pipelines/verify_release_signatures.py
  • pyartcd/pyartcd/signatory.py
  • pyartcd/tests/pipelines/test_verify_release_signatures.py

Comment thread pyartcd/pyartcd/signatory.py Outdated
Comment thread pyartcd/tests/pipelines/test_verify_release_signatures.py Outdated
@tomasdavidorg tomasdavidorg added the tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. label Jul 24, 2026
@tomasdavidorg
tomasdavidorg force-pushed the ART-21572 branch 2 times, most recently from a6c3ef5 to 235bb51 Compare July 29, 2026 12:23
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

rh-pre-commit.version: 2.4.0
rh-pre-commit.check-secrets: ENABLED
@tomasdavidorg tomasdavidorg changed the title ART-21572: Create artcd verify_release_signatures command for Image S… ART-21572: Add doozer verify-signatures command for image signed check Jul 30, 2026
rh-pre-commit.version: 2.4.0
rh-pre-commit.check-secrets: ENABLED
…ify-signatures

Resolve release name from runtime.assembly and default arches from
group config, consistent with verify-image-grades pattern.

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

rh-pre-commit.version: 2.4.0
rh-pre-commit.check-secrets: ENABLED
Both dev and prod mirror signature checks are now on by default,
matching what a release verification should cover.

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

rh-pre-commit.version: 2.4.0
rh-pre-commit.check-secrets: ENABLED
@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@tomasdavidorg: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/security 7c24cc9 link false /test security

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants