Skip to content
Open
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
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ The following checks were performed on these signatures:
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":"cosign container image signature"},"Optional":null}
```

### Sign a container offline with a private key

To sign without contacting Sigstore network services, use the `--offline` flag with a private key:

```shell
cosign sign --key cosign.key --offline $IMAGE
```

Similarly, to sign a local file/blob offline:

```shell
cosign sign-blob --key cosign.key --offline --bundle artifact.sigstore.json artifact
```

**Note:** Offline signing requires a private key. When signing offline, key usage is not recorded in a transparency log and therefore not auditable.

### Verify a container in an air-gapped environment

**Note:** This section is out of date.
Expand Down
12 changes: 8 additions & 4 deletions cmd/cosign/cli/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ func Attest() *cobra.Command {
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := signcommon.ValidateSigningOptions(cmd.Context(), o.Offline,
o.Rekor.URL, o.Fulcio.URL, o.OIDC.Issuer, o.TSAServerURL,
o.TlogUpload, o.NewBundleFormat, "", o.Key, o.IssueCertificate,
"", "", "", "", "", ""); err != nil {
return err
}

oidcClientSecret, err := o.OIDC.ClientSecret()
if err != nil {
return err
Expand Down Expand Up @@ -105,10 +112,7 @@ func Attest() *cobra.Command {
BundlePath: o.BundlePath,
NewBundleFormat: o.NewBundleFormat,
}
if err := signcommon.LoadTrustedMaterialAndSigningConfig(cmd.Context(), &ko, o.UseSigningConfig, o.SigningConfigPath,
o.Rekor.URL, o.Fulcio.URL, o.OIDC.Issuer, o.TSAServerURL, o.TrustedRootPath, o.TlogUpload,
o.NewBundleFormat, "", o.Key, o.IssueCertificate,
"", "", "", "", "", ""); err != nil {
if err := signcommon.LoadTrustedMaterialAndSigningConfig(cmd.Context(), &ko, o.Offline, o.SigningConfigPath, o.TrustedRootPath); err != nil {
return err
}

Expand Down
12 changes: 8 additions & 4 deletions cmd/cosign/cli/attest_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ func AttestBlob() *cobra.Command {
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := signcommon.ValidateSigningOptions(cmd.Context(), o.Offline,
o.Rekor.URL, o.Fulcio.URL, o.OIDC.Issuer, o.TSAServerURL,
o.TlogUpload, o.NewBundleFormat, o.BundlePath, o.Key, o.IssueCertificate,
"", o.OutputAttestation, o.OutputCertificate, "", o.OutputSignature, o.RFC3161TimestampPath); err != nil {
return err
}

if o.Predicate.Statement == "" && len(args) != 1 {
return cobra.ExactArgs(1)(cmd, args)
}
Expand Down Expand Up @@ -92,10 +99,7 @@ func AttestBlob() *cobra.Command {
BundlePath: o.BundlePath,
NewBundleFormat: o.NewBundleFormat,
}
if err := signcommon.LoadTrustedMaterialAndSigningConfig(cmd.Context(), &ko, o.UseSigningConfig, o.SigningConfigPath,
o.Rekor.URL, o.Fulcio.URL, o.OIDC.Issuer, o.TSAServerURL, o.TrustedRootPath, o.TlogUpload,
o.NewBundleFormat, o.BundlePath, o.Key, o.IssueCertificate,
"", o.OutputAttestation, o.OutputCertificate, "", o.OutputSignature, o.RFC3161TimestampPath); err != nil {
if err := signcommon.LoadTrustedMaterialAndSigningConfig(cmd.Context(), &ko, o.Offline, o.SigningConfigPath, o.TrustedRootPath); err != nil {
return err
}

Expand Down
12 changes: 6 additions & 6 deletions cmd/cosign/cli/options/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type AttestOptions struct {
RecordCreationTimestamp bool
BundlePath string
NewBundleFormat bool
UseSigningConfig bool
Offline bool
SigningConfigPath string
TrustedRootPath string

Expand Down Expand Up @@ -129,15 +129,15 @@ func (o *AttestOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&o.NewBundleFormat, "new-bundle-format", true, "attach a Sigstore bundle using OCI referrers API")
_ = cmd.Flags().MarkDeprecated("new-bundle-format", "this will be the only supported format in future versions")

cmd.Flags().BoolVar(&o.UseSigningConfig, "use-signing-config", true,
"whether to use a TUF-provided signing config for the service URLs")
_ = cmd.Flags().MarkDeprecated("use-signing-config", "an offline signing flag will be added in the future; TUF will continue to provide a signing config by default if one is not provided manually")
cmd.Flags().BoolVar(&o.Offline, "offline", false,
"only allow offline signing with a local key without contacting network services. Key usage is not logged and therefore not auditable")

cmd.Flags().StringVar(&o.SigningConfigPath, "signing-config", "",
"path to a signing config file")

cmd.MarkFlagsMutuallyExclusive("use-signing-config", "signing-config")

cmd.Flags().StringVar(&o.TrustedRootPath, "trusted-root", "",
"optional path to a TrustedRoot JSON file to verify a signature after signing")

cmd.MarkFlagsMutuallyExclusive("offline", "signing-config")
cmd.MarkFlagsMutuallyExclusive("offline", "trusted-root")
}
12 changes: 6 additions & 6 deletions cmd/cosign/cli/options/attest_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type AttestBlobOptions struct {
OIDC OIDCOptions
SecurityKey SecurityKeyOptions

UseSigningConfig bool
Offline bool
SigningConfigPath string
TrustedRootPath string
}
Expand Down Expand Up @@ -105,18 +105,18 @@ func (o *AttestBlobOptions) AddFlags(cmd *cobra.Command) {
"output bundle in new format that contains all verification material")
_ = cmd.Flags().MarkDeprecated("new-bundle-format", "this will be the only supported format in future versions")

cmd.Flags().BoolVar(&o.UseSigningConfig, "use-signing-config", true,
"whether to use a TUF-provided signing config for the service URLs. Must provide --bundle, which will output verification material in the new format")
_ = cmd.Flags().MarkDeprecated("use-signing-config", "an offline signing flag will be added in the future; TUF will continue to provide a signing config by default if one is not provided manually")
cmd.Flags().BoolVar(&o.Offline, "offline", false,
"only allow offline signing with a local key without contacting network services. Key usage is not logged and therefore not auditable")

cmd.Flags().StringVar(&o.SigningConfigPath, "signing-config", "",
"path to a signing config file. Must provide --bundle, which will output verification material in the new format")

cmd.MarkFlagsMutuallyExclusive("use-signing-config", "signing-config")

cmd.Flags().StringVar(&o.TrustedRootPath, "trusted-root", "",
"optional path to a TrustedRoot JSON file to verify a signature after signing")

cmd.MarkFlagsMutuallyExclusive("offline", "signing-config")
cmd.MarkFlagsMutuallyExclusive("offline", "trusted-root")

cmd.Flags().StringVar(&o.Hash, "hash", "",
"hash of blob in hexadecimal (base16). Used if you want to sign an artifact stored elsewhere and have the hash")
_ = cmd.RegisterFlagCompletionFunc("hash", cobra.NoFileCompletions)
Expand Down
12 changes: 6 additions & 6 deletions cmd/cosign/cli/options/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type SignOptions struct {
SignContainerIdentities []string
RecordCreationTimestamp bool
NewBundleFormat bool
UseSigningConfig bool
Offline bool
SigningConfigPath string
TrustedRootPath string

Expand Down Expand Up @@ -161,15 +161,15 @@ func (o *SignOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&o.NewBundleFormat, "new-bundle-format", true, "expect the signature/attestation to be packaged in a Sigstore bundle")
_ = cmd.Flags().MarkDeprecated("new-bundle-format", "this will be the only supported format in future versions")

cmd.Flags().BoolVar(&o.UseSigningConfig, "use-signing-config", true,
"whether to use a TUF-provided signing config for the service URLs")
_ = cmd.Flags().MarkDeprecated("use-signing-config", "an offline signing flag will be added in the future; TUF will continue to provide a signing config by default if one is not provided manually")
cmd.Flags().BoolVar(&o.Offline, "offline", false,
"only allow offline signing with a local key without contacting network services. Key usage is not logged and therefore not auditable")

cmd.Flags().StringVar(&o.SigningConfigPath, "signing-config", "",
"path to a signing config file")

cmd.MarkFlagsMutuallyExclusive("use-signing-config", "signing-config")

cmd.Flags().StringVar(&o.TrustedRootPath, "trusted-root", "",
"optional path to a TrustedRoot JSON file to verify a signature after signing")

cmd.MarkFlagsMutuallyExclusive("offline", "signing-config")
cmd.MarkFlagsMutuallyExclusive("offline", "trusted-root")
}
12 changes: 6 additions & 6 deletions cmd/cosign/cli/options/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type SignBlobOptions struct {
IssueCertificate bool
SigningAlgorithm string

UseSigningConfig bool
Offline bool
SigningConfigPath string
TrustedRootPath string
}
Expand Down Expand Up @@ -109,18 +109,18 @@ func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) {
"output bundle in new format that contains all verification material")
_ = cmd.Flags().MarkDeprecated("new-bundle-format", "this will be the only supported format in future versions")

cmd.Flags().BoolVar(&o.UseSigningConfig, "use-signing-config", true,
"whether to use a TUF-provided signing config for the service URLs. Must provide --bundle, which will output verification material in the new format")
_ = cmd.Flags().MarkDeprecated("use-signing-config", "an offline signing flag will be added in the future; TUF will continue to provide a signing config by default if one is not provided manually")
cmd.Flags().BoolVar(&o.Offline, "offline", false,
"only allow offline signing with a local key without contacting network services. Key usage is not logged and therefore not auditable")

cmd.Flags().StringVar(&o.SigningConfigPath, "signing-config", "",
"path to a signing config file. Must provide --bundle, which will output verification material in the new format")

cmd.MarkFlagsMutuallyExclusive("use-signing-config", "signing-config")

cmd.Flags().StringVar(&o.TrustedRootPath, "trusted-root", "",
"optional path to a TrustedRoot JSON file to verify a signature after signing")

cmd.MarkFlagsMutuallyExclusive("offline", "signing-config")
cmd.MarkFlagsMutuallyExclusive("offline", "trusted-root")

cmd.Flags().BoolVarP(&o.SkipConfirmation, "yes", "y", false,
"skip confirmation prompts for non-destructive operations")

Expand Down
11 changes: 8 additions & 3 deletions cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ race conditions or (worse) malicious tampering.
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := signcommon.ValidateSigningOptions(cmd.Context(), o.Offline,
o.Rekor.URL, o.Fulcio.URL, o.OIDC.Issuer, o.TSAServerURL,
o.TlogUpload, o.NewBundleFormat, "", o.Key, o.IssueCertificate,
o.Output, "", o.OutputCertificate, o.OutputPayload, o.OutputSignature, ""); err != nil {
return err
}

switch o.Attachment {
case "sbom":
fmt.Fprintln(os.Stderr, options.SBOMAttachmentDeprecation)
Expand Down Expand Up @@ -132,9 +139,7 @@ race conditions or (worse) malicious tampering.
IssueCertificateForExistingKey: o.IssueCertificate,
NewBundleFormat: o.NewBundleFormat,
}
if err := signcommon.LoadTrustedMaterialAndSigningConfig(cmd.Context(), &ko, o.UseSigningConfig, o.SigningConfigPath,
o.Rekor.URL, o.Fulcio.URL, o.OIDC.Issuer, o.TSAServerURL, o.TrustedRootPath, o.TlogUpload,
o.NewBundleFormat, "", o.Key, o.IssueCertificate, o.Output, "", o.OutputCertificate, o.OutputPayload, o.OutputSignature, ""); err != nil {
if err := signcommon.LoadTrustedMaterialAndSigningConfig(cmd.Context(), &ko, o.Offline, o.SigningConfigPath, o.TrustedRootPath); err != nil {
return err
}

Expand Down
19 changes: 5 additions & 14 deletions cmd/cosign/cli/sign/sign_blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import (

"github.com/secure-systems-lab/go-securesystemslib/encrypted"
"github.com/sigstore/cosign/v3/cmd/cosign/cli/options"
"github.com/sigstore/cosign/v3/cmd/cosign/cli/signcommon"
"github.com/sigstore/cosign/v3/internal/test"
"github.com/sigstore/cosign/v3/pkg/cosign"
"github.com/sigstore/sigstore-go/pkg/root"
)

func TestSignBlobCmd(t *testing.T) {
Expand Down Expand Up @@ -105,20 +105,11 @@ func TestSignBlobCmd(t *testing.T) {

// Test signing using Ed25519 key with custom signing config and no transparency log upload
edKeyRef := writeFile(t, td, string(pemBytes), "ed_key.pem")
keyOpts = options.KeyOpts{KeyRef: edKeyRef, BundlePath: bundlePath}
sc, err := root.NewSigningConfig(
root.SigningConfigMediaType02,
nil,
nil,
nil,
root.ServiceConfiguration{},
nil,
root.ServiceConfiguration{},
)
if err != nil {
t.Fatal(err)
keyOpts = options.KeyOpts{
KeyRef: edKeyRef,
BundlePath: bundlePath,
SigningConfig: signcommon.NewEmptySigningConfig(),
}
keyOpts.SigningConfig = sc
sigBytes, err := SignBlobCmd(t.Context(), rootOpts, keyOpts, blobPath, "", "", true, "", "", true)
if err != nil {
t.Fatalf("unexpected error %v", err)
Expand Down
12 changes: 8 additions & 4 deletions cmd/cosign/cli/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ func SignBlob() *cobra.Command {
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := signcommon.ValidateSigningOptions(cmd.Context(), o.Offline,
o.Rekor.URL, o.Fulcio.URL, o.OIDC.Issuer, o.TSAServerURL,
o.TlogUpload, o.NewBundleFormat, o.BundlePath, o.Key, o.IssueCertificate,
o.Output, "", o.OutputCertificate, "", o.OutputSignature, o.RFC3161TimestampPath); err != nil {
return err
}

oidcClientSecret, err := o.OIDC.ClientSecret()
if err != nil {
return err
Expand Down Expand Up @@ -115,10 +122,7 @@ func SignBlob() *cobra.Command {
IssueCertificateForExistingKey: o.IssueCertificate,
SigningAlgorithm: o.SigningAlgorithm,
}
if err := signcommon.LoadTrustedMaterialAndSigningConfig(cmd.Context(), &ko, o.UseSigningConfig, o.SigningConfigPath,
o.Rekor.URL, o.Fulcio.URL, o.OIDC.Issuer, o.TSAServerURL, o.TrustedRootPath, o.TlogUpload,
o.NewBundleFormat, o.BundlePath, o.Key, o.IssueCertificate,
o.Output, "", o.OutputCertificate, "", o.OutputSignature, o.RFC3161TimestampPath); err != nil {
if err := signcommon.LoadTrustedMaterialAndSigningConfig(cmd.Context(), &ko, o.Offline, o.SigningConfigPath, o.TrustedRootPath); err != nil {
return err
}

Expand Down
Loading
Loading