-
Notifications
You must be signed in to change notification settings - Fork 56
Add --skip-att-sig-check flag #3267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,7 @@ import ( | |
| "github.com/santhosh-tekuri/jsonschema/v5" | ||
| "github.com/sigstore/cosign/v3/pkg/cosign" | ||
| cosignOCI "github.com/sigstore/cosign/v3/pkg/oci" | ||
| ociremote "github.com/sigstore/cosign/v3/pkg/oci/remote" | ||
| log "github.com/sirupsen/logrus" | ||
| "github.com/spf13/afero" | ||
|
|
||
|
|
@@ -201,9 +202,49 @@ func (a *ApplicationSnapshotImage) ValidateAttestationSignature(ctx context.Cont | |
| return a.parseAttestationsFromBundles(layers) | ||
| } | ||
|
|
||
| // 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) | ||
| } | ||
|
|
||
| // FetchAttestationsWithoutVerification fetches attestations from the registry | ||
| // without performing signature verification. This is used when --skip-att-sig-check | ||
| // is enabled but we still need the attestation data for policy evaluation. | ||
| func (a *ApplicationSnapshotImage) FetchAttestationsWithoutVerification(ctx context.Context) error { | ||
| if trace.IsEnabled() { | ||
| region := trace.StartRegion(ctx, "ec:fetch-attestations-without-verification") | ||
| defer region.End() | ||
| } | ||
|
|
||
| remoteOpts := oci.CreateRemoteOptions(ctx) | ||
| signedEntity, err := ociremote.SignedEntity(a.reference, ociremote.WithRemoteOptions(remoteOpts...)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This calls |
||
| if err != nil { | ||
| return fmt.Errorf("failed to fetch signed entity: %w", err) | ||
| } | ||
|
|
||
| layers, err := signedEntity.Attestations() | ||
| if err != nil { | ||
| return fmt.Errorf("failed to fetch attestations: %w", err) | ||
| } | ||
|
|
||
| // Check if using bundles | ||
| useBundles := a.hasBundles(ctx) | ||
| if useBundles { | ||
| sigs, err := layers.Get() | ||
| if err != nil { | ||
| return fmt.Errorf("failed to get attestation signatures: %w", err) | ||
| } | ||
| return a.parseAttestationsFromBundles(sigs) | ||
| } | ||
|
|
||
| sigs, err := layers.Get() | ||
| if err != nil { | ||
| return fmt.Errorf("failed to get attestation signatures: %w", err) | ||
| } | ||
|
|
||
|
Comment on lines
+231
to
+242
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
sigs, err := layers.Get()
if err != nil {
return fmt.Errorf("failed to get attestation signatures: %%w", err)
}
if useBundles {
return a.parseAttestationsFromBundles(sigs)
}
return a.parseAttestationsFromSignatures(sigs) |
||
| return a.parseAttestationsFromSignatures(sigs) | ||
| } | ||
|
Comment on lines
+211
to
+244
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method has four error paths and a bundle/non-bundle branch, none tested at the unit level. The integration test does not mock this path either, so the fetch silently fails there. Routing through |
||
|
|
||
| func (a *ApplicationSnapshotImage) parseAttestationsFromSignatures(sigs []cosignOCI.Signature) error { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| for _, sig := range sigs { | ||
| att, err := attestation.ProvenanceFromSignature(sig) | ||
| if err != nil { | ||
| return fmt.Errorf("unable to parse untyped provenance: %w", err) | ||
|
|
@@ -212,34 +253,27 @@ func (a *ApplicationSnapshotImage) ValidateAttestationSignature(ctx context.Cont | |
| log.Debugf("Found attestation with predicateType: %s", t) | ||
| switch t { | ||
| case attestation.PredicateSLSAProvenance: | ||
| // SLSAProvenanceFromSignature does the payload extraction | ||
| // and decoding that was done in ProvenanceFromSignature | ||
| // over again. We could refactor so we're not doing that twice, | ||
| // but it's not super important IMO. | ||
| // SLSAProvenanceFromSignature re-does the payload extraction from | ||
| // ProvenanceFromSignature. Could be deduplicated but not important. | ||
| sp, err := attestation.SLSAProvenanceFromSignature(sig) | ||
| if err != nil { | ||
| return fmt.Errorf("unable to parse as SLSA v0.2: %w", err) | ||
| } | ||
| a.attestations = append(a.attestations, sp) | ||
|
|
||
| case attestation.PredicateSLSAProvenanceV1: | ||
| // SLSA Provenance v1.0 | ||
| sp, err := attestation.SLSAProvenanceFromSignatureV1(sig) | ||
| if err != nil { | ||
| return fmt.Errorf("unable to parse as SLSA v1: %w", err) | ||
| } | ||
| a.attestations = append(a.attestations, sp) | ||
|
|
||
| case attestation.PredicateSpdxDocument: | ||
| // It's an SPDX format SBOM | ||
| // Todo maybe: We could unmarshal it into a suitable SPDX struct | ||
| // similar to how it's done for SLSA above | ||
| a.attestations = append(a.attestations, att) | ||
|
|
||
| // Todo: CycloneDX format SBOM | ||
|
|
||
| default: | ||
| // It's some other kind of attestation | ||
| a.attestations = append(a.attestations, att) | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The attestation here is signed with the correct key, so the skip flag is redundant. The
--skip-image-sig-checkhas a companion scenario at line 214 with an invalid signature that proves the flag is needed. An equivalent scenario with a wrong attestation key would catch a regression that silently ignores this flag.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was being lazy here main to satisfy Codecov stats. 😅