Skip to content

Commit

Permalink
Have the keyless cosign sign flow use a single 3LO.
Browse files Browse the repository at this point in the history
With this change, the keyless flow builds a single signer for all of the images, which means a single key and 3LO for all of the references we sign:

```shell
$ COSIGN_EXPERIMENTAL=true cosign sign ghcr.io/mattmoor/controller ghcr.io/mattmoor/webhook
Generating ephemeral keys...
Retrieving signed certificate...
Your browser will now be opened to:
https://oauth2.sigstore.dev/auth/auth?REDACTED
Successfully verified SCT...
tlog entry created with index: 693418
Pushing signature to: ghcr.io/mattmoor/controller:sha256-b10f4b2e04cde2e799e080068f162ef668c4db3099382798b5fe1a208023105d.sig
tlog entry created with index: 693420
Pushing signature to: ghcr.io/mattmoor/webhook:sha256-ed1b1c778685ae0739cd4c6354fa2d724351b01e998a019d1ddc2909c377483d.sig
```

Fixes: #658
Signed-off-by: Matt Moore <mattomata@gmail.com>
  • Loading branch information
mattmoor committed Sep 14, 2021
1 parent e14b69d commit cbfe9b4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 31 deletions.
62 changes: 32 additions & 30 deletions cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,11 @@ EXAMPLES
OIDCClientID: *oidcClientID,
OIDCClientSecret: *oidcClientSecret,
}
for _, img := range args {
if err := SignCmd(ctx, ko, annotations.annotations, img, *cert, *upload, *payloadPath, *force, *recursive, *attachment); err != nil {
if *attachment == "" {
return errors.Wrapf(err, "signing %s", img)
}
return errors.Wrapf(err, "signing attachement %s for image %s", *attachment, img)
if err := SignCmd(ctx, ko, annotations.annotations, args, *cert, *upload, *payloadPath, *force, *recursive, *attachment); err != nil {
if *attachment == "" {
return errors.Wrapf(err, "signing %v", args)
}
return errors.Wrapf(err, "signing attachement %s for image %v", *attachment, args)
}
return nil
},
Expand Down Expand Up @@ -257,12 +255,7 @@ func getTransitiveImages(rootIndex *remote.Descriptor, repo name.Repository, opt
}

func SignCmd(ctx context.Context, ko KeyOpts, annotations map[string]interface{},
inputImg string, certPath string, upload bool, payloadPath string, force bool, recursive bool, attachment string) error {
// A key file or token is required unless we're in experimental mode!
imageRef, err := getAttachedImageRef(ctx, inputImg, attachment)
if err != nil {
return fmt.Errorf("unable to resolve attachment %s for image %s", attachment, inputImg)
}
imgs []string, certPath string, upload bool, payloadPath string, force bool, recursive bool, attachment string) error {

if EnableExperimental() {
if nOf(ko.KeyRef, ko.Sk) > 1 {
Expand All @@ -279,27 +272,36 @@ func SignCmd(ctx context.Context, ko KeyOpts, annotations map[string]interface{}
remote.WithContext(ctx),
}

ref, err := name.ParseReference(imageRef)
if err != nil {
return errors.Wrap(err, "parsing reference")
}
get, err := remote.Get(ref, remoteOpts...)
if err != nil {
return errors.Wrap(err, "getting remote image")
}
var toSign []name.Digest
for _, inputImg := range imgs {

repo := ref.Context()
img := repo.Digest(get.Digest.String())

toSign := []name.Digest{img}
// A key file or token is required unless we're in experimental mode!
imageRef, err := getAttachedImageRef(ctx, inputImg, attachment)
if err != nil {
return fmt.Errorf("unable to resolve attachment %s for image %s", attachment, inputImg)
}

if recursive && get.MediaType.IsIndex() {
imgs, err := getTransitiveImages(get, repo, remoteOpts...)
ref, err := name.ParseReference(imageRef)
if err != nil {
return err
return errors.Wrap(err, "parsing reference")
}
get, err := remote.Get(ref, remoteOpts...)
if err != nil {
return errors.Wrap(err, "getting remote image")
}

repo := ref.Context()
toSign = append(toSign, repo.Digest(get.Digest.String()))

if recursive && get.MediaType.IsIndex() {
imgs, err := getTransitiveImages(get, repo, remoteOpts...)
if err != nil {
return err
}
toSign = append(toSign, imgs...)
}
toSign = append(toSign, imgs...)
}

sv, err := signerFromKeyOpts(ctx, certPath, ko)
if err != nil {
return errors.Wrap(err, "getting signer")
Expand Down Expand Up @@ -339,7 +341,7 @@ func SignCmd(ctx context.Context, ko KeyOpts, annotations map[string]interface{}
continue
}

sigRepo, err := TargetRepositoryForImage(ref)
sigRepo, err := TargetRepositoryForImage(img)
if err != nil {
return err
}
Expand All @@ -357,7 +359,7 @@ func SignCmd(ctx context.Context, ko KeyOpts, annotations map[string]interface{}
}

// Check if the image is public (no auth in Get)
uploadTLog, err := shouldUploadToTlog(ref, force, ko.RekorURL)
uploadTLog, err := shouldUploadToTlog(img, force, ko.RekorURL)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestSignCmdLocalKeyAndSk(t *testing.T) {
Sk: true,
},
} {
err := SignCmd(ctx, ko, nil, "", "", false, "", false, false, "")
err := SignCmd(ctx, ko, nil, nil, "", false, "", false, false, "")
if (errors.Is(err, &KeyParseError{}) == false) {
t.Fatal("expected KeyParseError")
}
Expand Down

0 comments on commit cbfe9b4

Please sign in to comment.