Skip to content

Commit

Permalink
setting creation timestamp behind a feature flag to preserve current …
Browse files Browse the repository at this point in the history
…behavior

Signed-off-by: Tobias Trabelsi <[email protected]>
  • Loading branch information
Lerentis committed Mar 5, 2024
1 parent c13b425 commit 21ec318
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 33 deletions.
3 changes: 3 additions & 0 deletions cmd/cosign/cli/options/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type SignOptions struct {
TSAServerURL string
IssueCertificate bool
SignContainerIdentity string
HonorCreateTimestamp bool

Rekor RekorOptions
Fulcio FulcioOptions
Expand Down Expand Up @@ -130,4 +131,6 @@ func (o *SignOptions) AddFlags(cmd *cobra.Command) {

cmd.Flags().StringVar(&o.SignContainerIdentity, "sign-container-identity", "",
"manually set the .critical.docker-reference field for the signed identity, which is useful when image proxies are being used where the pull reference should match the signature")

cmd.Flags().BoolVar(&o.HonorCreateTimestamp, "honor-create-timestamp", false, "honor the create timestamp in the signature artefact to be pushed to the OCI registry")
}
5 changes: 4 additions & 1 deletion cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ race conditions or (worse) malicious tampering.
cosign sign --key cosign.key --tlog-upload=false <IMAGE DIGEST>
# sign a container image by manually setting the container image identity
cosign sign --sign-container-identity <NEW IMAGE DIGEST> <IMAGE DIGEST>`,
cosign sign --sign-container-identity <NEW IMAGE DIGEST> <IMAGE DIGEST>
# sign a container image and honor the creation timestamp of the signature
cosign sign --key cosign.key --honor-create-timestamp <IMAGE DIGEST>`,

Args: cobra.MinimumNArgs(1),
PersistentPreRun: options.BindViper,
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko opti
}

// Attach the signature to the entity.
newSE, err := mutate.AttachSignatureToEntity(se, ociSig, mutate.WithDupeDetector(dd))
newSE, err := mutate.AttachSignatureToEntity(se, ociSig, mutate.WithDupeDetector(dd), mutate.WithHonorCreationTimestamp(signOpts.HonorCreateTimestamp))
if err != nil {
return err
}
Expand Down
4 changes: 4 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: 1 addition & 1 deletion pkg/oci/mutate/mutate.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,5 +377,5 @@ func (so *signOpts) dedupeAndReplace(sig oci.Signature, basefn func() (oci.Signa
}
return ReplaceSignatures(replace)
}
return AppendSignatures(base, sig)
return AppendSignatures(base, so.hct, sig)
}
11 changes: 9 additions & 2 deletions pkg/oci/mutate/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ type ReplaceOp interface {
type SignOption func(*signOpts)

type signOpts struct {
dd DupeDetector
ro ReplaceOp
dd DupeDetector
ro ReplaceOp
hct bool
}

func makeSignOpts(opts ...SignOption) *signOpts {
Expand All @@ -59,6 +60,12 @@ func WithReplaceOp(ro ReplaceOp) SignOption {
}
}

func WithHonorCreationTimestamp(hct bool) SignOption {
return func(so *signOpts) {
so.hct = hct
}
}

type signatureOpts struct {
annotations map[string]string
bundle *bundle.RekorBundle
Expand Down
20 changes: 11 additions & 9 deletions pkg/oci/mutate/signatures.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

// AppendSignatures produces a new oci.Signatures with the provided signatures
// appended to the provided base signatures.
func AppendSignatures(base oci.Signatures, sigs ...oci.Signature) (oci.Signatures, error) {
func AppendSignatures(base oci.Signatures, honorTimestamp bool, sigs ...oci.Signature) (oci.Signatures, error) {
adds := make([]mutate.Addendum, 0, len(sigs))
for _, sig := range sigs {
ann, err := sig.Annotations()
Expand All @@ -43,15 +43,17 @@ func AppendSignatures(base oci.Signatures, sigs ...oci.Signature) (oci.Signature
return nil, err
}

t, err := now.Now()
if err != nil {
return nil, err
}
if honorTimestamp {
t, err := now.Now()
if err != nil {
return nil, err
}

// Set the Created date to time of execution
img, err = mutate.CreatedAt(img, v1.Time{Time: t})
if err != nil {
return nil, err
// Set the Created date to time of execution
img, err = mutate.CreatedAt(img, v1.Time{Time: t})
if err != nil {
return nil, err
}
}

return &sigAppender{
Expand Down
12 changes: 9 additions & 3 deletions pkg/oci/mutate/signatures_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ func TestAppendSignatures(t *testing.T) {
t.Fatalf("NewSignature() = %v", err)
}

oneSig, err := AppendSignatures(base, s1)
oneSig, err := AppendSignatures(base, false, s1)
if err != nil {
t.Fatalf("AppendSignatures() = %v", err)
}

twoSig, err := AppendSignatures(oneSig, s2)
twoSig, err := AppendSignatures(oneSig, false, s2)
if err != nil {
t.Fatalf("AppendSignatures() = %v", err)
}

threeSig, err := AppendSignatures(oneSig, s2, s3)
threeSig, err := AppendSignatures(oneSig, true, s2, s3)
if err != nil {
t.Fatalf("AppendSignatures() = %v", err)
}
Expand Down Expand Up @@ -76,4 +76,10 @@ func TestAppendSignatures(t *testing.T) {
} else if testCfg.Created.Time.IsZero() {
t.Errorf("Date of Signature was Zero")
}

if testDefaultCfg, err := twoSig.ConfigFile(); err != nil {
t.Fatalf("ConfigFile() = %v", err)
} else if !testDefaultCfg.Created.Time.IsZero() {
t.Errorf("Date of Signature was Zero")
}
}
19 changes: 11 additions & 8 deletions pkg/oci/static/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,19 @@ func NewFile(payload []byte, opts ...Option) (oci.File, error) {
// Add annotations from options
img = mutate.Annotations(img, o.Annotations).(v1.Image)

t, err := now.Now()
if err != nil {
return nil, err
}
if o.HonorCreateTimestamp {
t, err := now.Now()
if err != nil {
return nil, err
}

// Set the Created date to time of execution
img, err = mutate.CreatedAt(img, v1.Time{Time: t})
if err != nil {
return nil, err
// Set the Created date to time of execution
img, err = mutate.CreatedAt(img, v1.Time{Time: t})
if err != nil {
return nil, err
}
}

return &file{
SignedImage: signed.Image(img),
layer: layer,
Expand Down
15 changes: 14 additions & 1 deletion pkg/oci/static/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ func TestNewFile(t *testing.T) {
t.Fatalf("NewFile() = %v", err)
}

timestampedFile, err := NewFile([]byte(payload), WithLayerMediaType("foo"), WithAnnotations(map[string]string{"foo": "bar"}), WithHonorCreationTimestamp(true))

if err != nil {
t.Fatalf("NewFile() = %v", err)
}

layers, err := file.Layers()
if err != nil {
t.Fatalf("Layers() = %v", err)
Expand Down Expand Up @@ -126,7 +132,14 @@ func TestNewFile(t *testing.T) {
if err != nil {
t.Fatalf("ConfigFile() = %v", err)
}
if fileCfg.Created.Time.IsZero() {
if !fileCfg.Created.Time.IsZero() {
t.Errorf("Date of Signature was not Zero")
}
tsCfg, err := timestampedFile.ConfigFile()
if err != nil {
t.Fatalf("ConfigFile() = %v", err)
}
if tsCfg.Created.Time.IsZero() {
t.Errorf("Date of Signature was Zero")
}
})
Expand Down
22 changes: 15 additions & 7 deletions pkg/oci/static/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ import (
type Option func(*options)

type options struct {
LayerMediaType types.MediaType
ConfigMediaType types.MediaType
Bundle *bundle.RekorBundle
RFC3161Timestamp *bundle.RFC3161Timestamp
Cert []byte
Chain []byte
Annotations map[string]string
LayerMediaType types.MediaType
ConfigMediaType types.MediaType
Bundle *bundle.RekorBundle
RFC3161Timestamp *bundle.RFC3161Timestamp
Cert []byte
Chain []byte
Annotations map[string]string
HonorCreateTimestamp bool
}

func makeOptions(opts ...Option) (*options, error) {
Expand Down Expand Up @@ -112,3 +113,10 @@ func WithCertChain(cert, chain []byte) Option {
o.Chain = chain
}
}

// WithHonorCreationTimestamp sets the feature flag to honor the creation timestamp to time of running
func WithHonorCreationTimestamp(hct bool) Option {
return func(o *options) {
o.HonorCreateTimestamp = hct
}
}

0 comments on commit 21ec318

Please sign in to comment.