39
39
from sigstore ._internal .fulcio .client import ExpiredCertificate
40
40
from sigstore ._internal .rekor import _hashedrekord_from_parts
41
41
from sigstore ._internal .rekor .client import RekorClient
42
- from sigstore ._internal .trust import ClientTrustConfig , TrustedRoot
42
+ from sigstore ._internal .trust import ClientTrustConfig
43
43
from sigstore ._utils import sha256_digest
44
44
from sigstore .dsse import StatementBuilder , Subject
45
45
from sigstore .dsse ._predicate import (
51
51
from sigstore .hashes import Hashed
52
52
from sigstore .models import Bundle , InvalidBundle
53
53
from sigstore .oidc import (
54
- DEFAULT_OAUTH_ISSUER_URL ,
55
54
ExpiredIdentity ,
56
55
IdentityToken ,
57
56
Issuer ,
@@ -229,8 +228,8 @@ def _add_shared_oidc_options(
229
228
"--oidc-issuer" ,
230
229
metavar = "URL" ,
231
230
type = str ,
232
- default = os .getenv ("SIGSTORE_OIDC_ISSUER" , DEFAULT_OAUTH_ISSUER_URL ),
233
- help = "The OpenID Connect issuer to use (conflicts with --staging) " ,
231
+ default = os .getenv ("SIGSTORE_OIDC_ISSUER" , None ),
232
+ help = "The OpenID Connect issuer to use" ,
234
233
)
235
234
group .add_argument (
236
235
"--oauth-force-oob" ,
@@ -614,11 +613,7 @@ def main(args: list[str] | None = None) -> None:
614
613
elif args .verify_subcommand == "github" :
615
614
_verify_github (args )
616
615
elif args .subcommand == "get-identity-token" :
617
- identity = _get_identity (args )
618
- if identity :
619
- print (identity )
620
- else :
621
- _invalid_arguments (args , "No identity token supplied or detected!" )
616
+ _get_identity_token (args )
622
617
elif args .subcommand == "plumbing" :
623
618
if args .plumbing_subcommand == "fix-bundle" :
624
619
_fix_bundle (args )
@@ -630,6 +625,17 @@ def main(args: list[str] | None = None) -> None:
630
625
e .log_and_exit (_logger , args .verbose >= 1 )
631
626
632
627
628
+ def _get_identity_token (args : argparse .Namespace ) -> None :
629
+ """
630
+ Output the OIDC authentication token
631
+ """
632
+ identity = _get_identity (args , _get_trust_config (args ))
633
+ if identity :
634
+ print (identity )
635
+ else :
636
+ _invalid_arguments (args , "No identity token supplied or detected!" )
637
+
638
+
633
639
def _sign_common (
634
640
args : argparse .Namespace , output_map : OutputMap , predicate : dict [str , Any ] | None
635
641
) -> None :
@@ -643,17 +649,8 @@ def _sign_common(
643
649
not, it will use a hashedrekord.
644
650
"""
645
651
# Select the signing context to use.
646
- if args .staging :
647
- _logger .debug ("sign: staging instances requested" )
648
- signing_ctx = SigningContext .staging ()
649
- elif args .trust_config :
650
- trust_config = ClientTrustConfig .from_json (args .trust_config .read_text ())
651
- signing_ctx = SigningContext ._from_trust_config (trust_config )
652
- else :
653
- # If the user didn't request the staging instance or pass in an
654
- # explicit client trust config, we're using the public good (i.e.
655
- # production) instance.
656
- signing_ctx = SigningContext .production ()
652
+ trust_config = _get_trust_config (args )
653
+ signing_ctx = SigningContext .from_trust_config (trust_config )
657
654
658
655
# The order of precedence for identities is as follows:
659
656
#
@@ -664,7 +661,7 @@ def _sign_common(
664
661
if args .identity_token :
665
662
identity = IdentityToken (args .identity_token )
666
663
else :
667
- identity = _get_identity (args )
664
+ identity = _get_identity (args , trust_config )
668
665
669
666
if not identity :
670
667
_invalid_arguments (args , "No identity token supplied or detected!" )
@@ -1009,14 +1006,8 @@ def _collect_verification_state(
1009
1006
f"Missing verification materials for { (hashed )} : { ', ' .join (missing )} " ,
1010
1007
)
1011
1008
1012
- if args .staging :
1013
- _logger .debug ("verify: staging instances requested" )
1014
- verifier = Verifier .staging (offline = args .offline )
1015
- elif args .trust_config :
1016
- trust_config = ClientTrustConfig .from_json (args .trust_config .read_text ())
1017
- verifier = Verifier ._from_trust_config (trust_config )
1018
- else :
1019
- verifier = Verifier .production (offline = args .offline )
1009
+ trust_config = _get_trust_config (args )
1010
+ verifier = Verifier (trusted_root = trust_config .trusted_root )
1020
1011
1021
1012
all_materials = []
1022
1013
for file_or_hashed , materials in input_map .items ():
@@ -1167,7 +1158,27 @@ def _verify_common(
1167
1158
return None
1168
1159
1169
1160
1170
- def _get_identity (args : argparse .Namespace ) -> Optional [IdentityToken ]:
1161
+ def _get_trust_config (args : argparse .Namespace ) -> ClientTrustConfig :
1162
+ """
1163
+ Return the client trust configuration (Sigstore service URLs, key material and lifetimes)
1164
+
1165
+ The configuration may come from explicit argument (--trust-config) or from the TUF
1166
+ repository of the used Sigstore instance.
1167
+ """
1168
+ # Not all commands provide --offline
1169
+ offline = getattr (args , "offline" , False )
1170
+
1171
+ if args .trust_config :
1172
+ return ClientTrustConfig .from_json (args .trust_config .read_text ())
1173
+ elif args .staging :
1174
+ return ClientTrustConfig .staging (offline = offline )
1175
+ else :
1176
+ return ClientTrustConfig .production (offline = offline )
1177
+
1178
+
1179
+ def _get_identity (
1180
+ args : argparse .Namespace , trust_config : ClientTrustConfig
1181
+ ) -> Optional [IdentityToken ]:
1171
1182
token = None
1172
1183
if not args .oidc_disable_ambient_providers :
1173
1184
token = detect_credential ()
@@ -1176,12 +1187,10 @@ def _get_identity(args: argparse.Namespace) -> Optional[IdentityToken]:
1176
1187
if token :
1177
1188
return IdentityToken (token )
1178
1189
1179
- if args .staging :
1180
- issuer = Issuer .staging ()
1181
- elif args .oidc_issuer == DEFAULT_OAUTH_ISSUER_URL :
1182
- issuer = Issuer .production ()
1183
- else :
1190
+ if args .oidc_issuer is not None :
1184
1191
issuer = Issuer (args .oidc_issuer )
1192
+ else :
1193
+ issuer = Issuer (trust_config .signing_config .get_oidc_url ())
1185
1194
1186
1195
if args .oidc_client_secret is None :
1187
1196
args .oidc_client_secret = "" # nosec: B105
@@ -1198,6 +1207,7 @@ def _get_identity(args: argparse.Namespace) -> Optional[IdentityToken]:
1198
1207
def _fix_bundle (args : argparse .Namespace ) -> None :
1199
1208
# NOTE: We could support `--trusted-root` here in the future,
1200
1209
# for custom Rekor instances.
1210
+
1201
1211
rekor = RekorClient .staging () if args .staging else RekorClient .production ()
1202
1212
1203
1213
raw_bundle = RawBundle .from_dict (json .loads (args .bundle .read_bytes ()))
@@ -1234,13 +1244,10 @@ def _fix_bundle(args: argparse.Namespace) -> None:
1234
1244
1235
1245
1236
1246
def _update_trust_root (args : argparse .Namespace ) -> None :
1237
- # Simply creating the TrustedRoot in online mode is enough to perform
1247
+ # Simply creating the TrustConfig in online mode is enough to perform
1238
1248
# a metadata update.
1239
- if args .staging :
1240
- trusted_root = TrustedRoot .staging (offline = False )
1241
- else :
1242
- trusted_root = TrustedRoot .production (offline = False )
1243
1249
1250
+ config = _get_trust_config (args )
1244
1251
_console .print (
1245
- f"Trust root updated: { len (trusted_root .get_fulcio_certs ())} Fulcio certificates"
1252
+ f"Trust root & signing config updated: { len (config . trusted_root .get_fulcio_certs ())} Fulcio certificates"
1246
1253
)
0 commit comments