Clean up service account options completion and fallback

- Remove unused fallback to TLS serving key as service account verifying key
- Separate ServiceAccountTokenMaxExpiration setup from signer setup
- Separate the check for a signing method (private key) from the existence of issuers
This commit is contained in:
Jordan Liggitt 2024-06-11 19:00:51 -04:00
parent 6c556cb9c2
commit b8be6275b9
No known key found for this signature in database

View File

@ -37,7 +37,6 @@ import (
netutil "k8s.io/utils/net" netutil "k8s.io/utils/net"
_ "k8s.io/kubernetes/pkg/features" _ "k8s.io/kubernetes/pkg/features"
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options" kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
"k8s.io/kubernetes/pkg/serviceaccount" "k8s.io/kubernetes/pkg/serviceaccount"
) )
@ -230,27 +229,7 @@ func (o *Options) Complete(alternateDNS []string, alternateIPs []net.IP) (Comple
// adjust authentication for completed authorization // adjust authentication for completed authorization
completed.Authentication.ApplyAuthorization(completed.Authorization) completed.Authentication.ApplyAuthorization(completed.Authorization)
// Use (ServiceAccountSigningKeyFile != "") as a proxy to the user enabling // verify and adjust ServiceAccountTokenMaxExpiration
// TokenRequest functionality. This defaulting was convenient, but messed up
// a lot of people when they rotated their serving cert with no idea it was
// connected to their service account keys. We are taking this opportunity to
// remove this problematic defaulting.
if completed.ServiceAccountSigningKeyFile == "" {
// Default to the private server key for service account token signing
if len(completed.Authentication.ServiceAccounts.KeyFiles) == 0 && completed.SecureServing.ServerCert.CertKey.KeyFile != "" {
if kubeauthenticator.IsValidServiceAccountKeyFile(completed.SecureServing.ServerCert.CertKey.KeyFile) {
completed.Authentication.ServiceAccounts.KeyFiles = []string{completed.SecureServing.ServerCert.CertKey.KeyFile}
} else {
klog.Warning("No TLS key provided, service account token authentication disabled")
}
}
}
if completed.ServiceAccountSigningKeyFile != "" && len(completed.Authentication.ServiceAccounts.Issuers) != 0 && completed.Authentication.ServiceAccounts.Issuers[0] != "" {
sk, err := keyutil.PrivateKeyFromFile(completed.ServiceAccountSigningKeyFile)
if err != nil {
return CompletedOptions{}, fmt.Errorf("failed to parse service-account-issuer-key-file: %v", err)
}
if completed.Authentication.ServiceAccounts.MaxExpiration != 0 { if completed.Authentication.ServiceAccounts.MaxExpiration != 0 {
lowBound := time.Hour lowBound := time.Hour
upBound := time.Duration(1<<32) * time.Second upBound := time.Duration(1<<32) * time.Second
@ -267,12 +246,19 @@ func (o *Options) Complete(alternateDNS []string, alternateIPs []net.IP) (Comple
} }
} }
} }
completed.ServiceAccountTokenMaxExpiration = completed.Authentication.ServiceAccounts.MaxExpiration
if len(completed.Authentication.ServiceAccounts.Issuers) != 0 && completed.Authentication.ServiceAccounts.Issuers[0] != "" {
if completed.ServiceAccountSigningKeyFile != "" {
sk, err := keyutil.PrivateKeyFromFile(completed.ServiceAccountSigningKeyFile)
if err != nil {
return CompletedOptions{}, fmt.Errorf("failed to parse service-account-issuer-key-file: %w", err)
}
completed.ServiceAccountIssuer, err = serviceaccount.JWTTokenGenerator(completed.Authentication.ServiceAccounts.Issuers[0], sk) completed.ServiceAccountIssuer, err = serviceaccount.JWTTokenGenerator(completed.Authentication.ServiceAccounts.Issuers[0], sk)
if err != nil { if err != nil {
return CompletedOptions{}, fmt.Errorf("failed to build token generator: %v", err) return CompletedOptions{}, fmt.Errorf("failed to build token generator: %w", err)
}
} }
completed.ServiceAccountTokenMaxExpiration = completed.Authentication.ServiceAccounts.MaxExpiration
} }
for key, value := range completed.APIEnablement.RuntimeConfig { for key, value := range completed.APIEnablement.RuntimeConfig {