From ca56d97146a3da3e59199ae52dcb7f8ad50b0806 Mon Sep 17 00:00:00 2001 From: Hector Fernandez Date: Mon, 17 Oct 2022 13:55:29 +0200 Subject: [PATCH 1/3] bind flags to prefixed env variables Signed-off-by: Hector Fernandez --- cmd/cosign/cli/attach.go | 21 +++++++++++--------- cmd/cosign/cli/attest.go | 3 ++- cmd/cosign/cli/attest_blob.go | 3 ++- cmd/cosign/cli/clean.go | 9 +++++---- cmd/cosign/cli/copy.go | 3 ++- cmd/cosign/cli/dockerfile.go | 3 ++- cmd/cosign/cli/download.go | 27 ++++++++++++++------------ cmd/cosign/cli/generate.go | 3 ++- cmd/cosign/cli/generate_key_pair.go | 1 + cmd/cosign/cli/import_key_pair.go | 2 +- cmd/cosign/cli/initialize.go | 1 + cmd/cosign/cli/load.go | 11 ++++++----- cmd/cosign/cli/manifest.go | 3 ++- cmd/cosign/cli/options/root.go | 30 +++++++++++++++++++++++++++++ cmd/cosign/cli/piv_tool.go | 14 ++++++++------ cmd/cosign/cli/policy_init.go | 8 +++++--- cmd/cosign/cli/public_key.go | 1 + cmd/cosign/cli/save.go | 11 ++++++----- cmd/cosign/cli/sign.go | 3 ++- cmd/cosign/cli/signblob.go | 3 ++- cmd/cosign/cli/tree.go | 9 +++++---- cmd/cosign/cli/triangulate.go | 7 ++++--- cmd/cosign/cli/upload.go | 12 +++++++----- cmd/cosign/cli/verify.go | 12 ++++++++---- 24 files changed, 131 insertions(+), 69 deletions(-) diff --git a/cmd/cosign/cli/attach.go b/cmd/cosign/cli/attach.go index 8aa897f3f39..ae12f60d20f 100644 --- a/cmd/cosign/cli/attach.go +++ b/cmd/cosign/cli/attach.go @@ -43,10 +43,11 @@ func attachSignature() *cobra.Command { o := &options.AttachSignatureOptions{} cmd := &cobra.Command{ - Use: "signature", - Short: "Attach signatures to the supplied container image", - Example: " cosign attach signature ", - Args: cobra.ExactArgs(1), + Use: "signature", + Short: "Attach signatures to the supplied container image", + Example: " cosign attach signature ", + PersistentPreRun: options.BindViper, + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { return attach.SignatureCmd(cmd.Context(), o.Registry, o.Signature, o.Payload, args[0]) }, @@ -61,10 +62,11 @@ func attachSBOM() *cobra.Command { o := &options.AttachSBOMOptions{} cmd := &cobra.Command{ - Use: "sbom", - Short: "Attach sbom to the supplied container image", - Example: " cosign attach sbom ", - Args: cobra.ExactArgs(1), + Use: "sbom", + Short: "Attach sbom to the supplied container image", + Example: " cosign attach sbom ", + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { mediaType, err := o.MediaType() if err != nil { @@ -96,7 +98,8 @@ func attachAttestation() *cobra.Command { cosign attach attestation --attestation `, - Args: cobra.MinimumNArgs(1), + Args: cobra.MinimumNArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return attach.AttestationCmd(cmd.Context(), o.Registry, o.Attestations, args[0]) }, diff --git a/cmd/cosign/cli/attest.go b/cmd/cosign/cli/attest.go index 71e17746c23..ae067cb3c60 100644 --- a/cmd/cosign/cli/attest.go +++ b/cmd/cosign/cli/attest.go @@ -57,7 +57,8 @@ func Attest() *cobra.Command { # attach an attestation to a container image which does not fully support OCI media types COSIGN_DOCKER_MEDIA_TYPES=1 cosign attest --predicate --type --key cosign.key legacy-registry.example.com/my/image`, - Args: cobra.MinimumNArgs(1), + Args: cobra.MinimumNArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { oidcClientSecret, err := o.OIDC.ClientSecret() if err != nil { diff --git a/cmd/cosign/cli/attest_blob.go b/cmd/cosign/cli/attest_blob.go index 5ac6c3e5cf9..0eca6c8c810 100644 --- a/cmd/cosign/cli/attest_blob.go +++ b/cmd/cosign/cli/attest_blob.go @@ -43,7 +43,8 @@ func AttestBlob() *cobra.Command { # attach an attestation to a blob with a key pair stored in Hashicorp Vault cosign attest-blob --predicate --type --key hashivault://[KEY] `, - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { v := attest.AttestBlobCommand{ KeyRef: o.Key, diff --git a/cmd/cosign/cli/clean.go b/cmd/cosign/cli/clean.go index 33ae67af7ba..1ec4054ddba 100644 --- a/cmd/cosign/cli/clean.go +++ b/cmd/cosign/cli/clean.go @@ -36,10 +36,11 @@ func Clean() *cobra.Command { c := &options.CleanOptions{} cmd := &cobra.Command{ - Use: "clean", - Short: "Remove all signatures from an image.", - Example: " cosign clean ", - Args: cobra.ExactArgs(1), + Use: "clean", + Short: "Remove all signatures from an image.", + Example: " cosign clean ", + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return CleanCmd(cmd.Context(), c.Registry, c.CleanType, args[0], c.Force) }, diff --git a/cmd/cosign/cli/copy.go b/cmd/cosign/cli/copy.go index 11c395bccbf..be890a011c0 100644 --- a/cmd/cosign/cli/copy.go +++ b/cmd/cosign/cli/copy.go @@ -39,7 +39,8 @@ func Copy() *cobra.Command { # overwrite destination image and signatures cosign copy -f example.com/src example.com/dest`, - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(2), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return copy.CopyCmd(cmd.Context(), o.Registry, args[0], args[1], o.SignatureOnly, o.Force) }, diff --git a/cmd/cosign/cli/dockerfile.go b/cmd/cosign/cli/dockerfile.go index 70aa9018672..db0753cfb4b 100644 --- a/cmd/cosign/cli/dockerfile.go +++ b/cmd/cosign/cli/dockerfile.go @@ -42,6 +42,7 @@ func dockerfileVerify() *cobra.Command { cmd := &cobra.Command{ Use: "verify", Short: "Verify a signature on the base image specified in the Dockerfile", + PersistentPreRun: options.BindViper, Long: `Verify signature and annotations on images in a Dockerfile by checking claims against the transparency log. @@ -114,4 +115,4 @@ Shell-like variables in the Dockerfile's FROM lines will be substituted with val o.AddFlags(cmd) return cmd -} +} \ No newline at end of file diff --git a/cmd/cosign/cli/download.go b/cmd/cosign/cli/download.go index a856e58ee23..34876fbe2e2 100644 --- a/cmd/cosign/cli/download.go +++ b/cmd/cosign/cli/download.go @@ -44,10 +44,11 @@ func downloadSignature() *cobra.Command { o := &options.RegistryOptions{} cmd := &cobra.Command{ - Use: "signature", - Short: "Download signatures from the supplied container image", - Example: " cosign download signature ", - Args: cobra.ExactArgs(1), + Use: "signature", + Short: "Download signatures from the supplied container image", + Example: " cosign download signature ", + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return download.SignatureCmd(cmd.Context(), *o, args[0]) }, @@ -63,10 +64,11 @@ func downloadSBOM() *cobra.Command { do := &options.SBOMDownloadOptions{} cmd := &cobra.Command{ - Use: "sbom", - Short: "Download SBOMs from the supplied container image", - Example: " cosign download sbom ", - Args: cobra.ExactArgs(1), + Use: "sbom", + Short: "Download SBOMs from the supplied container image", + Example: " cosign download sbom ", + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { fmt.Fprintln(os.Stderr, "WARNING: Downloading SBOMs this way does not ensure its authenticity. If you want to ensure a tamper-proof SBOM, download it using 'cosign download attestation ' or verify its signature using 'cosign verify --key --attachment sbom '.") _, err := download.SBOMCmd(cmd.Context(), *o, *do, args[0], cmd.OutOrStdout()) @@ -84,10 +86,11 @@ func downloadAttestation() *cobra.Command { o := &options.RegistryOptions{} cmd := &cobra.Command{ - Use: "attestation", - Short: "Download in-toto attestations from the supplied container image", - Example: " cosign download attestation ", - Args: cobra.ExactArgs(1), + Use: "attestation", + Short: "Download in-toto attestations from the supplied container image", + Example: " cosign download attestation ", + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return download.AttestationCmd(cmd.Context(), *o, args[0]) }, diff --git a/cmd/cosign/cli/generate.go b/cmd/cosign/cli/generate.go index 85a7a78c753..162f8277ded 100644 --- a/cmd/cosign/cli/generate.go +++ b/cmd/cosign/cli/generate.go @@ -42,7 +42,8 @@ to sign payloads with your own tooling or algorithms.`, # Use this payload in another tool gpg --output image.sig --detach-sig <(cosign generate )`, - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { annotationMap, err := o.AnnotationsMap() if err != nil { diff --git a/cmd/cosign/cli/generate_key_pair.go b/cmd/cosign/cli/generate_key_pair.go index 6366f697bc0..a4f2278a6ec 100644 --- a/cmd/cosign/cli/generate_key_pair.go +++ b/cmd/cosign/cli/generate_key_pair.go @@ -62,6 +62,7 @@ CAVEATS: This command interactively prompts for a password. You can use the COSIGN_PASSWORD environment variable to provide one.`, + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return generate.GenerateKeyPairCmd(cmd.Context(), o.KMS, args) }, diff --git a/cmd/cosign/cli/import_key_pair.go b/cmd/cosign/cli/import_key_pair.go index 7c5a017eed4..1e5d4b9ff3b 100644 --- a/cmd/cosign/cli/import_key_pair.go +++ b/cmd/cosign/cli/import_key_pair.go @@ -37,7 +37,7 @@ func ImportKeyPair() *cobra.Command { CAVEATS: This command interactively prompts for a password. You can use the COSIGN_PASSWORD environment variable to provide one.`, - + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return importkeypair.ImportKeyPairCmd(cmd.Context(), o.Key, args) }, diff --git a/cmd/cosign/cli/initialize.go b/cmd/cosign/cli/initialize.go index 89e9c7aff23..48a920608a8 100644 --- a/cmd/cosign/cli/initialize.go +++ b/cmd/cosign/cli/initialize.go @@ -51,6 +51,7 @@ cosign initialize -root # initialize with an out-of-band root key file and custom repository mirror. cosign initialize -mirror -root `, + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return initialize.DoInitialize(cmd.Context(), o.Root, o.Mirror) }, diff --git a/cmd/cosign/cli/load.go b/cmd/cosign/cli/load.go index 26c8b1ecb42..fc19c0997a3 100644 --- a/cmd/cosign/cli/load.go +++ b/cmd/cosign/cli/load.go @@ -30,11 +30,12 @@ func Load() *cobra.Command { o := &options.LoadOptions{} cmd := &cobra.Command{ - Use: "load", - Short: "Load a signed image on disk to a remote registry", - Long: "Load a signed image on disk to a remote registry", - Example: ` cosign load --dir `, - Args: cobra.ExactArgs(1), + Use: "load", + Short: "Load a signed image on disk to a remote registry", + Long: "Load a signed image on disk to a remote registry", + Example: ` cosign load --dir `, + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return LoadCmd(cmd.Context(), *o, args[0]) }, diff --git a/cmd/cosign/cli/manifest.go b/cmd/cosign/cli/manifest.go index a6b0fb0e323..160e6f98e26 100644 --- a/cmd/cosign/cli/manifest.go +++ b/cmd/cosign/cli/manifest.go @@ -72,7 +72,8 @@ against the transparency log.`, # verify images with public key stored in Hashicorp Vault cosign manifest verify --key hashivault://[KEY] `, - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { annotations, err := o.AnnotationsMap() if err != nil { diff --git a/cmd/cosign/cli/options/root.go b/cmd/cosign/cli/options/root.go index d00f1599653..4baa32695ff 100644 --- a/cmd/cosign/cli/options/root.go +++ b/cmd/cosign/cli/options/root.go @@ -16,11 +16,17 @@ package options import ( + "fmt" + "strings" "time" "github.com/spf13/cobra" + "github.com/spf13/pflag" + "github.com/spf13/viper" ) +const EnvPrefix = "COSIGN" + // RootOptions define flags and options for the root cosign cli. type RootOptions struct { OutputFile string @@ -45,3 +51,27 @@ func (o *RootOptions) AddFlags(cmd *cobra.Command) { cmd.PersistentFlags().DurationVarP(&o.Timeout, "timeout", "t", DefaultTimeout, "timeout for commands") } + +func BindViper(cmd *cobra.Command, args []string) { + v := viper.New() + v.SetEnvPrefix(EnvPrefix) + v.AutomaticEnv() + bindFlags(cmd, v) +} + +func bindFlags(cmd *cobra.Command, v *viper.Viper) { + cmd.Flags().VisitAll(func(f *pflag.Flag) { + if strings.Contains(f.Name, "-") { + _ = v.BindEnv(f.Name, flagToEnvVar(f.Name)) + } + if !f.Changed && v.IsSet((f.Name)) { + val := v.Get(f.Name) + _ = cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)) + } + }) +} + +func flagToEnvVar(f string) string { + f = strings.ToUpper(f) + return fmt.Sprintf("%s_%s", EnvPrefix, strings.ReplaceAll(f, "-", "_")) +} diff --git a/cmd/cosign/cli/piv_tool.go b/cmd/cosign/cli/piv_tool.go index 1989fb48ca8..1b9b4302711 100644 --- a/cmd/cosign/cli/piv_tool.go +++ b/cmd/cosign/cli/piv_tool.go @@ -56,9 +56,10 @@ func pivToolSetManagementKey() *cobra.Command { o := &options.PIVToolSetManagementKeyOptions{} cmd := &cobra.Command{ - Use: "set-management-key", - Short: "sets the management key of a hardware token", - Args: cobra.ExactArgs(0), + Use: "set-management-key", + Short: "sets the management key of a hardware token", + Args: cobra.ExactArgs(0), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return pivcli.SetManagementKeyCmd(cmd.Context(), o.OldKey, o.NewKey, o.RandomKey) }, @@ -73,9 +74,10 @@ func pivToolSetPIN() *cobra.Command { o := &options.PIVToolSetPINOptions{} cmd := &cobra.Command{ - Use: "set-pin", - Short: "sets the PIN on a hardware token", - Args: cobra.ExactArgs(0), + Use: "set-pin", + Short: "sets the PIN on a hardware token", + Args: cobra.ExactArgs(0), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return pivcli.SetPinCmd(cmd.Context(), o.OldPIN, o.NewPIN) }, diff --git a/cmd/cosign/cli/policy_init.go b/cmd/cosign/cli/policy_init.go index f577405d867..bdf1d910946 100644 --- a/cmd/cosign/cli/policy_init.go +++ b/cmd/cosign/cli/policy_init.go @@ -84,6 +84,7 @@ func initPolicy() *cobra.Command { Example: ` # extract public key from private key to a specified out file. cosign policy init -ns --maintainers {email_addresses} --threshold --expires (days)`, + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { var publicKeys []*tuf.Key @@ -163,9 +164,10 @@ func signPolicy() *cobra.Command { o := &options.PolicySignOptions{} cmd := &cobra.Command{ - Use: "sign", - Short: "sign a keyless policy.", - Long: "policy is used to manage a root.json policy\nfor keyless signing delegation. This is used to establish a policy for a registry namespace,\na signing threshold and a list of maintainers who can sign over the body section.", + Use: "sign", + Short: "sign a keyless policy.", + Long: "policy is used to manage a root.json policy\nfor keyless signing delegation. This is used to establish a policy for a registry namespace,\na signing threshold and a list of maintainers who can sign over the body section.", + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() if ro.Timeout != 0 { diff --git a/cmd/cosign/cli/public_key.go b/cmd/cosign/cli/public_key.go index b66ef3ed18e..b08b1917b47 100644 --- a/cmd/cosign/cli/public_key.go +++ b/cmd/cosign/cli/public_key.go @@ -62,6 +62,7 @@ func PublicKey() *cobra.Command { } return nil }, + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { writer := publickey.NamedWriter{Name: "", Writer: nil} var f *os.File diff --git a/cmd/cosign/cli/save.go b/cmd/cosign/cli/save.go index e72f8688cd9..90d775e7a49 100644 --- a/cmd/cosign/cli/save.go +++ b/cmd/cosign/cli/save.go @@ -32,11 +32,12 @@ func Save() *cobra.Command { o := &options.SaveOptions{} cmd := &cobra.Command{ - Use: "save", - Short: "Save the container image and associated signatures to disk at the specified directory.", - Long: "Save the container image and associated signatures to disk at the specified directory.", - Example: ` cosign save --dir `, - Args: cobra.ExactArgs(1), + Use: "save", + Short: "Save the container image and associated signatures to disk at the specified directory.", + Long: "Save the container image and associated signatures to disk at the specified directory.", + Example: ` cosign save --dir `, + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return SaveCmd(cmd.Context(), *o, args[0]) }, diff --git a/cmd/cosign/cli/sign.go b/cmd/cosign/cli/sign.go index 07ce0b3de27..4ce1e1d128a 100644 --- a/cmd/cosign/cli/sign.go +++ b/cmd/cosign/cli/sign.go @@ -79,7 +79,8 @@ race conditions or (worse) malicious tampering. # sign a container image and not upload transparency log cosign sign --key cosign.key --no-tlog-upload=true `, - Args: cobra.MinimumNArgs(1), + Args: cobra.MinimumNArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { switch o.Attachment { case "sbom", "": diff --git a/cmd/cosign/cli/signblob.go b/cmd/cosign/cli/signblob.go index b5fb5191e3c..816062fa440 100644 --- a/cmd/cosign/cli/signblob.go +++ b/cmd/cosign/cli/signblob.go @@ -52,7 +52,8 @@ func SignBlob() *cobra.Command { # sign a blob with a key pair stored in Hashicorp Vault cosign sign-blob --key hashivault://[KEY] `, - Args: cobra.MinimumNArgs(1), + Args: cobra.MinimumNArgs(1), + PersistentPreRun: options.BindViper, PreRunE: func(cmd *cobra.Command, args []string) error { // A key file is required unless we're in experimental mode! if !options.EnableExperimental() { diff --git a/cmd/cosign/cli/tree.go b/cmd/cosign/cli/tree.go index 27b9baed536..d8d834068a4 100644 --- a/cmd/cosign/cli/tree.go +++ b/cmd/cosign/cli/tree.go @@ -33,10 +33,11 @@ func Tree() *cobra.Command { c := &options.TreeOptions{} cmd := &cobra.Command{ - Use: "tree", - Short: "Display supply chain security related artifacts for an image such as signatures, SBOMs and attestations", - Example: " cosign tree ", - Args: cobra.ExactArgs(1), + Use: "tree", + Short: "Display supply chain security related artifacts for an image such as signatures, SBOMs and attestations", + Example: " cosign tree ", + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return TreeCmd(cmd.Context(), c.Registry, args[0]) }, diff --git a/cmd/cosign/cli/triangulate.go b/cmd/cosign/cli/triangulate.go index 6477e4f92b3..c06d36a7de0 100644 --- a/cmd/cosign/cli/triangulate.go +++ b/cmd/cosign/cli/triangulate.go @@ -28,9 +28,10 @@ func Triangulate() *cobra.Command { o := &options.TriangulateOptions{} cmd := &cobra.Command{ - Use: "triangulate", - Short: "Outputs the located cosign image reference. This is the location cosign stores the specified artifact type.", - Example: " cosign triangulate ", + Use: "triangulate", + Short: "Outputs the located cosign image reference. This is the location cosign stores the specified artifact type.", + Example: " cosign triangulate ", + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return flag.ErrHelp diff --git a/cmd/cosign/cli/upload.go b/cmd/cosign/cli/upload.go index b05150b762a..572286e03a7 100644 --- a/cmd/cosign/cli/upload.go +++ b/cmd/cosign/cli/upload.go @@ -63,7 +63,8 @@ func uploadBlob() *cobra.Command { # upload two blobs named foo-darwin and foo-linux to the location specified by , setting annotations cosign upload blob -a mykey=myvalue -a myotherkey="my other value" -f foo-darwin:darwin -f foo-linux:linux `, - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, PreRunE: func(cmd *cobra.Command, args []string) error { if len(o.Files.Files) < 1 { return flag.ErrHelp @@ -89,10 +90,11 @@ func uploadWASM() *cobra.Command { o := &options.UploadWASMOptions{} cmd := &cobra.Command{ - Use: "wasm", - Short: "Upload a wasm module to the supplied container image reference", - Example: " cosign upload wasm -f foo.wasm ", - Args: cobra.ExactArgs(1), + Use: "wasm", + Short: "Upload a wasm module to the supplied container image reference", + Example: " cosign upload wasm -f foo.wasm ", + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { return upload.WasmCmd(cmd.Context(), o.Registry, o.File, args[0]) }, diff --git a/cmd/cosign/cli/verify.go b/cmd/cosign/cli/verify.go index 322ce5b6fcb..df946d76b32 100644 --- a/cmd/cosign/cli/verify.go +++ b/cmd/cosign/cli/verify.go @@ -80,7 +80,8 @@ against the transparency log.`, # verify image with public key stored in GitLab with project id cosign verify --key gitlab://[PROJECT_ID] `, - Args: cobra.MinimumNArgs(1), + Args: cobra.MinimumNArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { annotations, err := o.AnnotationsMap() if err != nil { @@ -175,7 +176,8 @@ against the transparency log.`, # verify image with public key and validate attestation based on CUE policy cosign verify-attestation --key cosign.pub --type --policy `, - Args: cobra.MinimumNArgs(1), + Args: cobra.MinimumNArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { v := verify.VerifyAttestationCommand{ RegistryOptions: o.Registry, @@ -256,7 +258,8 @@ The blob may be specified as a path to a file or - for stdin.`, COSIGN_EXPERIMENTAL=1 cosign verify-blob --certificate --signature $sig `, - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { ko := options.KeyOpts{ KeyRef: o.Key, @@ -298,7 +301,8 @@ The blob may be specified as a path to a file.`, `, - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + PersistentPreRun: options.BindViper, RunE: func(cmd *cobra.Command, args []string) error { v := verify.VerifyBlobAttestationCommand{ KeyRef: o.Key, From dcd2bd966fb7d77103f8e841351688ef491c51cc Mon Sep 17 00:00:00 2001 From: Hector Fernandez Date: Mon, 17 Oct 2022 16:15:47 +0200 Subject: [PATCH 2/3] test: use environment variables Signed-off-by: Hector Fernandez --- cmd/cosign/cli/dockerfile.go | 6 +++--- test/e2e_test_secrets.sh | 18 +++++++++--------- test/sign_blob_test.sh | 6 ++++++ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/cmd/cosign/cli/dockerfile.go b/cmd/cosign/cli/dockerfile.go index db0753cfb4b..91cd80564f7 100644 --- a/cmd/cosign/cli/dockerfile.go +++ b/cmd/cosign/cli/dockerfile.go @@ -40,8 +40,8 @@ func dockerfileVerify() *cobra.Command { o := &options.VerifyDockerfileOptions{} cmd := &cobra.Command{ - Use: "verify", - Short: "Verify a signature on the base image specified in the Dockerfile", + Use: "verify", + Short: "Verify a signature on the base image specified in the Dockerfile", PersistentPreRun: options.BindViper, Long: `Verify signature and annotations on images in a Dockerfile by checking claims against the transparency log. @@ -115,4 +115,4 @@ Shell-like variables in the Dockerfile's FROM lines will be substituted with val o.AddFlags(cmd) return cmd -} \ No newline at end of file +} diff --git a/test/e2e_test_secrets.sh b/test/e2e_test_secrets.sh index 621bab2c80e..5b9901c6707 100755 --- a/test/e2e_test_secrets.sh +++ b/test/e2e_test_secrets.sh @@ -159,25 +159,25 @@ if ( ! cmp -s randomblob randomblob_from_digest ); then false; fi # TODO: tlog -## KMS! +## KMS using env variables! TEST_KMS=${TEST_KMS:-gcpkms://projects/projectsigstore/locations/global/keyRings/e2e-test/cryptoKeys/test} (crane delete $(./cosign triangulate $img)) || true -./cosign generate-key-pair --kms $TEST_KMS +COSIGN_KMS=$TEST_KMS ./cosign generate-key-pair signing_key=$TEST_KMS if (./cosign verify --key ${verification_key} $img); then false; fi -./cosign sign --key ${signing_key} $img -./cosign verify --key ${verification_key} $img +COSIGN_KEY=${signing_key} ./cosign sign $img +COSIGN_KEY=${verification_key} ./cosign verify $img if (./cosign verify -a foo=bar --key ${verification_key} $img); then false; fi -./cosign sign --key ${signing_key} -a foo=bar $img -./cosign verify --key ${verification_key} -a foo=bar $img +COSIGN_KEY=${signing_key} ./cosign sign -a foo=bar $img +COSIGN_KEY=${verification_key} ./cosign verify -a foo=bar $img # store signatures in a different repo export COSIGN_REPOSITORY=${TEST_INSTANCE_REPO}/subbedrepo (crane delete $(./cosign triangulate $img)) || true -./cosign sign --key ${signing_key} $img -./cosign verify --key ${verification_key} $img +COSIGN_KEY=${signing_key} ./cosign sign $img +COSIGN_KEY=${verification_key} ./cosign verify $img unset COSIGN_REPOSITORY # test stdin interaction for private key password @@ -185,7 +185,7 @@ stdin_password=${COSIGN_PASSWORD} unset COSIGN_PASSWORD (crane delete $(./cosign triangulate $img)) || true echo $stdin_password | ./cosign sign --key ${signing_key} --output-signature interactive.sig $img -./cosign verify --key ${verification_key} --signature interactive.sig $img +COSIGN_KEY=${verification_key} COSIGN_SIGNATURE=interactive.sig ./cosign verify $img export COSIGN_PASSWORD=${stdin_password} # What else needs auth? diff --git a/test/sign_blob_test.sh b/test/sign_blob_test.sh index 06f2d744250..621ad72d136 100755 --- a/test/sign_blob_test.sh +++ b/test/sign_blob_test.sh @@ -34,6 +34,9 @@ $COSIGN_CLI sign-blob --output-certificate blob.cert --output-signature blob.sig echo "Verifying ..." $COSIGN_CLI verify-blob --signature blob.sig --cert blob.cert $BLOB +echo "Verifying using cosign ENV variables..." +COSIGN_SIGNATURE=blob.sig COSIGN_CERTIFICATE=blob.cert $COSIGN_CLI verify-blob $BLOB + # Now, sign the blob with a self-signed certificate and upload to rekor SIG_FILE=verify-experimental-signature @@ -79,3 +82,6 @@ curl -X POST https://rekor.sigstore.dev/api/v1/log/entries -H 'Content-Type: app # Verifying should still work echo "Verifying ..." $COSIGN_CLI verify-blob --signature "$SIG_FILE" --cert "$CERT_FILE" --certificate-chain "$CERT_FILE" "$BLOB" + +echo "Verifying using cosign ENV variables ..." +COSIGN_SIGNATURE="$SIG_FILE" COSIGN_CERTIFICATE_CHAIN="$CERT_FILE" COSIGN_CERTIFICATE="$CERT_FILE" $COSIGN_CLI verify-blob "$BLOB" From eedf87fed6adfeef88f9349e07438e7f23a30e3d Mon Sep 17 00:00:00 2001 From: Hector Fernandez Date: Tue, 18 Oct 2022 11:10:04 +0200 Subject: [PATCH 3/3] test: validate flag to env func Signed-off-by: Hector Fernandez --- cmd/cosign/cli/options/root_test.go | 59 +++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 cmd/cosign/cli/options/root_test.go diff --git a/cmd/cosign/cli/options/root_test.go b/cmd/cosign/cli/options/root_test.go new file mode 100644 index 00000000000..8810757ad60 --- /dev/null +++ b/cmd/cosign/cli/options/root_test.go @@ -0,0 +1,59 @@ +// +// 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 ( + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestFlagToEnv(t *testing.T) { + testCases := []struct { + flag string + expected string + }{ + { + flag: "rekor-url", + expected: "COSIGN_REKOR_URL", + }, + { + flag: "certificate", + expected: "COSIGN_CERTIFICATE", + }, + { + flag: "k8s-keychain", + expected: "COSIGN_K8S_KEYCHAIN", + }, + { + flag: "output-file", + expected: "COSIGN_OUTPUT_FILE", + }, + { + flag: "sbom", + expected: "COSIGN_SBOM", + }, + } + + for _, tc := range testCases { + t.Run(tc.flag, func(t *testing.T) { + result := flagToEnvVar(tc.flag) + if diff := cmp.Diff(result, tc.expected); diff != "" { + t.Fatal(diff) + } + }) + } +}