Skip to content
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

Add support for new bundle specification for attesting/verifying OCI image attestations #3889

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

codysoyland
Copy link
Member

@codysoyland codysoyland commented Sep 25, 2024

Summary

This PR adds support for the new Cosign Bundle Specification in cosign attest and cosign verify-attestation.

Related: #3139

To test, run the following (replacing MY_IDENTITY, MY_ISSUER, MY_TRUSTED_ROOT and MY_IMAGE as needed -- trusted root is optional). Note that the new OCI support requires passing --new-bundle-format into both commands.

go run ./cmd/cosign attest --predicate my-predicate.json --new-bundle-format MY_IMAGE
go run ./cmd/cosign verify-attestation --certificate-identity MY_IDENTITY --certificate-oidc-issuer MY_ISSUER --new-bundle-format --trusted-root=MY_TRUSTED_ROOT MY_IMAGE

Full example (using crane, but can instead use docker tag/docker push):

make cosign
docker run -d -p 5050:5000 ghcr.io/project-zot/zot-linux-arm64:latest
crane copy busybox:latest localhost:5050/busybox
echo '{"foo": "bar"}' > predicate.json
./cosign attest --predicate predicate.json --new-bundle-format localhost:5050/busybox:latest
# Dex workflow, assuming GitHub as provider
./cosign verify-attestation [email protected] --certificate-oidc-issuer=https://github.com/login/oauth --new-bundle-format localhost:5050/busybox:latest

To show that it uses the OCI 1.1 referrers API, you can use oras:

oras discover localhost:5050/busybox:latest
Discovered 1 artifact referencing latest
Digest: sha256:db142d433cdde11f10ae479dbf92f3b13d693fd1c91053da9979728cceb1dc68

Artifact Type                                   Digest
application/vnd.dev.sigstore.bundle.v0.3+json   sha256:3fb46d845fe437667a6b3ed45d2b11dea11c43f8fbe76dd642eb71de2a9b8b77

Release Note

Documentation

Copy link

codecov bot commented Nov 6, 2024

Codecov Report

Attention: Patch coverage is 9.95025% with 362 lines in your changes missing coverage. Please review.

Project coverage is 35.86%. Comparing base (2ef6022) to head (1602cc1).
Report is 278 commits behind head on main.

Files with missing lines Patch % Lines
pkg/cosign/verify.go 19.27% 126 Missing and 8 partials ⚠️
pkg/oci/remote/write.go 0.00% 92 Missing ⚠️
cmd/cosign/cli/verify/verify_attestation.go 0.00% 34 Missing ⚠️
cmd/cosign/cli/attest/attest.go 0.00% 32 Missing ⚠️
pkg/oci/remote/signatures.go 0.00% 31 Missing ⚠️
cmd/cosign/cli/attest/common.go 0.00% 10 Missing ⚠️
cmd/cosign/cli/verify/verify.go 0.00% 7 Missing ⚠️
cmd/cosign/cli/attest/attest_blob.go 14.28% 6 Missing ⚠️
pkg/cosign/verify_bundle.go 40.00% 4 Missing and 2 partials ⚠️
cmd/cosign/cli/verify.go 0.00% 4 Missing ⚠️
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3889      +/-   ##
==========================================
- Coverage   40.10%   35.86%   -4.24%     
==========================================
  Files         155      210      +55     
  Lines       10044    13695    +3651     
==========================================
+ Hits         4028     4912     +884     
- Misses       5530     8152    +2622     
- Partials      486      631     +145     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codysoyland codysoyland force-pushed the verify-attestation-bundle-spec branch from af5093d to 524f558 Compare November 22, 2024 16:44
@codysoyland codysoyland marked this pull request as ready for review November 22, 2024 19:55
@codysoyland codysoyland changed the title Add support for new bundle specification in cosign verify-attestation Add support for new bundle specification for attesting/verifying OCI image attestations Nov 22, 2024
cmd/cosign/cli/attest/attest.go Show resolved Hide resolved
cmd/cosign/cli/attest/common.go Show resolved Hide resolved
cmd/cosign/cli/options/verify.go Show resolved Hide resolved
cmd/cosign/cli/verify/verify_attestation.go Outdated Show resolved Hide resolved
cmd/cosign/cli/verify/verify_attestation.go Outdated Show resolved Hide resolved
pkg/cosign/verify.go Outdated Show resolved Hide resolved
pkg/cosign/verify.go Show resolved Hide resolved
pkg/cosign/verify.go Show resolved Hide resolved
pkg/cosign/verify.go Outdated Show resolved Hide resolved
pkg/cosign/verify.go Outdated Show resolved Hide resolved
pkg/cosign/verify.go Show resolved Hide resolved
pkg/cosign/verify.go Outdated Show resolved Hide resolved
pkg/cosign/verify.go Outdated Show resolved Hide resolved
// Wrap TrustedMaterial
vTrustedMaterial := &verifyTrustedMaterial{TrustedMaterial: co.TrustedMaterial}

// If TrustedMaterial is not set, fetch it from TUF (TODO: should this even be done? Old verifier requires co.RootCerts to be set)
Copy link
Contributor

Choose a reason for hiding this comment

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

If they haven't set --trusted-root then they could be using other flags or relying on the TUF v1 setup which might be pointed to something other than the public good instance. I understand that this is only meant to be called when --new-bundle-format is set but I'm worried that this would be surprising behavior if the PGI trusted root is used while the cached TUF metadata is pointed somewhere else.

pkg/cosign/verify.go Outdated Show resolved Hide resolved
}

for _, verified := range bundlesVerified {
atLeastOneBundleVerified = atLeastOneBundleVerified || verified
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you clarify why it's okay for only one bundle to be verified?

@@ -25,7 +25,9 @@ import (
func Referrers(d name.Digest, artifactType string, opts ...Option) (*v1.IndexManifest, error) {
o := makeOptions(name.Repository{}, opts...)
rOpt := o.ROpt
rOpt = append(rOpt, remote.WithFilter("artifactType", artifactType))
if artifactType != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there not a more specific artifact type we can filter by when getting attestations?

Copy link
Member Author

Choose a reason for hiding this comment

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

The artifactType for bundles is something like application/vnd.dev.sigstore.bundle.v0.3+json. Since the version number is baked into the type, we can't use the filter feature here. Therefore, getBundles uses an empty string as the artifactType in the call to Referrers.

@@ -361,7 +377,7 @@ func attestVerify(t *testing.T, predicateType, attestation, goodCue, badCue stri
}

// Now attest the image
ko := options.KeyOpts{KeyRef: privKeyPath, PassFunc: passFunc}
ko := options.KeyOpts{KeyRef: privKeyPath, PassFunc: passFunc, NewBundleFormat: newBundleFormat}
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe out of scope for this PR but a note for the future, this is setting NewBundleFormat without setting TrustedRootPath, which means the TrustedMaterial will default to using PGI. We're trying to avoid making external network calls to live services. The only reason that isn't a problem here is because this test is using a local key pair and is not uploading to Rekor, so it doesn't matter what verification material is used. But a useful test in the future might be to have this use ephemeral keys from Fulcio (localhost:5555) and upload the entry to Rekor (localhost:3000) so that the full verification path with a locally generated trust root could be tested.

pkg/cosign/verify.go Outdated Show resolved Hide resolved
@codysoyland codysoyland force-pushed the verify-attestation-bundle-spec branch from 2c27fc5 to 1602cc1 Compare January 24, 2025 21:38
@codysoyland
Copy link
Member Author

I rebased and squashed all commits into one as there have been a couple of items refactored into separate PRs (#4006 and #4013) and this ongoing PR was getting a bit messy.

I still need to finish #4013 and rebase this one again, at which point I will be ready for another review pass.

Thanks everyone who has been patiently reviewing and helping me iterate on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants