@@ -51,6 +51,17 @@ type verifierWithConfig struct {
5151	* oidc.Config 
5252}
5353
54+ type  bearerTokenTransport  struct  {
55+ 	Transport  http.RoundTripper 
56+ 	Token      string 
57+ }
58+ 
59+ func  (t  * bearerTokenTransport ) RoundTrip (req  * http.Request ) (* http.Response , error ) {
60+ 	req  =  req .Clone (req .Context ())
61+ 	req .Header .Set ("Authorization" , "Bearer " + t .Token )
62+ 	return  t .Transport .RoundTrip (req )
63+ }
64+ 
5465type  FulcioConfig  struct  {
5566	OIDCIssuers  map [string ]OIDCIssuer  `json:"OIDCIssuers,omitempty" yaml:"oidc-issuers,omitempty"` 
5667
@@ -292,55 +303,100 @@ func httpClientForIssuer(iss OIDCIssuer) (*http.Client, error) {
292303}
293304
294305func  (fc  * FulcioConfig ) prepare () error  {
295- 	if  _ , ok  :=  fc .GetIssuer ("https://kubernetes.default.svc" ); ok  {
296- 		// Add the Kubernetes cluster's CA to the system CA pool, and to 
297- 		// the default transport. 
306+ 	fc .verifiers  =  make (map [string ][]* verifierWithConfig , len (fc .OIDCIssuers ))
307+ 	for  _ , iss  :=  range  fc .OIDCIssuers  {
308+ 		if  err  :=  fc .insertVerifier (iss ); err  !=  nil  {
309+ 			log .Logger .Errorf ("error creating provider for issuer URL %q: %v" , iss .IssuerURL , err )
310+ 			continue 
311+ 		}
312+ 	}
313+ 
314+ 	_ , verifierPresent  :=  fc .verifiers [k8sIssuerURL ]
315+ 	k8sIssuer , issuerConfigured  :=  fc .GetIssuer (k8sIssuerURL )
316+ 	if  issuerConfigured  &&  ! verifierPresent  {
317+ 		// configure static validator for k8s that cover metaIssuers 
318+ 		if  err  :=  fc .insertVerifier (k8sIssuer ); err  !=  nil  {
319+ 			log .Logger .Errorf ("error creating provider for issuer URL %q: %v" , k8sIssuer .IssuerURL , err )
320+ 		}
321+ 	}
322+ 
323+ 	cache , err  :=  lru.New2Q [string , []* verifierWithConfig ](100  /* size */ )
324+ 	if  err  !=  nil  {
325+ 		return  fmt .Errorf ("lru: %w" , err )
326+ 	}
327+ 	fc .lru  =  cache 
328+ 	return  nil 
329+ }
330+ 
331+ var  (
332+ 	k8sCA  =  "/var/run/fulcio/ca.crt" 
333+ 	// k8sTokenFile specifies the standard path where Kubernetes automatically 
334+ 	// mounts the projected service account token for a pod. 
335+ 	// This path is publicly known and not a sensitive credential itself, 
336+ 	// hence the Gosec G101 warning is a false positive and is suppressed. 
337+ 	// #nosec G101 
338+ 	k8sTokenFile  =  "/var/run/secrets/kubernetes.io/serviceaccount/token" 
339+ 	k8sIssuerURL  =  "https://kubernetes.default.svc" 
340+ )
341+ 
342+ func  (fc  * FulcioConfig ) insertVerifier (iss  OIDCIssuer ) error  {
343+ 	var  client  * http.Client 
344+ 	if  iss .IssuerURL  ==  k8sIssuerURL  {
345+ 		var  transport  http.RoundTripper 
346+ 		// Add the Kubernetes cluster's CA to the client's CA pool 
298347		rootCAs , _  :=  x509 .SystemCertPool ()
299348		if  rootCAs  ==  nil  {
300349			rootCAs  =  x509 .NewCertPool ()
301350		}
302- 		const  k8sCA  =  "/var/run/fulcio/ca.crt" 
303351		certs , err  :=  os .ReadFile (k8sCA )
304352		if  err  !=  nil  {
305- 			return  fmt .Errorf ("read file: %w" , err )
353+ 			return  fmt .Errorf ("unable to  read cluster CA  file: %w" , err )
306354		}
307355		if  ok  :=  rootCAs .AppendCertsFromPEM (certs ); ! ok  {
308- 			return  fmt .Errorf ("unable to append certs" )
356+ 			return  fmt .Errorf ("unable to append cluster  certs" )
309357		}
310358
311- 		t  :=  originalTransport .(* http.Transport ).Clone ()
359+ 		t  :=  http . DefaultTransport .(* http.Transport ).Clone ()
312360		t .TLSClientConfig .RootCAs  =  rootCAs 
313- 		http .DefaultTransport  =  t 
314- 	} else  {
315- 		// If we parse a config that doesn't include a cluster issuer 
316- 		// signed with the cluster'sCA, then restore the original transport 
317- 		// (in case we overwrote it) 
318- 		http .DefaultTransport  =  originalTransport 
319- 	}
361+ 		transport  =  t 
320362
321- 	fc .verifiers  =  make (map [string ][]* verifierWithConfig , len (fc .OIDCIssuers ))
322- 	for  _ , iss  :=  range  fc .OIDCIssuers  {
323- 		ctx , cancel  :=  context .WithTimeout (context .Background (), defaultOIDCDiscoveryTimeout )
324- 		defer  cancel ()
325- 		client , err  :=  httpClientForIssuer (iss )
326- 		if  err  !=  nil  {
327- 			log .Logger .Errorf ("error creating http client for issuer URL %q: %v" , iss .IssuerURL , err )
328- 			continue 
363+ 		if  _ , err  :=  os .Stat (k8sTokenFile ); err  !=  nil  {
364+ 			if  errors .Is (err , os .ErrNotExist ) {
365+ 				log .Logger .Warnf ("Kubernetes token file can't be found on path: %s" , k8sTokenFile )
366+ 			} else  {
367+ 				return  err 
368+ 			}
369+ 		} else  {
370+ 			// add the authentication header 
371+ 			tokenBytes , err  :=  os .ReadFile (k8sTokenFile )
372+ 			if  err  !=  nil  {
373+ 				return  fmt .Errorf ("unable to read cluster token file: %w" , err )
374+ 			}
375+ 			transport  =  & bearerTokenTransport {
376+ 				Transport : transport ,
377+ 				Token :     string (tokenBytes ),
378+ 			}
329379		}
330- 		provider , err  :=  oidc .NewProvider (oidc .ClientContext (ctx , client ), iss .IssuerURL )
380+ 
381+ 		client  =  & http.Client {Transport : transport }
382+ 
383+ 	} else  {
384+ 		var  err  error 
385+ 		client , err  =  httpClientForIssuer (iss )
331386		if  err  !=  nil  {
332- 			log .Logger .Errorf ("error creating provider for issuer URL %q: %v" , iss .IssuerURL , err )
333- 		} else  {
334- 			cfg  :=  & oidc.Config {ClientID : iss .ClientID }
335- 			fc .verifiers [iss .IssuerURL ] =  []* verifierWithConfig {{provider .Verifier (cfg ), cfg }}
387+ 			return  err 
336388		}
337389	}
338390
339- 	cache , err  :=  lru.New2Q [string , []* verifierWithConfig ](100  /* size */ )
391+ 	ctx , cancel  :=  context .WithTimeout (context .Background (), defaultOIDCDiscoveryTimeout )
392+ 	defer  cancel ()
393+ 	provider , err  :=  oidc .NewProvider (oidc .ClientContext (ctx , client ), iss .IssuerURL )
340394	if  err  !=  nil  {
341- 		return  fmt .Errorf ("lru: %w" , err )
395+ 		return  err 
396+ 	} else  {
397+ 		cfg  :=  & oidc.Config {ClientID : iss .ClientID }
398+ 		fc .verifiers [iss .IssuerURL ] =  []* verifierWithConfig {{provider .Verifier (cfg ), cfg }}
342399	}
343- 	fc .lru  =  cache 
344400	return  nil 
345401}
346402
@@ -507,8 +563,6 @@ var DefaultConfig = &FulcioConfig{
507563	},
508564}
509565
510- var  originalTransport  =  http .DefaultTransport 
511- 
512566type  configKey  struct {}
513567
514568func  With (ctx  context.Context , cfg  * FulcioConfig ) context.Context  {
0 commit comments