mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #29071 from albatross0/fix_rbac_for_serviceaccounts
Automatic merge from submit-queue
Fix RBAC authorizer of ServiceAccount
RBAC authorizer assigns a role to a wrong service account.
How to reproduce
1.Create role and rolebinding to allow default user in kube-system namespace to read secrets in kube-system namespace.
```
# kubectl create -f role.yaml
# kubectl create -f binding.yaml
```
```yaml
# role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
  name: secret-reader
  namespace: kube-system
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "watch", "list"]
    nonResourceURLs: []
```
```yaml
# binding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
  name: read-secrets
  namespace: kube-system
subjects:
  - kind: ServiceAccount
    name: default
    namespace: kube-system
roleRef:
  kind: Role
  namespace: kube-system
  name: secret-reader
  apiVersion: rbac.authorization.k8s.io/v1alpha1
```
2.Set a credential of default user
```
$ kubectl config set-credentials default_user --token=<token_of_system:serviceaccount:kube-system:default>
$ kubectl config set-context default_user-context --cluster=test-cluster --user=default_user
$ kubectl config use-context default_user-context
```
3.Try to get secrets as default user in kube-system namespace
```
$ kubectl --namespace=kube-system get secrets
the server does not allow access to the requested resource (get secrets)
```
As shown above, default user could not access to secrets.
But if I have kube-system user in default namespace, it is allowed access to secrets.
4.Create a service account and try to get secrets as kube-system user in default namespace
```
# kubectl --namespace=default create serviceaccount kube-system
serviceaccount "kube-system" created
$ kubectl config set-credentials kube-system_user --token=<token_of_system:serviceaccount:default:kube-system>
$ kubectl config set-context kube-system_user-context --cluster=test-cluster --user=kube-system_user
$ kubectl config use-context kube-system_user-context
$ kubectl --namespace=kube-system get secrets
NAME                  TYPE                                  DATA      AGE
default-token-8pyb3   kubernetes.io/service-account-token   3         4d
```
			
			
This commit is contained in:
		@@ -25,6 +25,7 @@ import (
 | 
				
			|||||||
	apierrors "k8s.io/kubernetes/pkg/api/errors"
 | 
						apierrors "k8s.io/kubernetes/pkg/api/errors"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/rbac"
 | 
						"k8s.io/kubernetes/pkg/apis/rbac"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/auth/user"
 | 
						"k8s.io/kubernetes/pkg/auth/user"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/serviceaccount"
 | 
				
			||||||
	utilerrors "k8s.io/kubernetes/pkg/util/errors"
 | 
						utilerrors "k8s.io/kubernetes/pkg/util/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -201,8 +202,7 @@ func appliesToUser(user user.Info, subject rbac.Subject) (bool, error) {
 | 
				
			|||||||
		if subject.Namespace == "" {
 | 
							if subject.Namespace == "" {
 | 
				
			||||||
			return false, fmt.Errorf("subject of kind service account without specified namespace")
 | 
								return false, fmt.Errorf("subject of kind service account without specified namespace")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// TODO(ericchiang): Is there a better way of matching a service account name?
 | 
							return serviceaccount.MakeUsername(subject.Namespace, subject.Name) == user.GetName(), nil
 | 
				
			||||||
		return "system:serviceaccount:"+subject.Name+":"+subject.Namespace == user.GetName(), nil
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return false, fmt.Errorf("unknown subject kind: %s", subject.Kind)
 | 
							return false, fmt.Errorf("unknown subject kind: %s", subject.Kind)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -234,7 +234,7 @@ func TestAppliesTo(t *testing.T) {
 | 
				
			|||||||
			subjects: []rbac.Subject{
 | 
								subjects: []rbac.Subject{
 | 
				
			||||||
				{Kind: rbac.UserKind, Name: "barfoo"},
 | 
									{Kind: rbac.UserKind, Name: "barfoo"},
 | 
				
			||||||
				{Kind: rbac.GroupKind, Name: "foobar"},
 | 
									{Kind: rbac.GroupKind, Name: "foobar"},
 | 
				
			||||||
				{Kind: rbac.ServiceAccountKind, Name: "kube-system", Namespace: "default"},
 | 
									{Kind: rbac.ServiceAccountKind, Namespace: "kube-system", Name: "default"},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			ctx: api.WithNamespace(
 | 
								ctx: api.WithNamespace(
 | 
				
			||||||
				api.WithUser(api.NewContext(), &user.DefaultInfo{Name: "system:serviceaccount:kube-system:default"}),
 | 
									api.WithUser(api.NewContext(), &user.DefaultInfo{Name: "system:serviceaccount:kube-system:default"}),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user