Skip to content

Add --skip-att-sig-check flag#3267

Open
simonbaird wants to merge 2 commits into
conforma:mainfrom
simonbaird:skip-att-sig-check
Open

Add --skip-att-sig-check flag#3267
simonbaird wants to merge 2 commits into
conforma:mainfrom
simonbaird:skip-att-sig-check

Conversation

@simonbaird
Copy link
Copy Markdown
Member

@simonbaird simonbaird commented Apr 28, 2026

Implement --skip-att-sig-check flag to skip attestation signature validation checks, mirroring the existing --skip-image-sig-check flag. When enabled, attestation signature verification is bypassed during image validation.

Why? Often I'm debugging/troubleshooting something and I get given an image ref to look at. We can use cosign download attestation to inspect the attestation, which is very useful, but if we want to try running Conforma against it, we must either guess, find, or ask to be provided with the public key. Sometimes that's not so difficult, but other times it may be very difficult or even impossible. (Consider for example if the image was built on an ephemeral cluster and the signing secret used is gone forever.)

Now we can use --skip-image-sig-check and --skip-att-sig-check and carry on with the debugging. Note that we added the --skip-image-sig-check recently for other reasons, see https://redhat.atlassian.net/browse/EC-1647. The
--skip-att-sig-check is perhaps a little more complicated because we need to add a function that can download the attestation without verifying it.

The argument against this is that it may encourage less secure practices, but I would say it's acceptable because we're not changing the default behavior, which is always to require signature verification.

Ref: https://redhat.atlassian.net/browse/EC-1815

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

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

Adds a configurable --skip-att-sig-check CLI flag wired into policy options, implements a verification-free attestation fetch path, conditions image validation on the flag, and updates unit and integration tests plus docs and feature scenario.

Changes

Attestation signature verification skip flag

Layer / File(s) Summary
Policy interface and configuration
internal/policy/policy.go, internal/policy/policy_test.go
Adds SkipAttSigCheck() bool to Policy, skipAttSigCheck to policy, SkipAttSigCheck to Options, wires option into NewPolicy, and tests default/true behavior.
CLI flag and documentation
cmd/validate/image.go, docs/modules/ROOT/pages/ec_validate_image.adoc
Adds --skip-att-sig-check flag, stores value in imageData.skipAttSigCheck, wires into policy.Options.SkipAttSigCheck during PreRunE, and documents the option (default: false).
Attestation fetching without verification
internal/evaluation_target/application_snapshot_image/application_snapshot_image.go, internal/evaluation_target/application_snapshot_image/application_snapshot_image_test.go
Adds ociremote import and FetchAttestationsWithoutVerification(ctx), chooses bundle vs signature parsing, updates parseAttestationsFromSignatures predicate handling for SLSA v0.2/v1/SPDX/unknown, and adds unit test TestParseAttestationsFromSignatures.
Image validation conditional logic
internal/image/validate.go, internal/image/validate_test.go
ValidateImage branches on policy.SkipAttSigCheck(): when true, calls fetch-without-verification and records the attestation check result; when false, runs standard validation. Tests verify presence/absence of AttestationSignatureCheck.Result and inclusion in Violations()/Successes().
End-to-end feature scenario
features/validate_image.feature
Adds "happy day with skip-att-sig-check flag" scenario that runs validation with the flag and expects builtin.attestation.signature_check omitted from success output.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and concisely describes the main change: adding a new CLI flag for skipping attestation signature verification.
Description check ✅ Passed The description provides clear context about the feature, its motivation, and implementation approach, all directly related to the changeset.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@simonbaird
Copy link
Copy Markdown
Member Author

Making it a draft because it has no Jira (yet anyway).

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

❌ Patch coverage is 69.09091% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/utils/oci/client.go 58.82% 7 Missing ⚠️
internal/utils/oci/fake/client.go 0.00% 6 Missing ⚠️
...ation_snapshot_image/application_snapshot_image.go 69.23% 4 Missing ⚠️
Flag Coverage Δ
acceptance 53.53% <71.42%> (+0.05%) ⬆️
generative 16.94% <0.00%> (-0.07%) ⬇️
integration 27.91% <5.45%> (-0.09%) ⬇️
unit 69.02% <40.00%> (-0.15%) ⬇️

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

Files with missing lines Coverage Δ
cmd/validate/image.go 91.21% <100.00%> (+0.06%) ⬆️
internal/image/validate.go 72.18% <100.00%> (+1.76%) ⬆️
internal/policy/policy.go 91.74% <100.00%> (+0.07%) ⬆️
...ation_snapshot_image/application_snapshot_image.go 84.98% <69.23%> (-0.85%) ⬇️
internal/utils/oci/fake/client.go 0.00% <0.00%> (ø)
internal/utils/oci/client.go 57.03% <58.82%> (+0.27%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@simonbaird simonbaird force-pushed the skip-att-sig-check branch from 8d30082 to a77249d Compare May 7, 2026 20:52
@simonbaird
Copy link
Copy Markdown
Member Author

This isn't in the sprint currently, so maybe review it only after you reviewed everything else.

@simonbaird simonbaird force-pushed the skip-att-sig-check branch from a77249d to 767ffe0 Compare May 14, 2026 18:35
@simonbaird simonbaird marked this pull request as ready for review May 14, 2026 19:17
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/evaluation_target/application_snapshot_image/application_snapshot_image.go (1)

280-314: ⚡ Quick win

Deduplicate attestation parsing to avoid behavior drift

Line 280 through Line 314 duplicates the non-bundle parsing path from ValidateAttestationSignature. A future change in one path can silently desync the other and produce inconsistent attestation handling.

🤖 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
`@internal/evaluation_target/application_snapshot_image/application_snapshot_image.go`
around lines 280 - 314, This block duplicates the non-bundle attestation parsing
logic found in ValidateAttestationSignature; extract the parsing/appending logic
into a single helper (or call the existing ValidateAttestationSignature parsing
routine) so both paths use the same code path: for each signature from
layers.Get() call the shared function that runs ProvenanceFromSignature,
switches on PredicateType and converts to SLSA v0.2/v1 or generic attestation
via SLSAProvenanceFromSignature, SLSAProvenanceFromSignatureV1 and appends the
result to a.attestations; remove the duplicated switch in the current loop and
replace it with a call to that helper to avoid divergence.
🤖 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 `@internal/image/validate.go`:
- Around line 87-90: The attestation fetch error is being suppressed in the
validation path; change the behavior in the block that calls
a.FetchAttestationsWithoutVerification(ctx) so that instead of only logging and
continuing (the log.Debugf("Failed to fetch attestations without verification:
%v", err) path) you return or propagate a wrapped error to abort this
component's validation; locate the call to
a.FetchAttestationsWithoutVerification and replace the silent-continue with an
immediate return of the error (or fmt.Errorf/Wrap with context) so callers see
the registry fetch failure.

---

Nitpick comments:
In
`@internal/evaluation_target/application_snapshot_image/application_snapshot_image.go`:
- Around line 280-314: This block duplicates the non-bundle attestation parsing
logic found in ValidateAttestationSignature; extract the parsing/appending logic
into a single helper (or call the existing ValidateAttestationSignature parsing
routine) so both paths use the same code path: for each signature from
layers.Get() call the shared function that runs ProvenanceFromSignature,
switches on PredicateType and converts to SLSA v0.2/v1 or generic attestation
via SLSAProvenanceFromSignature, SLSAProvenanceFromSignatureV1 and appends the
result to a.attestations; remove the duplicated switch in the current loop and
replace it with a call to that helper to avoid divergence.
🪄 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: 1da8673f-6dfe-44f1-a84d-a6396b58f8cb

📥 Commits

Reviewing files that changed from the base of the PR and between 3743934 and 767ffe0.

📒 Files selected for processing (5)
  • cmd/validate/image.go
  • docs/modules/ROOT/pages/ec_validate_image.adoc
  • internal/evaluation_target/application_snapshot_image/application_snapshot_image.go
  • internal/image/validate.go
  • internal/policy/policy.go

Comment thread internal/image/validate.go
@github-actions github-actions Bot added size: XL and removed size: M labels May 18, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
internal/evaluation_target/application_snapshot_image/application_snapshot_image_test.go (1)

1158-1231: ⚡ Quick win

Add malformed DSSE payload coverage for the unverified parsing path.

This test only covers happy paths. Since --skip-att-sig-check relies on parsing unverified attestations, add at least one malformed DSSE/base64/statement case to lock down failure behavior and prevent regressions in this security-sensitive path.

internal/image/validate_test.go (1)

746-750: ⚡ Quick win

Assert VerifyImageAttestations call behavior for skip vs non-skip.

The test checks output shaping, but not whether attestation verification was actually bypassed. Add explicit mock call assertions so the flag contract is enforced (called when false, not called when true).

Suggested assertion pattern
 			output, err := ValidateImage(ctx, comp, snap, updatedPolicy, evaluators, false)

 			require.NoError(t, err)
 			require.NotNil(t, output)
+
+			if tt.skipAttSigCheck {
+				fakeClient.AssertNotCalled(t, "VerifyImageAttestations", refNoTag, mock.Anything)
+			} else {
+				fakeClient.AssertCalled(t, "VerifyImageAttestations", refNoTag, mock.Anything)
+			}

Also applies to: 783-826

🤖 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 `@internal/image/validate_test.go` around lines 746 - 750, Add explicit mock
expectations in the test around the VerifyImageAttestations (and similarly
VerifyImageSignatures) calls so the skip flag contract is enforced: when the
skip-attestations flag is false assert
fakeClient.AssertCalled/AssertNumberOfCalls for
VerifyImageAttestations(refNoTag, mock.Anything) (and for VerifyImageSignatures
when relevant), and when the skip flag is true assert fakeClient.AssertNotCalled
for VerifyImageAttestations; apply the same pattern for the other test variants
referenced (around the blocks using fakeClient.On("Head", ref)... and the other
cases in the 783-826 range) to ensure attestations are invoked only when not
skipped.
🤖 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 `@internal/image/validate_test.go`:
- Around line 712-718: This file fails gci import/format checks; run the
repository formatting/import toolchain to reorder and format imports and code in
the test file containing TestValidateImageSkipAttSigCheck and the tests struct,
then re-run gci/static checks to ensure the file is properly formatted before
committing.

---

Nitpick comments:
In `@internal/image/validate_test.go`:
- Around line 746-750: Add explicit mock expectations in the test around the
VerifyImageAttestations (and similarly VerifyImageSignatures) calls so the skip
flag contract is enforced: when the skip-attestations flag is false assert
fakeClient.AssertCalled/AssertNumberOfCalls for
VerifyImageAttestations(refNoTag, mock.Anything) (and for VerifyImageSignatures
when relevant), and when the skip flag is true assert fakeClient.AssertNotCalled
for VerifyImageAttestations; apply the same pattern for the other test variants
referenced (around the blocks using fakeClient.On("Head", ref)... and the other
cases in the 783-826 range) to ensure attestations are invoked only when not
skipped.
🪄 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: 8c50c02f-863b-4993-9b4a-6ed41ef86795

📥 Commits

Reviewing files that changed from the base of the PR and between 767ffe0 and a80cb60.

📒 Files selected for processing (4)
  • internal/evaluation_target/application_snapshot_image/application_snapshot_image.go
  • internal/evaluation_target/application_snapshot_image/application_snapshot_image_test.go
  • internal/image/validate_test.go
  • internal/policy/policy_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/evaluation_target/application_snapshot_image/application_snapshot_image.go

Comment thread internal/image/validate_test.go
@simonbaird simonbaird force-pushed the skip-att-sig-check branch 2 times, most recently from 87f5671 to bc7ed38 Compare May 18, 2026 19:57
@simonbaird
Copy link
Copy Markdown
Member Author

Doing some extra work to get the Codecov check green.

Copy link
Copy Markdown
Contributor

@st3penta st3penta left a comment

Choose a reason for hiding this comment

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

Main concerns: error visibility when the fetch fails in skip mode, the new method bypasses the oci.Client abstraction centralized in #3269, and test coverage for the new code path needs work.

Comment thread internal/image/validate.go
Comment thread internal/image/validate.go
Comment thread internal/image/validate.go Outdated
Comment thread internal/image/validate_test.go
Comment thread features/validate_image.feature Outdated
Comment thread internal/image/validate_test.go Outdated
Comment thread internal/image/validate_test.go
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@internal/image/validate.go`:
- Line 89: The file uses fmt.Errorf in the call to
out.SetAttestationSignatureCheckFromError but does not import the fmt package;
add "fmt" to the import block in internal/image/validate.go so fmt.Errorf can be
resolved (locate the use at
out.SetAttestationSignatureCheckFromError(fmt.Errorf(...)) and update the
imports accordingly).
🪄 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: 5089e64a-4278-4072-8ad6-b64e2ae89fee

📥 Commits

Reviewing files that changed from the base of the PR and between bc7ed38 and 5b6e064.

📒 Files selected for processing (1)
  • internal/image/validate.go

Comment thread internal/image/validate.go
@simonbaird
Copy link
Copy Markdown
Member Author

Got some changes in progress. Will move back to draft while I'm working on them.

@simonbaird simonbaird marked this pull request as draft May 20, 2026 12:59
We're going this already for make feature_%. Use the same technique.

Co-authored-by: Claude Code <noreply@anthropic.com>
@simonbaird simonbaird force-pushed the skip-att-sig-check branch from 5b6e064 to c1a78bc Compare June 3, 2026 19:43
@simonbaird
Copy link
Copy Markdown
Member Author

simonbaird commented Jun 3, 2026

Claude says all the suggestions have been addressed.

It might be true.. 😅

@fullsend-ai-review
Copy link
Copy Markdown

fullsend-ai-review Bot commented Jun 3, 2026

Review

Findings

Low

  • [cryptographic-verification-bypass] internal/image/validate.go:84 — The new --skip-att-sig-check flag allows fetching and processing attestations without cryptographic signature verification. While this is the stated purpose of the PR and mirrors the existing --skip-image-sig-check pattern (defaults to false, emits log.Warn), downstream consumers of the validation output have no programmatic way to distinguish verified from unverified attestations. Consider adding an output field indicating signature verification was skipped.

  • [behavioral-change] internal/image/validate.go:79 — The existing --skip-image-sig-check log message was changed from log.Debug to log.Warn. This is a behavioral change for current users of that flag who filter on log levels. Likely intentional (consistency with the new flag's warning) but worth noting.

  • [test-adequacy] internal/evaluation_target/application_snapshot_image/application_snapshot_image.go:204FetchAttestationsWithoutVerification has integration-level test coverage via TestValidateImageSkipAttSigCheck but no dedicated unit test that mocks the OCI client to exercise error paths and bundle detection independently. The extracted parseAttestationsFromSignatures helper does have direct test coverage via TestParseAttestationsFromSignatures.

Info

  • [both-skip-flags] internal/image/validate.go:89 — When both --skip-image-sig-check and --skip-att-sig-check are active, all cryptographic verification is disabled. The code correctly warns about this combination. No enforcement prevents it, which is appropriate for a debugging tool.

  • [naming-convention] cmd/validate/image.go:502 — The att abbreviation in --skip-att-sig-check contrasts with other flags that spell out attestation (e.g., --attestation-format). However, it correctly mirrors the abbreviation pattern of --skip-image-sig-check and maintains internal consistency within the skip-flag family.

Previous run

Review

Findings

Low

  • [test-inadequate] internal/image/validate_test.goTestValidateImageSkipAttSigCheck does not verify that downstream processing (attestation syntax check, policy evaluation) occurs after a successful unverified attestation fetch. All skip-enabled test cases either error or only assert that AttestationSignatureCheck.Result is nil, without verifying the attestation data flows through to evaluation.

  • [missing-test] internal/evaluation_target/application_snapshot_image/application_snapshot_image.goFetchAttestationsWithoutVerification lacks a dedicated unit test. While parseAttestationsFromSignatures is tested directly and the method is covered by integration-level ValidateImage tests and acceptance tests, a unit test would provide targeted coverage for the OCI client interaction and bundle detection paths.

  • [test-weakened] internal/image/validate_test.goTestValidateImageSkipImageSigCheck was refactored to remove output-level assertions that verified violations/successes don't contain builtin.image.signature_check when skipped. The replacement mock assertions (AssertCalled/AssertNotCalled) test method invocation but not output aggregation correctness. This is a reasonable simplification given the new skip-att-sig-check path makes the old "attestation always appears" assertion invalid, but the output-level checks had independent value.

  • [behavioral change] internal/image/validate.go:79 — Log level for "Image signature check skipped" was changed from Debug to Warn. This is a sensible improvement (warning about skipped security checks is appropriate), but it's an undocumented behavioral change that may surface unexpected log output for existing --skip-image-sig-check users.

  • [design-smell] internal/image/validate.go:80 — When --skip-att-sig-check is used, attestations are fetched and parsed without any cryptographic verification, then fed directly into OPA policy evaluation. This is the intended design and mirrors --skip-image-sig-check, but the combined use of both flags disables all cryptographic verification. The warning logs are appropriate and the secure-by-default (flags default to false) is correct.

Info

  • [edge-case] internal/image/validate.go:89 — When SkipAttSigCheck is true and FetchAttestationsWithoutVerification succeeds, SetAttestationSignatureCheckFromError is never called, leaving AttestationSignatureCheck with Passed=false and Result=nil. This is consistent with how SkipImageSigCheck behaves and is handled correctly by downstream code that guards on Result != nil.
Previous run (2)

Review

Findings

Medium

  • [audit-gap] internal/image/validate.go:84-93 — When --skip-att-sig-check is active and attestation fetch succeeds, the AttestationSignatureCheck output field is never populated — Passed defaults to false (Go zero value) and Result is nil. This means the JSON output contains no machine-parseable record that attestation signature verification was deliberately skipped. The only indication is a stderr warning log. When combined with --skip-image-sig-check, all cryptographic verification is disabled with no trace in the structured output. While this is consistent with the existing --skip-image-sig-check pattern (which also leaves ImageSignatureCheck.Result nil), downstream consumers (CI gates, audit systems) inspecting the result may incorrectly interpret a nil result as "not applicable" rather than "deliberately bypassed."
    See also: [logic-error] finding at this location (correctness dimension).

Low

  • [nil-deref] internal/utils/oci/client.go:145FetchAttestationLayers calls signedEntity.Attestations() and then immediately calls layers.Get(). If the cosign library returns (nil, nil) from Attestations() (e.g., when no attestation tag or referrer exists for the image), layers.Get() will panic with a nil pointer dereference. The existing VerifyImageAttestations path handles this internally within cosign's code, but this new raw SignedEntity path bypasses that safety.
    Remediation: Add a nil check after signedEntity.Attestations() — if layers is nil, return an empty slice and nil error.

  • [data-integrity] internal/evaluation_target/application_snapshot_image/application_snapshot_image.go:210FetchAttestationsWithoutVerification feeds unverified attestation layers into the same parsing pipeline (parseAttestationsFromSignatures/parseAttestationsFromBundles) used by verified attestations. Once parsed, unverified attestations are indistinguishable from verified ones in the a.attestations slice. This is the intended behavior of the flag, but it means an attacker with registry write access could supply arbitrary attestation content that would be evaluated by policy rules as if it were authentic.

  • [test-integrity] internal/image/validate_test.go:574TestValidateImageSkipImageSigCheck was simplified: the fields expectImageSigCheckCall/expectAttSigCheckCall were removed, and the output-level assertions verifying that skipped checks don't appear in violations/successes were replaced with mock-level AssertNotCalled/AssertCalled checks. The mock assertions verify behavior (was the function called?) rather than the output structure (do violations/successes correctly exclude skipped checks). This is a reasonable refactoring to a more direct testing style but covers a narrower aspect of the contract.

Info

  • [behavioral-change] internal/image/validate.go:79 — The log level for "Image signature check skipped" was changed from Debug to Warn. This is a user-visible change — users with --skip-image-sig-check enabled will now see a warning on every run. The acceptance test snapshots confirm this is intentional.

  • [sub-agent-failure] N/A — The intent-coherence, style-conventions, docs-currency, and cross-repo-contracts sub-agents did not return findings: model claude-sonnet-4-5@20250929 unavailable on the deployment. These are sonnet-tier dimensions; opus-tier dimensions (correctness, security) completed successfully.

Previous run (3)

Review

Findings

Low

  • [logic-error] internal/image/validate.go — When --skip-att-sig-check is active and FetchAttestationsWithoutVerification succeeds, SetAttestationSignatureCheckFromError is never called, leaving AttestationSignatureCheck at its zero value (Passed: false, Result: nil). This is consistent with how --skip-image-sig-check handles its skip path (also leaves ImageSignatureCheck at zero value), so it follows the established pattern. However, downstream consumers inspecting the output structure cannot distinguish "verification failed" from "verification was deliberately skipped." Consider introducing an explicit "skipped" state in a follow-up.

  • [edge-case] internal/image/validate.go:79 — The log level for the existing --skip-image-sig-check message was changed from log.Debug to log.Warn. This is a behavioral change to existing functionality bundled with the new feature — users of --skip-image-sig-check will now see this warning in default log output. The change is reasonable (security-relevant skips should be visible), but it is worth noting as an intentional side effect.

Info

  • [scope-exceeded] cmd/validate/image.go — No linked GitHub issue; the PR references an external Jira ticket (EC-1815). The rationale in the PR description is clear and the change is well-scoped, mirroring the existing --skip-image-sig-check pattern. The external reference provides sufficient context.

  • [naming-convention] internal/policy/policy.go — The new SkipAttSigCheck() method follows the existing pattern of SkipImageSigCheck() which also lacks a doc comment. For consistency, neither needs one now, but adding doc comments to both would be a minor improvement in a follow-up.

Comment thread internal/image/validate.go
@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label Jun 3, 2026
@simonbaird simonbaird force-pushed the skip-att-sig-check branch from 79ada71 to e18ba05 Compare June 3, 2026 20:14
@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 Jun 3, 2026
@simonbaird
Copy link
Copy Markdown
Member Author

Claude and I agree that the Covscan number is close enough.

@simonbaird
Copy link
Copy Markdown
Member Author

The [nil-deref] is being fixed. Here are my local agents take on the other items:

  • audit-gap — Valid observation but out of scope for this PR. Both skip flags behave the same way, and introducing a "skipped" status would be a broader change to the output model. Good follow-up item.
  • data-integrity — Intentional by design, no action needed.
  • test-integrity — Fair point but the mock assertions are actually more precise (they verify the right code path ran). The old output-scanning was indirect. I'd leave as-is.

Implement --skip-att-sig-check flag to skip attestation signature
validation checks, mirroring the existing --skip-image-sig-check flag.
When enabled, attestation signature verification is bypassed during
image validation.

Why? Often I'm debugging/troubleshooting something and I get given
an image ref to look at. We can use cosign download attestation to
inspect the attestation, which is very useful, but if we want to try
running Conforma against it, we must either guess, find, or ask to
be provided with the public key. Sometimes that's not so difficult,
but other times it may be very difficult or even impossible.
(Consider for example if the image was built on an ephemeral cluster
and the signing secret used is gone forever.)

Now we can use --skip-image-sig-check and --skip-att-sig-check and
carry on with the debugging. Note that we added the
--skip-image-sig-check recently for other reasons, see
https://redhat.atlassian.net/browse/EC-1647. The
--skip-att-sig-check is a little more complicated because we needed
to add a new function that can download the attestation without
verifying it.

The argument against this is that it may encourage less secure
practices, but I would say it's acceptable because we're not
changing the default behavior, which is always to require signature
verification.

Ref: https://redhat.atlassian.net/browse/EC-1815
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@simonbaird simonbaird force-pushed the skip-att-sig-check branch from e18ba05 to c3eb9ee Compare June 3, 2026 20:43
@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge and removed requires-manual-review Review requires human judgment labels Jun 3, 2026
@simonbaird simonbaird requested a review from st3penta June 3, 2026 21:36
@simonbaird simonbaird marked this pull request as ready for review June 3, 2026 21:36
} else {
out.SetImageSignatureCheckFromError(a.ValidateImageSignature(ctx))
}

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] cryptographic-verification-bypass

The new --skip-att-sig-check flag allows fetching and processing attestations without cryptographic signature verification. Downstream consumers of the validation output have no programmatic way to distinguish verified from unverified attestations.

Suggested fix: Consider adding an output field indicating signature verification was skipped so policy rules can detect and handle unverified attestations.

@@ -76,14 +77,27 @@ func ValidateImage(ctx context.Context, comp app.SnapshotComponent, snap *app.Sn

// Handle image signature validation
if p.SkipImageSigCheck() {
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] behavioral-change

The existing --skip-image-sig-check log message was changed from log.Debug to log.Warn, which is a behavioral change for current users who filter on log levels.

// Extract the signatures from the attestations here in order to also validate that
// the signatures do exist in the expected format.
for _, sig := range layers {
return a.parseAttestationsFromSignatures(layers)
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] test-adequacy

FetchAttestationsWithoutVerification has integration-level test coverage but no dedicated unit test exercising error paths and bundle detection independently.

Suggested fix: Add a unit test for FetchAttestationsWithoutVerification that mocks the OCI client to cover error paths and bundle detection.

@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge and removed ready-for-merge All reviewers approved — ready to merge labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-merge All reviewers approved — ready to merge size: XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants