Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Included timeout option for uploading to Rekor #1001

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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