diff --git a/pkg/kubeapiserver/authenticator/config.go b/pkg/kubeapiserver/authenticator/config.go index bc8033c04ca..ce4be0fda3b 100644 --- a/pkg/kubeapiserver/authenticator/config.go +++ b/pkg/kubeapiserver/authenticator/config.go @@ -151,10 +151,20 @@ func (config Config) New() (authenticator.Request, *spec.SecurityDefinitions, er // simply returns an error, the OpenID Connect plugin may query the provider to // update the keys, causing performance hits. if len(config.OIDCIssuerURL) > 0 && len(config.OIDCClientID) > 0 { + // TODO(enj): wire up the Notifier and ControllerRunner bits when OIDC supports CA reload + var oidcCAContent oidc.CAContentProvider + if len(config.OIDCCAFile) != 0 { + var oidcCAErr error + oidcCAContent, oidcCAErr = dynamiccertificates.NewDynamicCAContentFromFile("oidc-authenticator", config.OIDCCAFile) + if oidcCAErr != nil { + return nil, nil, oidcCAErr + } + } + oidcAuth, err := newAuthenticatorFromOIDCIssuerURL(oidc.Options{ IssuerURL: config.OIDCIssuerURL, ClientID: config.OIDCClientID, - CAFile: config.OIDCCAFile, + CAContentProvider: oidcCAContent, UsernameClaim: config.OIDCUsernameClaim, UsernamePrefix: config.OIDCUsernamePrefix, GroupsClaim: config.OIDCGroupsClaim, diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go index 8840b65f733..1fb5e70c679 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go @@ -78,8 +78,8 @@ type Options struct { // See: https://openid.net/specs/openid-connect-core-1_0.html#IDToken ClientID string - // Path to a PEM encoded root certificate of the provider. - CAFile string + // PEM encoded root certificate contents of the provider. + CAContentProvider CAContentProvider // UsernameClaim is the JWT field to use as the user's username. UsernameClaim string @@ -116,6 +116,11 @@ type Options struct { now func() time.Time } +// Subset of dynamiccertificates.CAContentProvider that can be used to dynamically load root CAs. +type CAContentProvider interface { + CurrentCABundleContent() []byte +} + // initVerifier creates a new ID token verifier for the given configuration and issuer URL. On success, calls setVerifier with the // resulting verifier. func initVerifier(ctx context.Context, config *oidc.Config, iss string) (*oidc.IDTokenVerifier, error) { @@ -273,10 +278,11 @@ func newAuthenticator(opts Options, initVerifier func(ctx context.Context, a *Au } var roots *x509.CertPool - if opts.CAFile != "" { - roots, err = certutil.NewPool(opts.CAFile) + if opts.CAContentProvider != nil { + // TODO(enj): make this reload CA data dynamically + roots, err = certutil.NewPoolFromBytes(opts.CAContentProvider.CurrentCABundleContent()) if err != nil { - return nil, fmt.Errorf("Failed to read the CA file: %v", err) + return nil, fmt.Errorf("Failed to read the CA contents: %v", err) } } else { klog.Info("OIDC: No x509 certificates provided, will use host's root CA set") diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc_test.go index 9841225df49..93189d0ee63 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc_test.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc_test.go @@ -38,6 +38,7 @@ import ( oidc "github.com/coreos/go-oidc" jose "gopkg.in/square/go-jose.v2" "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/server/dynamiccertificates" "k8s.io/klog/v2" ) @@ -254,7 +255,11 @@ func (c *claimsTest) run(t *testing.T) { // by writing its root CA certificate into a temporary file. tempFileName := writeTempCert(t, ts.TLS.Certificates[0].Certificate[0]) defer os.Remove(tempFileName) - c.options.CAFile = tempFileName + caContent, err := dynamiccertificates.NewDynamicCAContentFromFile("oidc-authenticator", tempFileName) + if err != nil { + t.Fatalf("initialize ca: %v", err) + } + c.options.CAContentProvider = caContent // Allow claims to refer to the serving URL of the test server. For this, // substitute all references to {{.URL}} in appropriate places.