Skip to content

Commit 0b2eaa0

Browse files
authored
feat(cosign): add support for cosign bundle (#4023)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
1 parent 993a17f commit 0b2eaa0

15 files changed

Lines changed: 135 additions & 47 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ GOLINTER_VERSION := v2.6.2
1616
NOTATION := $(TOOLSDIR)/bin/notation
1717
NOTATION_VERSION := 1.3.2
1818
COSIGN := $(TOOLSDIR)/bin/cosign
19-
COSIGN_VERSION := 2.2.0
19+
COSIGN_VERSION := 3.0.6
2020
HELM := $(TOOLSDIR)/bin/helm
2121
ORAS := $(TOOLSDIR)/bin/oras
2222
ORAS_VERSION := 1.2.1

pkg/cli/client/client.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -546,23 +546,24 @@ func isCosignSigned(ctx context.Context, repo, digestStr string, searchConf Sear
546546
return true
547547
}
548548

549-
var referrers ispec.Index
549+
for _, artifactType := range []string{common.ArtifactTypeCosign, common.ArtifactTypeCosignBundle} {
550+
var referrers ispec.Index
550551

551-
artifactType := url.QueryEscape(common.ArtifactTypeCosign)
552-
URL = fmt.Sprintf("%s/v2/%s/referrers/%s?artifactType=%s",
553-
searchConf.ServURL, repo, digestStr, artifactType)
552+
URL = fmt.Sprintf("%s/v2/%s/referrers/%s?artifactType=%s",
553+
searchConf.ServURL, repo, digestStr, url.QueryEscape(artifactType))
554554

555-
_, err = httpClient.makeGETRequest(ctx, URL, username, password, searchConf.VerifyTLS,
556-
searchConf.Debug, &referrers, searchConf.ResultWriter)
557-
if err != nil {
558-
return false
559-
}
555+
_, err = httpClient.makeGETRequest(ctx, URL, username, password, searchConf.VerifyTLS,
556+
searchConf.Debug, &referrers, searchConf.ResultWriter)
557+
if err != nil {
558+
continue
559+
}
560560

561-
if len(referrers.Manifests) == 0 {
562-
return false
561+
if len(referrers.Manifests) > 0 {
562+
return true
563+
}
563564
}
564565

565-
return true
566+
return false
566567
}
567568

568569
func (p *requestsPool) submitJob(job *httpJob) {

pkg/common/common.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ const (
3030
// ArtifactTypeNotation is the same value as github.com/notaryproject/notation-go/registry.ArtifactTypeNotation
3131
// (assert by internal test).
3232
// reason used: to reduce zot minimal binary size (otherwise adds oras.land/oras-go/v2 deps).
33-
ArtifactTypeNotation = "application/vnd.cncf.notary.signature"
34-
ArtifactTypeCosign = "application/vnd.dev.cosign.artifact.sig.v1+json"
33+
ArtifactTypeNotation = "application/vnd.cncf.notary.signature"
34+
ArtifactTypeCosign = "application/vnd.dev.cosign.artifact.sig.v1+json"
35+
ArtifactTypeCosignBundle = "application/vnd.dev.sigstore.bundle.v0.3+json"
3536
// CosignSignatureTagSuffix is the suffix used for cosign signature tags (e.g., "sha256-digest.sig").
3637
// Using constant to avoid pulling in cosign dependency.
3738
CosignSignatureTagSuffix = "sig"
@@ -53,6 +54,12 @@ func IsCosignTag(tag string) bool {
5354
return IsCosignSignature(tag) || IsCosignSBOM(tag)
5455
}
5556

57+
// IsArtifactTypeCosign returns true if the given artifact type corresponds to a cosign signature,
58+
// covering both the legacy type and the newer sigstore bundle type.
59+
func IsArtifactTypeCosign(artifactType string) bool {
60+
return artifactType == ArtifactTypeCosign || artifactType == ArtifactTypeCosignBundle
61+
}
62+
5663
// RemoveFrom removes matches of item in [].
5764
func RemoveFrom(inputSlice []string, item string) []string {
5865
var newSlice []string

pkg/common/common_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ func TestCommon(t *testing.T) {
6161
So(common.ArtifactTypeNotation, ShouldEqual, notreg.ArtifactTypeNotation)
6262
})
6363

64+
Convey("Test IsArtifactTypeCosign", t, func() {
65+
So(common.IsArtifactTypeCosign(common.ArtifactTypeCosign), ShouldBeTrue)
66+
So(common.IsArtifactTypeCosign(common.ArtifactTypeCosignBundle), ShouldBeTrue)
67+
So(common.IsArtifactTypeCosign(common.ArtifactTypeNotation), ShouldBeFalse)
68+
So(common.IsArtifactTypeCosign("application/example"), ShouldBeFalse)
69+
})
70+
6471
Convey("Test GetLocalIPs", t, func() {
6572
localIPs, err := common.GetLocalIPs()
6673
So(err, ShouldBeNil)

pkg/extensions/sync/referrers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func hasSignatureReferrers(refs referrer.ReferrerList) bool {
2626
return true
2727
}
2828

29-
if desc.ArtifactType == common.ArtifactTypeCosign {
29+
if common.IsArtifactTypeCosign(desc.ArtifactType) {
3030
return true
3131
}
3232
}

pkg/meta/parse.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ func isSignature(reference string, manifestContent ispec.Manifest) (bool, string
439439
}
440440

441441
// check cosign signature
442-
if manifestArtifactType == zcommon.ArtifactTypeCosign && manifestContent.Subject != nil {
442+
if zcommon.IsArtifactTypeCosign(manifestArtifactType) && manifestContent.Subject != nil {
443443
return true, CosignType, manifestContent.Subject.Digest
444444
}
445445

pkg/meta/parse_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,35 @@ func RunParseStorageTests(rootDir string, metaDB mTypes.MetaDB, log log.Logger)
556556
So(repos[0].Signatures, ShouldContainKey, missingImageDigest.String())
557557
})
558558

559+
Convey("Detect cosign bundle signatures by artifact type and subject", func() {
560+
imageStore := local.NewImageStore(rootDir, false, false,
561+
log, monitoring.NewMetricsServer(false, log), nil, nil, nil, nil)
562+
563+
storeController := storage.StoreController{DefaultStore: imageStore}
564+
565+
signedImage := CreateRandomImage()
566+
err := WriteImageToFileSystem(signedImage, repo, "signed", storeController)
567+
So(err, ShouldBeNil)
568+
569+
bundleSig := CreateMockCosignBundleSignature(signedImage.DescriptorRef())
570+
err = WriteImageToFileSystem(bundleSig, repo, "bundle-sig", storeController)
571+
So(err, ShouldBeNil)
572+
573+
err = meta.ParseStorage(metaDB, storeController, log) //nolint: contextcheck
574+
So(err, ShouldBeNil)
575+
576+
repos, err := metaDB.GetMultipleRepoMeta(ctx,
577+
func(repoMeta mTypes.RepoMeta) bool { return true })
578+
So(err, ShouldBeNil)
579+
So(repos, ShouldNotBeEmpty)
580+
581+
repoMeta := repos[0]
582+
subjectDigest := signedImage.DigestStr()
583+
So(repoMeta.Signatures, ShouldContainKey, subjectDigest)
584+
So(repoMeta.Signatures[subjectDigest], ShouldContainKey, zcommon.CosignSignature)
585+
So(len(repoMeta.Signatures[subjectDigest][zcommon.CosignSignature]), ShouldBeGreaterThan, 0)
586+
})
587+
559588
Convey("Check statistics after load", func() {
560589
imageStore := local.NewImageStore(rootDir, false, false,
561590
log, monitoring.NewMetricsServer(false, log), nil, nil, nil, nil)

pkg/storage/common/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ func IsSignature(descriptor ispec.Descriptor) bool {
653653
}
654654

655655
// is cosign signature (OCI 1.1 support)
656-
if descriptor.ArtifactType == zcommon.ArtifactTypeCosign {
656+
if zcommon.IsArtifactTypeCosign(descriptor.ArtifactType) {
657657
return true
658658
}
659659

pkg/storage/gc/gc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ func (gc GarbageCollect) removeReferrer(repo string, index *ispec.Index, manifes
321321
// check if its notation or cosign signature
322322
if artifactType == zcommon.ArtifactTypeNotation {
323323
signatureType = storage.NotationType
324-
} else if artifactType == zcommon.ArtifactTypeCosign {
324+
} else if zcommon.IsArtifactTypeCosign(artifactType) {
325325
signatureType = storage.CosignType
326326
}
327327

pkg/storage/storage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ func CheckIsImageSignature(repoName string, manifestBlob []byte, reference strin
297297
}
298298

299299
// check cosign signature (OCI 1.1 support)
300-
if manifestArtifactType == zcommon.ArtifactTypeCosign && manifestContent.Subject != nil {
300+
if zcommon.IsArtifactTypeCosign(manifestArtifactType) && manifestContent.Subject != nil {
301301
return true, CosignType, manifestContent.Subject.Digest, nil
302302
}
303303

0 commit comments

Comments
 (0)