Skip to content

Commit cb01516

Browse files
authored
Honor creation timestamp for signatures again (#3549)
* Honor creation timestamp for signatures again Signed-off-by: ttrabelsi <[email protected]> * setting creation timestamp behind a feature flag to preserve current behavior Signed-off-by: Tobias Trabelsi <[email protected]> * review feedback Signed-off-by: Tobias Trabelsi <[email protected]> * additional review feedback Signed-off-by: Tobias Trabelsi <[email protected]> --------- Signed-off-by: ttrabelsi <[email protected]> Signed-off-by: Tobias Trabelsi <[email protected]>
1 parent fb488d7 commit cb01516

File tree

11 files changed

+110
-38
lines changed

11 files changed

+110
-38
lines changed

cmd/cosign/cli/options/sign.go

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,27 @@ import (
2121

2222
// SignOptions is the top level wrapper for the sign command.
2323
type SignOptions struct {
24-
Key string
25-
Cert string
26-
CertChain string
27-
Upload bool
28-
Output string // deprecated: TODO remove when the output flag is fully deprecated
29-
OutputSignature string // TODO: this should be the root output file arg.
30-
OutputPayload string
31-
OutputCertificate string
32-
PayloadPath string
33-
Recursive bool
34-
Attachment string
35-
SkipConfirmation bool
36-
TlogUpload bool
37-
TSAClientCACert string
38-
TSAClientCert string
39-
TSAClientKey string
40-
TSAServerName string
41-
TSAServerURL string
42-
IssueCertificate bool
43-
SignContainerIdentity string
24+
Key string
25+
Cert string
26+
CertChain string
27+
Upload bool
28+
Output string // deprecated: TODO remove when the output flag is fully deprecated
29+
OutputSignature string // TODO: this should be the root output file arg.
30+
OutputPayload string
31+
OutputCertificate string
32+
PayloadPath string
33+
Recursive bool
34+
Attachment string
35+
SkipConfirmation bool
36+
TlogUpload bool
37+
TSAClientCACert string
38+
TSAClientCert string
39+
TSAClientKey string
40+
TSAServerName string
41+
TSAServerURL string
42+
IssueCertificate bool
43+
SignContainerIdentity string
44+
RecordCreationTimestamp bool
4445

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

131132
cmd.Flags().StringVar(&o.SignContainerIdentity, "sign-container-identity", "",
132133
"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")
134+
135+
cmd.Flags().BoolVar(&o.RecordCreationTimestamp, "record-creation-timestamp", false, "set the createdAt timestamp in the signature artifact to the time it was created; by default, cosign sets this to the zero value")
133136
}

cmd/cosign/cli/sign.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ race conditions or (worse) malicious tampering.
8383
cosign sign --key cosign.key --tlog-upload=false <IMAGE DIGEST>
8484
8585
# sign a container image by manually setting the container image identity
86-
cosign sign --sign-container-identity <NEW IMAGE DIGEST> <IMAGE DIGEST>`,
86+
cosign sign --sign-container-identity <NEW IMAGE DIGEST> <IMAGE DIGEST>
87+
88+
# sign a container image and honor the creation timestamp of the signature
89+
cosign sign --key cosign.key --record-creation-timestamp <IMAGE DIGEST>`,
8790

8891
Args: cobra.MinimumNArgs(1),
8992
PersistentPreRun: options.BindViper,

cmd/cosign/cli/sign/sign.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko opti
329329
}
330330

331331
// Attach the signature to the entity.
332-
newSE, err := mutate.AttachSignatureToEntity(se, ociSig, mutate.WithDupeDetector(dd))
332+
newSE, err := mutate.AttachSignatureToEntity(se, ociSig, mutate.WithDupeDetector(dd), mutate.WithRecordCreationTimestamp(signOpts.RecordCreationTimestamp))
333333
if err != nil {
334334
return err
335335
}

doc/cosign_sign.md

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/oci/mutate/mutate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,5 +377,5 @@ func (so *signOpts) dedupeAndReplace(sig oci.Signature, basefn func() (oci.Signa
377377
}
378378
return ReplaceSignatures(replace)
379379
}
380-
return AppendSignatures(base, sig)
380+
return AppendSignatures(base, so.rct, sig)
381381
}

pkg/oci/mutate/options.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ type ReplaceOp interface {
3333
type SignOption func(*signOpts)
3434

3535
type signOpts struct {
36-
dd DupeDetector
37-
ro ReplaceOp
36+
dd DupeDetector
37+
ro ReplaceOp
38+
rct bool
3839
}
3940

4041
func makeSignOpts(opts ...SignOption) *signOpts {
@@ -59,6 +60,12 @@ func WithReplaceOp(ro ReplaceOp) SignOption {
5960
}
6061
}
6162

63+
func WithRecordCreationTimestamp(rct bool) SignOption {
64+
return func(so *signOpts) {
65+
so.rct = rct
66+
}
67+
}
68+
6269
type signatureOpts struct {
6370
annotations map[string]string
6471
bundle *bundle.RekorBundle

pkg/oci/mutate/signatures.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ import (
1919
v1 "github.com/google/go-containerregistry/pkg/v1"
2020
"github.com/google/go-containerregistry/pkg/v1/empty"
2121
"github.com/google/go-containerregistry/pkg/v1/mutate"
22+
"github.com/sigstore/cosign/v2/internal/pkg/now"
2223
"github.com/sigstore/cosign/v2/pkg/oci"
2324
)
2425

2526
// AppendSignatures produces a new oci.Signatures with the provided signatures
2627
// appended to the provided base signatures.
27-
func AppendSignatures(base oci.Signatures, sigs ...oci.Signature) (oci.Signatures, error) {
28+
func AppendSignatures(base oci.Signatures, recordCreationTimestamp bool, sigs ...oci.Signature) (oci.Signatures, error) {
2829
adds := make([]mutate.Addendum, 0, len(sigs))
2930
for _, sig := range sigs {
3031
ann, err := sig.Annotations()
@@ -42,6 +43,19 @@ func AppendSignatures(base oci.Signatures, sigs ...oci.Signature) (oci.Signature
4243
return nil, err
4344
}
4445

46+
if recordCreationTimestamp {
47+
t, err := now.Now()
48+
if err != nil {
49+
return nil, err
50+
}
51+
52+
// Set the Created date to time of execution
53+
img, err = mutate.CreatedAt(img, v1.Time{Time: t})
54+
if err != nil {
55+
return nil, err
56+
}
57+
}
58+
4559
return &sigAppender{
4660
Image: img,
4761
base: base,

pkg/oci/mutate/signatures_test.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ func TestAppendSignatures(t *testing.T) {
3838
t.Fatalf("NewSignature() = %v", err)
3939
}
4040

41-
oneSig, err := AppendSignatures(base, s1)
41+
oneSig, err := AppendSignatures(base, false, s1)
4242
if err != nil {
4343
t.Fatalf("AppendSignatures() = %v", err)
4444
}
4545

46-
twoSig, err := AppendSignatures(oneSig, s2)
46+
twoSig, err := AppendSignatures(oneSig, false, s2)
4747
if err != nil {
4848
t.Fatalf("AppendSignatures() = %v", err)
4949
}
5050

51-
threeSig, err := AppendSignatures(oneSig, s2, s3)
51+
threeSig, err := AppendSignatures(oneSig, true, s2, s3)
5252
if err != nil {
5353
t.Fatalf("AppendSignatures() = %v", err)
5454
}
@@ -73,7 +73,13 @@ func TestAppendSignatures(t *testing.T) {
7373

7474
if testCfg, err := threeSig.ConfigFile(); err != nil {
7575
t.Fatalf("ConfigFile() = %v", err)
76-
} else if !testCfg.Created.Time.IsZero() {
77-
t.Errorf("Date of Signature was not Zero")
76+
} else if testCfg.Created.Time.IsZero() {
77+
t.Errorf("Date of Signature was Zero")
78+
}
79+
80+
if testDefaultCfg, err := twoSig.ConfigFile(); err != nil {
81+
t.Fatalf("ConfigFile() = %v", err)
82+
} else if !testDefaultCfg.Created.Time.IsZero() {
83+
t.Errorf("Date of Signature was Zero")
7884
}
7985
}

pkg/oci/static/file.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/google/go-containerregistry/pkg/v1/empty"
2323
"github.com/google/go-containerregistry/pkg/v1/mutate"
2424
"github.com/google/go-containerregistry/pkg/v1/types"
25+
"github.com/sigstore/cosign/v2/internal/pkg/now"
2526
"github.com/sigstore/cosign/v2/pkg/oci"
2627
"github.com/sigstore/cosign/v2/pkg/oci/signed"
2728
)
@@ -48,6 +49,19 @@ func NewFile(payload []byte, opts ...Option) (oci.File, error) {
4849
// Add annotations from options
4950
img = mutate.Annotations(img, o.Annotations).(v1.Image)
5051

52+
if o.RecordCreationTimestamp {
53+
t, err := now.Now()
54+
if err != nil {
55+
return nil, err
56+
}
57+
58+
// Set the Created date to time of execution
59+
img, err = mutate.CreatedAt(img, v1.Time{Time: t})
60+
if err != nil {
61+
return nil, err
62+
}
63+
}
64+
5165
return &file{
5266
SignedImage: signed.Image(img),
5367
layer: layer,

pkg/oci/static/file_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ func TestNewFile(t *testing.T) {
3232
t.Fatalf("NewFile() = %v", err)
3333
}
3434

35+
timestampedFile, err := NewFile([]byte(payload), WithLayerMediaType("foo"), WithAnnotations(map[string]string{"foo": "bar"}), WithRecordCreationTimestamp(true))
36+
37+
if err != nil {
38+
t.Fatalf("NewFile() = %v", err)
39+
}
40+
3541
layers, err := file.Layers()
3642
if err != nil {
3743
t.Fatalf("Layers() = %v", err)
@@ -129,6 +135,13 @@ func TestNewFile(t *testing.T) {
129135
if !fileCfg.Created.Time.IsZero() {
130136
t.Errorf("Date of Signature was not Zero")
131137
}
138+
tsCfg, err := timestampedFile.ConfigFile()
139+
if err != nil {
140+
t.Fatalf("ConfigFile() = %v", err)
141+
}
142+
if tsCfg.Created.Time.IsZero() {
143+
t.Errorf("Date of Signature was Zero")
144+
}
132145
})
133146

134147
t.Run("check annotations", func(t *testing.T) {

0 commit comments

Comments
 (0)