Skip to content

Commit

Permalink
Included timeout option for uploading to Rekor (#1001)
Browse files Browse the repository at this point in the history
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
  • Loading branch information
naveensrinivasan committed Nov 9, 2021
1 parent d3440b5 commit d442592
Show file tree
Hide file tree
Showing 14 changed files with 55 additions and 23 deletions.
5 changes: 3 additions & 2 deletions cmd/cosign/cli/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func Attest() *cobra.Command {
Example: ` cosign attest --key <key path>|<kms uri> [--predicate <path>] [--a key=value] [--upload=true|false] [--f] [--r] <image uri>
# attach an attestation to a container image Google sign-in (experimental)
COSIGN_EXPERIMENTAL=1 cosign attest --predicate <FILE> --type <TYPE> <IMAGE>
COSIGN_EXPERIMENTAL=1 cosign attest --timeout 90s --predicate <FILE> --type <TYPE> <IMAGE>
# attach an attestation to a container image with a local key pair file
cosign attest --predicate <FILE> --type <TYPE> --key cosign.key <IMAGE>
Expand Down Expand Up @@ -70,7 +70,8 @@ func Attest() *cobra.Command {
OIDCClientSecret: o.OIDC.ClientSecret,
}
for _, img := range args {
if err := attest.AttestCmd(cmd.Context(), ko, o.Registry, img, o.Cert, o.NoUpload, o.Predicate.Path, o.Force, o.Predicate.Type); err != nil {
if err := attest.AttestCmd(cmd.Context(), ko, o.Registry, img, o.Cert, o.NoUpload,
o.Predicate.Path, o.Force, o.Predicate.Type, o.Timeout); err != nil {
return errors.Wrapf(err, "signing %s", img)
}
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/cosign/cli/attest/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"encoding/json"
"fmt"
"os"
"time"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
Expand All @@ -44,7 +45,7 @@ import (

//nolint
func AttestCmd(ctx context.Context, ko sign.KeyOpts, regOpts options.RegistryOptions, imageRef string, certPath string,
noUpload bool, predicatePath string, force bool, predicateType string) error {
noUpload bool, predicatePath string, force bool, predicateType string, timeout time.Duration) error {
// A key file or token is required unless we're in experimental mode!
if options.EnableExperimental() {
if options.NOf(ko.KeyRef, ko.Sk) > 1 {
Expand Down Expand Up @@ -129,7 +130,7 @@ func AttestCmd(ctx context.Context, ko sign.KeyOpts, regOpts options.RegistryOpt
return err
} else if uploadTLog {
bundle, err := sign.UploadToTlog(ctx, sv, ko.RekorURL, func(r *client.Rekor, b []byte) (*models.LogEntryAnon, error) {
return cosign.TLogUploadInTotoAttestation(r, signedPayload, b)
return cosign.TLogUploadInTotoAttestation(r, signedPayload, b, timeout)
})
if err != nil {
return err
Expand Down
6 changes: 6 additions & 0 deletions cmd/cosign/cli/options/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package options

import (
"time"

"github.com/spf13/cobra"
)

Expand All @@ -26,6 +28,7 @@ type AttestOptions struct {
NoUpload bool
Force bool
Recursive bool
Timeout time.Duration

Rekor RekorOptions
Fulcio FulcioOptions
Expand Down Expand Up @@ -60,4 +63,7 @@ func (o *AttestOptions) AddFlags(cmd *cobra.Command) {

cmd.Flags().BoolVarP(&o.Recursive, "recursive", "r", false,
"if a multi-arch image is specified, additionally sign each discrete image")

cmd.Flags().DurationVar(&o.Timeout, "timeout", time.Second*30,
"HTTP Timeout defaults to 30 seconds")
}
7 changes: 7 additions & 0 deletions cmd/cosign/cli/options/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package options

import (
"time"

"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -61,6 +63,7 @@ type PolicySignOptions struct {
Registry RegistryOptions
Fulcio FulcioOptions
Rekor RekorOptions
Timeout time.Duration

OIDC OIDCOptions
}
Expand All @@ -74,6 +77,10 @@ func (o *PolicySignOptions) AddFlags(cmd *cobra.Command) {

cmd.Flags().StringVar(&o.OutFile, "out", "o",
"output policy locally")

cmd.Flags().DurationVar(&o.Timeout, "timeout", time.Second*30,
"HTTP Timeout defaults to 30 seconds")

o.Registry.AddFlags(cmd)
o.Fulcio.AddFlags(cmd)
o.Rekor.AddFlags(cmd)
Expand Down
6 changes: 6 additions & 0 deletions cmd/cosign/cli/options/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package options

import (
"time"

"github.com/spf13/cobra"
)

Expand All @@ -29,6 +31,7 @@ type SignBlobOptions struct {
Rekor RekorOptions
OIDC OIDCOptions
Registry RegistryOptions
Timeout time.Duration
}

var _ Interface = (*SignBlobOptions)(nil)
Expand All @@ -49,4 +52,7 @@ func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) {

cmd.Flags().StringVar(&o.Output, "output", "",
"write the signature to FILE")

cmd.Flags().DurationVar(&o.Timeout, "timeout", time.Second*30,
"HTTP Timeout defaults to 30 seconds")
}
2 changes: 1 addition & 1 deletion cmd/cosign/cli/policy_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func signPolicy() *cobra.Command {
if err != nil {
return err
}
entry, err := cosign.TLogUpload(rekorClient, sig, signed.Signed, rekorBytes)
entry, err := cosign.TLogUpload(rekorClient, sig, signed.Signed, rekorBytes, o.Timeout)
if err != nil {
return err
}
Expand Down
4 changes: 3 additions & 1 deletion cmd/cosign/cli/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
Expand Down Expand Up @@ -245,7 +246,8 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko KeyO
return err
} else if uploadTLog {
bundle, err := UploadToTlog(ctx, sv, ko.RekorURL, func(r *client.Rekor, b []byte) (*models.LogEntryAnon, error) {
return cosign.TLogUpload(r, signature, payload, b)
// TODO - Defaulting the timeout to zero as the CLI doesn't accept timeout.
return cosign.TLogUpload(r, signature, payload, b, time.Duration(0))
})
if err != nil {
return err
Expand Down
5 changes: 3 additions & 2 deletions cmd/cosign/cli/sign/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"io"
"os"
"path/filepath"
"time"

"github.com/pkg/errors"

Expand Down Expand Up @@ -51,7 +52,7 @@ type KeyOpts struct {
}

// nolint
func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOptions, payloadPath string, b64 bool, output string) ([]byte, error) {
func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOptions, payloadPath string, b64 bool, output string, timeout time.Duration) ([]byte, error) {
var payload []byte
var err error

Expand Down Expand Up @@ -93,7 +94,7 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption
if err != nil {
return nil, err
}
entry, err := cosign.TLogUpload(rekorClient, sig, payload, rekorBytes)
entry, err := cosign.TLogUpload(rekorClient, sig, payload, rekorBytes, timeout)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/cosign/cli/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func SignBlob() *cobra.Command {
Example: ` cosign sign-blob --key <key path>|<kms uri> <blob>
# sign a blob with Google sign-in (experimental)
COSIGN_EXPERIMENTAL=1 cosign sign-blob <FILE>
COSIGN_EXPERIMENTAL=1 cosign --timeout 90s sign-blob <FILE>
# sign a blob with a local key pair file
cosign sign-blob --key cosign.key <FILE>
Expand Down Expand Up @@ -74,7 +74,7 @@ func SignBlob() *cobra.Command {
OIDCClientSecret: o.OIDC.ClientSecret,
}
for _, blob := range args {
if _, err := sign.SignBlobCmd(cmd.Context(), ko, o.Registry, blob, o.Base64Output, o.Output); err != nil {
if _, err := sign.SignBlobCmd(cmd.Context(), ko, o.Registry, blob, o.Base64Output, o.Output, o.Timeout); err != nil {
return errors.Wrapf(err, "signing %s", blob)
}
}
Expand Down
3 changes: 2 additions & 1 deletion doc/cosign_attest.md

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

1 change: 1 addition & 0 deletions doc/cosign_policy_sign.md

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

3 changes: 2 additions & 1 deletion doc/cosign_sign-blob.md

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

18 changes: 12 additions & 6 deletions pkg/cosign/tlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"encoding/hex"
"fmt"
"strings"
"time"

"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
Expand Down Expand Up @@ -55,27 +56,32 @@ func GetRekorPub() string {
}

// TLogUpload will upload the signature, public key and payload to the transparency log.
func TLogUpload(rekorClient *client.Rekor, signature, payload []byte, pemBytes []byte) (*models.LogEntryAnon, error) {
func TLogUpload(rekorClient *client.Rekor, signature, payload []byte, pemBytes []byte, timeout time.Duration) (*models.LogEntryAnon, error) {
re := rekorEntry(payload, signature, pemBytes)
returnVal := models.Rekord{
APIVersion: swag.String(re.APIVersion()),
Spec: re.RekordObj,
}
return doUpload(rekorClient, &returnVal)
return doUpload(rekorClient, &returnVal, timeout)
}

// TLogUploadInTotoAttestation will upload and in-toto entry for the signature and public key to the transparency log.
func TLogUploadInTotoAttestation(rekorClient *client.Rekor, signature, pemBytes []byte) (*models.LogEntryAnon, error) {
func TLogUploadInTotoAttestation(rekorClient *client.Rekor, signature, pemBytes []byte, timeout time.Duration) (*models.LogEntryAnon, error) {
e := intotoEntry(signature, pemBytes)
returnVal := models.Intoto{
APIVersion: swag.String(e.APIVersion()),
Spec: e.IntotoObj,
}
return doUpload(rekorClient, &returnVal)
return doUpload(rekorClient, &returnVal, timeout)
}

func doUpload(rekorClient *client.Rekor, pe models.ProposedEntry) (*models.LogEntryAnon, error) {
params := entries.NewCreateLogEntryParams()
func doUpload(rekorClient *client.Rekor, pe models.ProposedEntry, timeout time.Duration) (*models.LogEntryAnon, error) {
var params *entries.CreateLogEntryParams
if timeout != time.Duration(0) {
params = entries.NewCreateLogEntryParamsWithTimeout(timeout)
} else {
params = entries.NewCreateLogEntryParams()
}
params.SetProposedEntry(pe)
resp, err := rekorClient.Entries.CreateLogEntry(params)
if err != nil {
Expand Down
9 changes: 4 additions & 5 deletions test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"path"
"path/filepath"
"testing"
"time"

"github.com/google/go-cmp/cmp"
"github.com/google/go-containerregistry/pkg/authn"
Expand Down Expand Up @@ -183,7 +184,7 @@ func TestAttestVerify(t *testing.T) {
// Now attest the image
ko := sign.KeyOpts{KeyRef: privKeyPath, PassFunc: passFunc}
must(attest.AttestCmd(ctx, ko, options.RegistryOptions{}, imgName, "", false, slsaAttestationPath, false,
"custom"), t)
"custom", time.Duration(30*time.Second)), t)

// Use cue to verify attestation
policyPath := filepath.Join(td, "policy.cue")
Expand Down Expand Up @@ -375,8 +376,7 @@ func TestMultipleSignatures(t *testing.T) {
}

func TestSignBlob(t *testing.T) {

var blob = "someblob"
blob := "someblob"
td1 := t.TempDir()
td2 := t.TempDir()
t.Cleanup(func() {
Expand Down Expand Up @@ -409,7 +409,7 @@ func TestSignBlob(t *testing.T) {
KeyRef: privKeyPath1,
PassFunc: passFunc,
}
sig, err := sign.SignBlobCmd(ctx, ko, options.RegistryOptions{}, bp, true, "")
sig, err := sign.SignBlobCmd(ctx, ko, options.RegistryOptions{}, bp, true, "", time.Duration(30*time.Second))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -557,7 +557,6 @@ func TestUploadDownload(t *testing.T) {
cleanup()
})
}

}

func TestUploadBlob(t *testing.T) {
Expand Down

0 comments on commit d442592

Please sign in to comment.