diff --git a/pkg/kubeapiserver/authorizer/config.go b/pkg/kubeapiserver/authorizer/config.go index 3c4da8ef39f..f9c6aeabc86 100644 --- a/pkg/kubeapiserver/authorizer/config.go +++ b/pkg/kubeapiserver/authorizer/config.go @@ -23,6 +23,7 @@ import ( utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizerfactory" "k8s.io/apiserver/pkg/authorization/union" @@ -79,6 +80,10 @@ func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, erro ruleResolvers []authorizer.RuleResolver ) + // Add SystemPrivilegedGroup as an authorizing group + superuserAuthorizer := authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup) + authorizers = append(authorizers, superuserAuthorizer) + for _, authorizationMode := range config.AuthorizationModes { // Keep cases in sync with constant list in k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go. switch authorizationMode { diff --git a/staging/src/k8s.io/apiserver/pkg/server/config.go b/staging/src/k8s.io/apiserver/pkg/server/config.go index 1d0753ea5df..c30dba712db 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/config.go @@ -46,8 +46,6 @@ import ( authenticatorunion "k8s.io/apiserver/pkg/authentication/request/union" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" - "k8s.io/apiserver/pkg/authorization/authorizerfactory" - authorizerunion "k8s.io/apiserver/pkg/authorization/union" "k8s.io/apiserver/pkg/endpoints/discovery" "k8s.io/apiserver/pkg/endpoints/filterlatency" genericapifilters "k8s.io/apiserver/pkg/endpoints/filters" @@ -971,7 +969,4 @@ func AuthorizeClientBearerToken(loopback *restclient.Config, authn *Authenticati tokenAuthenticator := authenticatorfactory.NewFromTokens(tokens, authn.APIAudiences) authn.Authenticator = authenticatorunion.New(tokenAuthenticator, authn.Authenticator) - - tokenAuthorizer := authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup) - authz.Authorizer = authorizerunion.New(tokenAuthorizer, authz.Authorizer) } diff --git a/test/integration/certificates/admission_sign_test.go b/test/integration/certificates/admission_sign_test.go index 9e1ae99922b..de8f9d61aab 100644 --- a/test/integration/certificates/admission_sign_test.go +++ b/test/integration/certificates/admission_sign_test.go @@ -60,6 +60,11 @@ func TestCSRSignerNameSigningPlugin(t *testing.T) { defer s.TearDownFn() client := clientset.NewForConfigOrDie(s.ClientConfig) + // Drop the default RBAC superuser permissions to rely on the internal superuser authorizer + if err := client.RbacV1().ClusterRoleBindings().Delete(context.TODO(), "cluster-admin", metav1.DeleteOptions{}); err != nil { + t.Fatal(err) + } + // Grant 'test-user' permission to sign CertificateSigningRequests with the specified signerName. const username = "test-user" grantUserPermissionToSignFor(t, client, username, test.allowedSignerName) @@ -100,6 +105,12 @@ dgA7Fe4tMAoGCCqGSM49BAMCA0gAMEUCIQCTT1YWQZaAqfQ2oBxzOkJE2BqLFxhz -----END CERTIFICATE----- Trailing non-PEM content `) + + // superuser should always have permission to sign; dry-run so we don't actually modify the CSR so the non-superuser can attempt as well + if _, err := client.CertificatesV1().CertificateSigningRequests().UpdateStatus(context.TODO(), csr, metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}); err != nil { + t.Errorf("expected no superuser error but got: %v", err) + } + _, err := testuserClient.CertificatesV1().CertificateSigningRequests().UpdateStatus(context.TODO(), csr, metav1.UpdateOptions{}) if err != nil && test.error != err.Error() { t.Errorf("expected error %q but got: %v", test.error, err)