Skip to content

Commit

Permalink
feat: add custom signature tag registry options (#808)
Browse files Browse the repository at this point in the history
* feat: add signature tag suffix to registry opts
* feat: add signature tag prefix to registry opts
* refactor: make prefix flag generic
* refactor: make TagOptions, rename parameters, reorder prefix location

Signed-off-by: Joel Kamp <[email protected]>
  • Loading branch information
mrjoelkamp authored Oct 8, 2021
1 parent 2f6a293 commit 5c1240b
Show file tree
Hide file tree
Showing 25 changed files with 108 additions and 9 deletions.
4 changes: 3 additions & 1 deletion cmd/cosign/cli/options/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
// RegistryOptions is the wrapper for the registry options.
type RegistryOptions struct {
AllowInsecure bool
Tags TagOptions
}

var _ Interface = (*RegistryOptions)(nil)
Expand All @@ -36,10 +37,11 @@ var _ Interface = (*RegistryOptions)(nil)
func (o *RegistryOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&o.AllowInsecure, "allow-insecure-registry", false,
"whether to allow insecure connections to registries. Don't use this for anything but testing")
o.Tags.AddFlags(cmd)
}

func (o *RegistryOptions) ClientOpts(ctx context.Context) []ociremote.Option {
return []ociremote.Option{ociremote.WithRemoteOptions(o.GetRegistryClientOpts(ctx)...)}
return []ociremote.Option{ociremote.WithRemoteOptions(o.GetRegistryClientOpts(ctx)...), ociremote.WithPrefix(o.Tags.TagPrefix), ociremote.WithSuffix(o.Tags.TagSuffix)}
}

func (o *RegistryOptions) GetRegistryClientOpts(ctx context.Context) []remote.Option {
Expand Down
34 changes: 34 additions & 0 deletions cmd/cosign/cli/options/tags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Copyright 2021 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package options

import (
"github.com/spf13/cobra"
)

// TagOptions is a wrapper for the tag options.
type TagOptions struct {
TagPrefix string
TagSuffix string
}

var _ Interface = (*TagOptions)(nil)

// AddFlags implements Interface
func (o *TagOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.TagPrefix, "tag-prefix", "", "custom prefix to use for tags")
cmd.Flags().StringVar(&o.TagSuffix, "tag-suffix", "", "custom suffix to use for tags")
}
2 changes: 2 additions & 0 deletions doc/cosign_attach_sbom.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_attach_signature.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_attest.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_clean.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_copy.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_dockerfile_verify.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_download_sbom.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_download_signature.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_generate.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_manifest_verify.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_policy_init.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_policy_sign.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_sign-blob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_sign.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_triangulate.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_upload_blob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_upload_wasm.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_verify-attestation.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_verify-blob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions doc/cosign_verify.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions pkg/oci/remote/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
SignatureTagSuffix = "sig"
SBOMTagSuffix = "sbom"
AttestationTagSuffix = "att"
CustomTagPrefix = ""

RepoOverrideKey = "COSIGN_REPOSITORY"
)
Expand All @@ -38,6 +39,7 @@ type options struct {
SignatureSuffix string
AttestationSuffix string
SBOMSuffix string
TagPrefix string
TargetRepository name.Repository
ROpt []remote.Option

Expand All @@ -54,6 +56,7 @@ func makeOptions(target name.Repository, opts ...Option) (*options, error) {
SignatureSuffix: SignatureTagSuffix,
AttestationSuffix: AttestationTagSuffix,
SBOMSuffix: SBOMTagSuffix,
TagPrefix: CustomTagPrefix,
TargetRepository: target,
ROpt: defaultOptions,

Expand All @@ -78,6 +81,26 @@ func makeOptions(target name.Repository, opts ...Option) (*options, error) {
return o, nil
}

// WithPrefix is a functional option for overriding the default
// tag prefix.
func WithPrefix(prefix string) Option {
return func(o *options) {
o.TagPrefix = prefix
}
}

// WithSuffix is a functional option for overriding the default
// tag suffix.
func WithSuffix(suffix string) Option {
return func(o *options) {
if suffix != "" {
o.SignatureSuffix = suffix
o.AttestationSuffix = suffix
o.SBOMSuffix = suffix
}
}
}

// WithSignatureSuffix is a functional option for overriding the default
// signature tag suffix.
func WithSignatureSuffix(suffix string) Option {
Expand Down
12 changes: 6 additions & 6 deletions pkg/oci/remote/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ func SignedEntity(ref name.Reference, options ...Option) (oci.SignedEntity, erro

// normalize turns image digests into tags with an optional suffix:
// sha256:d34db33f -> sha256-d34db33f.suffix
func normalize(h v1.Hash, suffix string) string {
func normalize(h v1.Hash, prefix string, suffix string) string {
if suffix == "" {
return fmt.Sprint(h.Algorithm, "-", h.Hex)
return fmt.Sprint(prefix, h.Algorithm, "-", h.Hex)
}
return fmt.Sprint(h.Algorithm, "-", h.Hex, ".", suffix)
return fmt.Sprint(prefix, h.Algorithm, "-", h.Hex, ".", suffix)
}

// SignatureTag returns the name.Tag that associated signatures with a particular digest.
Expand Down Expand Up @@ -131,7 +131,7 @@ func suffixTag(ref name.Reference, suffix string, o *options) (name.Tag, error)
}
h = desc.Digest
}
return o.TargetRepository.Tag(normalize(h, suffix)), nil
return o.TargetRepository.Tag(normalize(h, o.TagPrefix, suffix)), nil
}

type digestable interface {
Expand All @@ -144,7 +144,7 @@ func signatures(digestable digestable, o *options) (oci.Signatures, error) {
if err != nil {
return nil, err
}
return Signatures(o.TargetRepository.Tag(normalize(h, o.SignatureSuffix)), o.OriginalOptions...)
return Signatures(o.TargetRepository.Tag(normalize(h, o.TagPrefix, o.SignatureSuffix)), o.OriginalOptions...)
}

// attestations is a shared implementation of the oci.Signed* Signatures method.
Expand All @@ -153,5 +153,5 @@ func attestations(digestable digestable, o *options) (oci.Signatures, error) {
if err != nil {
return nil, err
}
return Signatures(o.TargetRepository.Tag(normalize(h, o.AttestationSuffix)), o.OriginalOptions...)
return Signatures(o.TargetRepository.Tag(normalize(h, o.TagPrefix, o.AttestationSuffix)), o.OriginalOptions...)
}
4 changes: 2 additions & 2 deletions pkg/oci/remote/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func WriteSignatures(repo name.Repository, se oci.SignedEntity, opts ...Option)
if err != nil {
return err
}
tag := o.TargetRepository.Tag(normalize(h, o.SignatureSuffix))
tag := o.TargetRepository.Tag(normalize(h, o.TagPrefix, o.SignatureSuffix))

// Write the Signatures image to the tag, with the provided remote.Options
return remoteWrite(tag, sigs, o.ROpt...)
Expand All @@ -64,7 +64,7 @@ func WriteAttestations(repo name.Repository, se oci.SignedEntity, opts ...Option
if err != nil {
return err
}
tag := o.TargetRepository.Tag(normalize(h, o.AttestationSuffix))
tag := o.TargetRepository.Tag(normalize(h, o.TagPrefix, o.AttestationSuffix))

// Write the Signatures image to the tag, with the provided remote.Options
return remoteWrite(tag, atts, o.ROpt...)
Expand Down

0 comments on commit 5c1240b

Please sign in to comment.