sigstore-cli 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/sigstore/cli.rb +62 -13
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fb6ae7ecf2b8c666e2f15a7ae9170e2c5b3ed0dc3d17ddd368406b1ca9487503
|
|
4
|
+
data.tar.gz: fc4df628cb9b00abdee837864dfa982371e6deefa14908c14c33f01322112168
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 99e28350dc70c09cf048160cfc415bd2c3ee694054dd8629ced2ba25403c06d2ca410ec949ce6ef66d4e2ec8da07f1c9cd2c99fc58d62bfa5695fbd1a1952d2a
|
|
7
|
+
data.tar.gz: 315e7240b1c2500c139c5e9346dba3415262c341c4386d21a31cb3794eb71681f308074a149f164a34425632634a846de273da2657d9be1d4cc0a38f6c0913ae
|
data/lib/sigstore/cli.rb
CHANGED
|
@@ -48,21 +48,29 @@ module Sigstore
|
|
|
48
48
|
option :certificate, type: :string, desc: "Path to the public certificate"
|
|
49
49
|
option :certificate_identity, type: :string, desc: "The identity of the certificate"
|
|
50
50
|
option :certificate_oidc_issuer, type: :string, desc: "The OIDC issuer of the certificate"
|
|
51
|
+
option :key, type: :string, desc: "Path to a PEM public key for managed-key (bring-your-own-key) verification"
|
|
51
52
|
option :offline, type: :boolean, desc: "Do not fetch the latest timestamp from the Rekor server"
|
|
52
53
|
option :bundle, type: :string, desc: "Path to the signed bundle"
|
|
53
54
|
option :trusted_root, type: :string, desc: "Path to the trusted root"
|
|
54
55
|
option :update_trusted_root, type: :boolean, desc: "Update the trusted root", default: true
|
|
55
56
|
exclusive :bundle, :signature
|
|
56
57
|
exclusive :bundle, :certificate
|
|
58
|
+
exclusive :key, :certificate
|
|
59
|
+
exclusive :key, :certificate_identity
|
|
57
60
|
def verify(*files)
|
|
58
61
|
verifier, files_with_materials = collect_verification_state(files)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
key = load_verification_key
|
|
63
|
+
policy = if key
|
|
64
|
+
Sigstore::Policy::UnsafeNoOp.new
|
|
65
|
+
else
|
|
66
|
+
Sigstore::Policy::Identity.new(
|
|
67
|
+
identity: options[:certificate_identity],
|
|
68
|
+
issuer: options[:certificate_oidc_issuer]
|
|
69
|
+
)
|
|
70
|
+
end
|
|
63
71
|
|
|
64
72
|
verified = files_with_materials.all? do |file, input|
|
|
65
|
-
result = verifier.verify(input:, policy:, offline: options[:offline])
|
|
73
|
+
result = verifier.verify(input:, policy:, offline: options[:offline], key:)
|
|
66
74
|
|
|
67
75
|
if result.verified?
|
|
68
76
|
say "OK: #{file}"
|
|
@@ -84,8 +92,17 @@ module Sigstore
|
|
|
84
92
|
option :signature, type: :string, desc: "Path to write the signature to"
|
|
85
93
|
option :certificate, type: :string, desc: "Path to the public certificate"
|
|
86
94
|
option :trusted_root, type: :string, desc: "Path to the trusted root"
|
|
95
|
+
option :signing_config, type: :string, desc: "Path to the signing config"
|
|
87
96
|
option :update_trusted_root, type: :boolean, desc: "Update the trusted root", default: true
|
|
97
|
+
option :in_toto, type: :boolean, desc: "Sign the file as an in-toto statement in a DSSE envelope"
|
|
88
98
|
def sign(file)
|
|
99
|
+
# A DSSE bundle carries an envelope, not a message signature, so the
|
|
100
|
+
# detached --signature/--certificate outputs of the message-signature flow
|
|
101
|
+
# do not apply.
|
|
102
|
+
if options[:in_toto] && (options[:signature] || options[:certificate])
|
|
103
|
+
raise Thor::InvocationError, "--in-toto cannot be combined with --signature or --certificate"
|
|
104
|
+
end
|
|
105
|
+
|
|
89
106
|
self.options = options.merge(identity_token: IdToken.detect_credential).freeze if options[:identity_token].nil?
|
|
90
107
|
unless options[:identity_token]
|
|
91
108
|
raise Error::InvalidIdentityToken,
|
|
@@ -93,10 +110,12 @@ module Sigstore
|
|
|
93
110
|
end
|
|
94
111
|
|
|
95
112
|
contents = File.binread(file)
|
|
96
|
-
|
|
113
|
+
signer = Sigstore::Signer.new(
|
|
97
114
|
jwt: options[:identity_token],
|
|
98
|
-
trusted_root
|
|
99
|
-
|
|
115
|
+
trusted_root:,
|
|
116
|
+
signing_config:
|
|
117
|
+
)
|
|
118
|
+
bundle = options[:in_toto] ? signer.sign_dsse(contents) : signer.sign(contents)
|
|
100
119
|
|
|
101
120
|
File.binwrite(options[:bundle], bundle.to_json) if options[:bundle]
|
|
102
121
|
if options[:signature]
|
|
@@ -114,7 +133,11 @@ module Sigstore
|
|
|
114
133
|
|
|
115
134
|
say "--- Bundle #{file} ---"
|
|
116
135
|
say "Media Type: #{bundle.media_type}"
|
|
117
|
-
|
|
136
|
+
if bundle.key_based?
|
|
137
|
+
say "Public Key (hint): #{bundle.signing_key_hint}"
|
|
138
|
+
else
|
|
139
|
+
say bundle.leaf_certificate.to_text
|
|
140
|
+
end
|
|
118
141
|
|
|
119
142
|
case bundle.content
|
|
120
143
|
when :message_signature
|
|
@@ -185,13 +208,39 @@ module Sigstore
|
|
|
185
208
|
def trusted_root
|
|
186
209
|
return Sigstore::TrustedRoot.from_file(options[:trusted_root]) if options[:trusted_root]
|
|
187
210
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
211
|
+
Sigstore::TrustedRoot.from_tuf_updater(tuf_updater)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def signing_config
|
|
215
|
+
return Sigstore::SigningConfig.from_file(options[:signing_config]) if options[:signing_config]
|
|
216
|
+
|
|
217
|
+
# With no explicit config, fall back to the one the Sigstore instance
|
|
218
|
+
# publishes via TUF, so signing targets the current Rekor (v2 where the
|
|
219
|
+
# config selects it). Returns nil offline or when none is published, in
|
|
220
|
+
# which case the Signer uses the legacy v1 flow from the trusted root.
|
|
221
|
+
Sigstore::SigningConfig.from_tuf_updater(tuf_updater)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# One refreshed TUF updater per command invocation, shared by the trusted
|
|
225
|
+
# root and signing config so signing refreshes the repository only once.
|
|
226
|
+
def tuf_updater
|
|
227
|
+
@tuf_updater ||= begin
|
|
228
|
+
url = options[:staging] ? Sigstore::TUF::STAGING_TUF_URL : Sigstore::TUF::DEFAULT_TUF_URL
|
|
229
|
+
offline = !options[:update_trusted_root]
|
|
230
|
+
Sigstore::TUF::TrustUpdater.new(url, offline).tap { _1.refresh unless offline }
|
|
192
231
|
end
|
|
193
232
|
end
|
|
194
233
|
|
|
234
|
+
def load_verification_key
|
|
235
|
+
return unless options[:key]
|
|
236
|
+
|
|
237
|
+
raise Thor::InvocationError, "Key file not found: #{options[:key]}" unless File.exist?(options[:key])
|
|
238
|
+
|
|
239
|
+
OpenSSL::PKey.read(Gem.read_binary(options[:key]))
|
|
240
|
+
rescue OpenSSL::OpenSSLError => e
|
|
241
|
+
raise Error::InvalidKey, "could not parse verification key #{options[:key].inspect}: #{e.message}"
|
|
242
|
+
end
|
|
243
|
+
|
|
195
244
|
def collect_verification_state(files)
|
|
196
245
|
if (options[:certificate] || options[:signature] || options[:bundle]) && files.size > 1
|
|
197
246
|
raise Thor::InvocationError, "Too many files specified: #{files.inspect}"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sigstore-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- The Sigstore Authors
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2026-
|
|
12
|
+
date: 2026-11-02 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: sigstore
|
|
@@ -17,14 +17,14 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - '='
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: 0.
|
|
20
|
+
version: 0.3.0
|
|
21
21
|
type: :runtime
|
|
22
22
|
prerelease: false
|
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
24
|
requirements:
|
|
25
25
|
- - '='
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
|
-
version: 0.
|
|
27
|
+
version: 0.3.0
|
|
28
28
|
- !ruby/object:Gem::Dependency
|
|
29
29
|
name: thor
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|