Skip to content

Commit 7b5c684

Browse files
authored
cli: Add --rekor-version to sign arguments (#1471)
* cli: Add --rekor-version to sign arguments This should not be needed... but it could be handy if * SigningConfig already contains rekor v2 * user for some reason does not want rekor v2 entries in the bundle This option only does anything if there are multiple Rekor versions listed in SigningConfig. The test is changed since the "ANY" selector is now considered to not be an error if there are 0 services: * This is not a problem since for both TSAs and tlogs we have a check that there is at least one service * This improves the error message when --rekor-version is used with a version that is not found in signingconfig Signed-off-by: Jussi Kukkonen <[email protected]> * README: Update help output Signed-off-by: Jussi Kukkonen <[email protected]> * cli: Improve help output for --rekor-version Avoid saying "default: None", mention the valid values instead. Signed-off-by: Jussi Kukkonen <[email protected]> --------- Signed-off-by: Jussi Kukkonen <[email protected]>
1 parent c23a19e commit 7b5c684

File tree

4 files changed

+58
-16
lines changed

4 files changed

+58
-16
lines changed

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ optional arguments:
9494

9595
<!-- @begin-sigstore-sign-help@ -->
9696
```
97-
usage: sigstore sign [-h] [-v] [--identity-token TOKEN] [--oidc-client-id ID]
97+
usage: sigstore sign [-h] [-v] [--rekor-version VERSION]
98+
[--identity-token TOKEN] [--oidc-client-id ID]
9899
[--oidc-client-secret SECRET]
99100
[--oidc-disable-ambient-providers] [--oidc-issuer URL]
100101
[--oauth-force-oob] [--no-default-files]
@@ -109,6 +110,10 @@ optional arguments:
109110
-h, --help show this help message and exit
110111
-v, --verbose run with additional debug logging; supply multiple
111112
times to increase verbosity (default: 0)
113+
--rekor-version VERSION
114+
Force the rekor transparency log version. Valid values
115+
are [1, 2]. By default the highest available version
116+
is used
112117
113118
OpenID Connect options:
114119
--identity-token TOKEN
@@ -151,9 +156,9 @@ Output options:
151156

152157
<!-- @begin-sigstore-attest-help@ -->
153158
```
154-
usage: sigstore attest [-h] [-v] --predicate FILE --predicate-type TYPE
155-
[--identity-token TOKEN] [--oidc-client-id ID]
156-
[--oidc-client-secret SECRET]
159+
usage: sigstore attest [-h] [-v] [--rekor-version VERSION] --predicate FILE
160+
--predicate-type TYPE [--identity-token TOKEN]
161+
[--oidc-client-id ID] [--oidc-client-secret SECRET]
157162
[--oidc-disable-ambient-providers] [--oidc-issuer URL]
158163
[--oauth-force-oob] [--bundle FILE] [--overwrite]
159164
FILE [FILE ...]
@@ -165,6 +170,10 @@ optional arguments:
165170
-h, --help show this help message and exit
166171
-v, --verbose run with additional debug logging; supply multiple
167172
times to increase verbosity (default: 0)
173+
--rekor-version VERSION
174+
Force the rekor transparency log version. Valid values
175+
are [1, 2]. By default the highest available version
176+
is used
168177
169178
DSSE options:
170179
--predicate FILE Path to the predicate file (default: None)

sigstore/_cli.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,13 @@ def _parser() -> argparse.ArgumentParser:
286286
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
287287
parents=[parent_parser],
288288
)
289+
attest.add_argument(
290+
"--rekor-version",
291+
type=int,
292+
metavar="VERSION",
293+
default=argparse.SUPPRESS,
294+
help="Force the rekor transparency log version. Valid values are [1, 2]. By default the highest available version is used",
295+
)
289296
attest.add_argument(
290297
"files",
291298
metavar="FILE",
@@ -346,6 +353,13 @@ def _parser() -> argparse.ArgumentParser:
346353
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
347354
parents=[parent_parser],
348355
)
356+
sign.add_argument(
357+
"--rekor-version",
358+
type=int,
359+
metavar="VERSION",
360+
default=argparse.SUPPRESS,
361+
help="Force the rekor transparency log version. Valid values are [1, 2]. By default the highest available version is used",
362+
)
349363

350364
oidc_options = sign.add_argument_group("OpenID Connect options")
351365
oidc_options.add_argument(
@@ -1203,11 +1217,16 @@ def _get_trust_config(args: argparse.Namespace) -> ClientTrustConfig:
12031217
offline = getattr(args, "offline", False)
12041218

12051219
if args.trust_config:
1206-
return ClientTrustConfig.from_json(args.trust_config.read_text())
1220+
trust_config = ClientTrustConfig.from_json(args.trust_config.read_text())
12071221
elif args.staging:
1208-
return ClientTrustConfig.staging(offline=offline)
1222+
trust_config = ClientTrustConfig.staging(offline=offline)
12091223
else:
1210-
return ClientTrustConfig.production(offline=offline)
1224+
trust_config = ClientTrustConfig.production(offline=offline)
1225+
1226+
# Enforce rekor version if --rekor-version is used
1227+
trust_config.force_tlog_version = getattr(args, "rekor_version", None)
1228+
1229+
return trust_config
12111230

12121231

12131232
def _get_identity(

sigstore/_internal/trust.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,10 +315,15 @@ def __str__(self) -> str:
315315
"""Returns the variant's string value."""
316316
return self.value
317317

318-
def __init__(self, inner: trustroot_v1.SigningConfig):
318+
def __init__(
319+
self, inner: trustroot_v1.SigningConfig, tlog_version: int | None = None
320+
):
319321
"""
320322
Construct a new `SigningConfig`.
321323
324+
tlog_version is an optional argument that enforces that only specified
325+
versions of rekor are included in the transparency logs.
326+
322327
@api private
323328
"""
324329
self._inner = inner
@@ -331,8 +336,13 @@ def __init__(self, inner: trustroot_v1.SigningConfig):
331336

332337
# Create lists of service protos that are valid, selected by the service
333338
# configuration & supported by this client
339+
if tlog_version is None:
340+
tlog_versions = REKOR_VERSIONS
341+
else:
342+
tlog_versions = [tlog_version]
343+
334344
self._tlogs = self._get_valid_services(
335-
self._inner.rekor_tlog_urls, REKOR_VERSIONS, self._inner.rekor_tlog_config
345+
self._inner.rekor_tlog_urls, tlog_versions, self._inner.rekor_tlog_config
336346
)
337347
if not self._tlogs:
338348
raise Error("No valid Rekor transparency log found in signing config")
@@ -396,7 +406,11 @@ def _get_valid_services(
396406
if config.selector == trustroot_v1.ServiceSelector.EXACT and config.count
397407
else 1
398408
)
399-
if len(result) < count:
409+
410+
if (
411+
config.selector == trustroot_v1.ServiceSelector.EXACT
412+
and len(result) < count
413+
):
400414
raise ValueError(
401415
f"Expected {count} services in signing config, found {len(result)}"
402416
)
@@ -633,6 +647,9 @@ def __init__(self, inner: trustroot_v1.ClientTrustConfig) -> None:
633647
"""
634648
self._inner = inner
635649

650+
# This can be used to enforce a specific rekor major version in signingconfig
651+
self.force_tlog_version: int | None = None
652+
636653
@property
637654
def trusted_root(self) -> TrustedRoot:
638655
"""
@@ -645,4 +662,6 @@ def signing_config(self) -> SigningConfig:
645662
"""
646663
Return the interior root of trust, as a `SigningConfig`.
647664
"""
648-
return SigningConfig(self._inner.signing_config)
665+
return SigningConfig(
666+
self._inner.signing_config, tlog_version=self.force_tlog_version
667+
)

test/unit/internal/test_trust.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,6 @@ def test_get_valid_services(self, services, versions, config, expected_result):
186186
@pytest.mark.parametrize(
187187
"services, versions, config",
188188
[
189-
( # ANY selector without services
190-
[],
191-
[1],
192-
ServiceConfiguration(selector=ServiceSelector.ANY),
193-
),
194189
( # EXACT selector without enough services
195190
[_service_v1_op1],
196191
[1],

0 commit comments

Comments
 (0)