![]() |
VOOZH | about |
We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.
Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.
Follow TNS on your favorite social media networks.
Become a TNS follower on LinkedIn.
Check out the latest featured and trending stories while you wait for your first TNS newsletter.
escalate, bind and impersonate — can override existing role limitations, grant unauthorized access to restricted areas, expose confidential data or even allow complete control over a cluster. This article explains these potent permissions, offering insights into their functions and guidance on mitigating their associated risks.
get, watch and list are commonly used. However, more intriguing ones also exist.
escalate: Allows users to create and edit roles even if they don’t have initial permissions to do so.bind: Allows users to create and edit role bindings and cluster role bindings with permissions they haven’t been assigned.impersonate: Allows users to impersonate other users and gain their privileges in the cluster or in a different group. Critical data can be accessed using this verb.rbac:
kubectl create ns rbac
privsec in the rbac namespace you just created:
kubectl -n rbac create sa privesc
escalate verb.
In the image below, the SA with only update and patch permissions can’t add a new verb to the role. But if you add a new role with the escalate verb, it becomes possible.
Adding the `escalate` verb to the role allows the user to change the role permissions and add a new verb.
kubectl -n rbac create role view --verb=list,watch,get --resource=role,pod
privesc:
kubectl -n rbac create rolebinding view --role=view --serviceaccount=rbac:privesc
kubectl auth can-i update role -n rbac --as=system:serviceaccount:rbac:privesc no
rbac namespace:
kubectl -n rbac create role edit --verb=update,patch --resource=role
privesc:
kubectl -n rbac create rolebinding edit --role=edit --serviceaccount=rbac:privesc
kubectl auth can-i update role -n rbac --as=system:serviceaccount:rbac:privesc yes
kubectl auth can-i delete role -n rbac --as=system:serviceaccount:rbac:privesc no
TOKEN=$(kubectl -n rbac create token privesc --duration=8h)
list, which you already used in the read-only view role:
Success.
Now, try to add a new verb, delete, which you haven’t used in other roles:
This confirms that Kubernetes doesn’t allow users or service accounts to add new permissions if they don’t already have them — only if users or service accounts are bound to roles with such permissions.
So extend the privesc SA permissions. Do this by using the admin config and adding a new role with the escalate verb:
KUBECONFIG=~/.kube/config kubectl -n rbac create role escalate --verb=escalate --resource=role
privesc SA to the new role:
KUBECONFIG=~/.kube/config kubectl -n rbac create rolebinding escalate --role=escalate --serviceaccount=rbac:privesc
escalate verb gives the appropriate admin privileges, including those of the namespace admin or even cluster admin.
bind verb allows the user to edit the RoleBinding or ClusterRoleBinding objects for privilege escalation, similar to escalate, which allows the user to edit Role or ClusterRole.
In the image below, the SA with the role binding that has the update, patch and create verbs can’t add delete until you create a new role with the bind verb.
Adding the new role with the `bind` verb allows the user to extend the role’s binding permissions.
kubeconfig file to admin:
export KUBECONFIG=~/.kube/config
kubectl -n rbac delete rolebinding view edit escalate kubectl -n rbac delete role view edit escalate
kubectl -n rbac create role view --verb=list,watch,get --resource=role,rolebinding,pod kubectl -n rbac create rolebinding view --role=view --serviceaccount=rbac:privesc kubectl -n rbac create role edit --verb=update,patch,create --resource=rolebinding,pod kubectl -n rbac create rolebinding edit --role=edit --serviceaccount=rbac:privesc
kubectl -n rbac create role pod-view-edit --verb=get,list,watch,update,patch --resource=pod kubectl -n rbac create role delete-pod --verb=delete --resource=pod
kubeconfig to the SA privesc and try to edit the role binding:
export KUBECONFIG=~/.kube/rbac.conf kubectl -n rbac create rolebinding pod-view-edit --role=pod-view-edit --serviceaccount=rbac:privesc rolebinding.rbac.authorization.k8s.io/pod-view-edit created
pod-view-edit role contains verbs and resources that were already bound to the SA by the role that binds view and edit.
Now, try to bind a role with a new verb, delete, which is missing among the roles that are bound to the SA:
kubectl -n rbac create rolebinding delete-pod --role=delete-pod --serviceaccount=rbac:privesc
error: failed to create rolebinding: rolebindings.rbac.authorization.k8s.io "delete-pod" is forbidden: user "system:serviceaccount:rbac:privesc" (groups=["system:serviceaccounts" "system:serviceaccounts:rbac" "system:authenticated"]) is attempting to grant RBAC permissions not currently held:
{APIGroups:[""], Resources:["pods"], Verbs:["delete"]}
bind verb. Do so using the admin config:
KUBECONFIG=~/.kube/config kubectl -n rbac create role bind --verb=bind --resource=role role.rbac.authorization.k8s.io/bind created KUBECONFIG=~/.kube/config kubectl -n rbac create rolebinding bind --role=bind --serviceaccount=rbac:privesc rolebinding.rbac.authorization.k8s.io/bind created
delete verb:
kubectl -n rbac create rolebinding delete-pod --role=delete-pod --serviceaccount=rbac:privesc rolebinding.rbac.authorization.k8s.io/delete-pod created
bind verb, the SA can bind any role to itself or any user.
impersonate verb in K8s is like sudo in Linux. If users have impersonate access, they can authenticate as other users and run commands on their behalf. The kubectl tool has the --as, --as-group and --as-uid options, which allow commands to be run as a different user, group or universally unique identifier (UUID), respectively. If a user was given impersonation permissions, they would become the namespace admin, or — if there is a cluster-admin service account in the namespace — even the cluster admin.
The impersonate verb is helpful to check the RBAC permissions delegated to a user. An admin should perform a command according to the template kubectl auth can-i --as=$USERNAME -n $NAMESPACE $VERB $RESOURCE and check if the authorization works as designed.
In this example, the SA wouldn’t get info about pods in the rbac namespace by just performing kubectl -n rbac get pod. But it becomes possible if there is a role with the impersonate verb:
kubectl auth can-i get pod -n rbac --as=system:serviceaccount:rbac:privesc yes
KUBECONFIG=~/.kube/config kubectl -n rbac create sa impersonator serviceaccount/impersonator created
impersonate verb and a role binding:
KUBECONFIG=~/.kube/config kubectl -n rbac create role impersonate --resource=serviceaccounts --verb=impersonate --resource-name=privesc
--resource-name parameter in the above command: It only allows impersonation as the privesc SA.)
role.rbac.authorization.k8s.io/impersonate created KUBECONFIG=~/.kube/config kubectl -n rbac create rolebinding impersonator --role=impersonate --serviceaccount=rbac:impersonator rolebinding.rbac.authorization.k8s.io/impersonator created
Getting info about pods with a role that has the `impersonate` verb.
TOKEN=$(KUBECONFIG=~/.kube/config kubectl -n rbac create token impersonator --duration=8h) kubectl config set-credentials impersonate --token=$TOKEN User "impersonate" set. kubectl config set-context impersonate@kubernetes --user=impersonate --cluster=kubernetes Context "impersonate@kubernetes" created. kubectl config use-context impersonate@kubernetes Switched to context "impersonate@kubernetes".
kubectl auth can-i --list -n rbac Resources Non-Resource URLs Resource Names Verbs selfsubjectaccessreviews.authorization.k8s.io [] [] [create] selfsubjectrulesreviews.authorization.k8s.io [] [] [create] ... serviceaccounts [] [privesc] [impersonate]
impersonate, as specified in the role. But if you impersonate the impersonator SA as the privesc SA, you get the same permissions that the privesc SA has:
kubectl auth can-i --list -n rbac --as=system:serviceaccount:rbac:privesc Resources Non-Resource URLs Resource Names Verbs roles.rbac.authorization.k8s.io [] [edit] [bind escalate] selfsubjectaccessreviews.authorization.k8s.io [] [] [create] selfsubjectrulesreviews.authorization.k8s.io [] [] [create] pods [] [] [get list watch update patch delete create] ... rolebindings.rbac.authorization.k8s.io [] [] [list watch get update patch create bind escalate] roles.rbac.authorization.k8s.io [] [] [list watch get update patch create bind escalate] configmaps [] [] [update patch create delete] secrets [] [] [update patch create delete]
impersonate SA has all of its own privileges as well as all the privileges of the SA it is impersonating, including those that a namespace admin has.
escalate, bind and impersonate verbs can be used to create flexible permissions, resulting in granular management of access to K8s infrastructure. But these verbs also open the door to malicious use, since, in some cases, they enable a user to access crucial infrastructure components with admin privileges.
Three practices can help you mitigate the potential dangers of misuse or malicious use of these verbs:
resourceNames field in the Role and ClusterRole manifests.kubectl get clusterrole -A -oyaml | yq '.items[] | select (.rules[].verbs[] | contains("esalate" | "bind" | "impersonate")) | .metadata.name'
kubectl get role -A -oyaml | yq '.items[] | select (.rules[].verbs[] | contains("esalate" | "bind" | "impersonate")) | .metadata.name'
escalate, bind, impersonate or any other verbs, configure the resourceNames field in the Role and ClusterRole manifests. There, you can — and should — enter the names of resources that can be used.
Here is an example of a ClusterRole that allows creation of a ClusterRoleBinding with roleRef named edit and view:
You can do the same with escalate and impersonate.
Note that in the case of bind, an admin sets permissions for a role, and users can bind that role to themselves only if allowed to do so in resourceNames. With escalate, users can write any parameters within a role and become admins of a namespace or cluster. So, bind restricts users, while escalate gives them more options. Keep this in mind if you need to grant these permissions.
delete verb and allow users to impersonate only that service account. This is the principle of least privilege. To simplify this process, you can use the kubectl plug-in kubectl-sudo.
At Gcore, we use these methods to make our Managed Kubernetes service more secure; we recommend that all our customers do the same. Using managed services doesn’t guarantee that your services are completely secured by default, but at Gcore, we do everything possible to ensure our customers’ protection, including encouraging RBAC best practices.
escalate, bind and impersonate verbs allow admins to manage access to K8s infrastructure flexibly and let users escalate their privileges. These are powerful tools that, if abused, can cause significant damage to a K8s cluster. Carefully review any use of these verbs and ensure that the least privileged rule is followed. Users must have the minimum privileges necessary to operate, no more.