Locking Down the Cluster: Restricting Kubernetes RBAC within a Namespace 🔒
Kubernetes Role-Based Access Control (RBAC) is your gatekeeper for securing your cluster. While it’s great for defining who can do what across the entire cluster, securing environments often requires limiting access to very specific resources—like only allowing a developer to manage Deployments but not Secrets—within their assigned namespace.
This focused approach is not only vital for security but also for maintaining stability and adhering to the principle of least privilege (PoLP).
Example
Kubernetes RBAC: How to Securely Restrict Access for the QA Team 🔐
Say, the QA team needs to deploy to the test environment, but granting full cluster access is a security risk. This scenario is a perfect real-world application of Kubernetes Role-Based Access Control (RBAC) to restrict permissions to a single namespace and a limited set of resources.
Our goal is to create credentials that allow the QA job to only:
-
Access the
testnamespace. -
Manage only Deployments, Pods, and DaemonSets within that namespace.
-
Be denied access to cluster-wide resources or sensitive objects like Secrets or ConfigMaps.
Here are the three simple steps to achieve this:
Note: If you are using docker for desktop, you need to delete existing cluster rolebinding docker-for-desktop-binding, otherwise RBAC rules won’t be respected. please read here
kubectl delete clusterrolebinding docker-for-desktop-binding
ClusterRole and RoleBinding
Create service accounts, test-user in namespace qa
kubectl create ns qa
kubectl create sa test-user -n qa
Create clusterRole and Rolebinding using the config below.
A RoleBinding grants permissions within a specific namespace, whereas a ClusterRoleBinding grants that access cluster-wide
So, you have to use a RoleBinding, but NOTa ClusterRoleBinding
kubectl apply -f <config.yaml> -n qa --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: test-namespace-role namespace: qa rules: - apiGroups: ["*"] resources: ["pods", "deployments","statefulsets", "daemonsets"] verbs: ["create", "update", "get", "list"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: test-namespace-only namespace: qa subjects: - kind: ServiceAccount
name: test-user namespace: qa roleRef: kind: ClusterRole name: test-namespace-role apiGroup: rbac.authorization.k8s.io
Generate token
TOKEN=$(kubectl describe secrets "$(kubectl describe sa test-user -n qa | grep -i Tokens | awk '{print $2}')" -n qa| grep token: | awk '{print $2}') echo $TOKEN
Set the token to the context
Set the token in the kubeconfig to test the access granted to this token.
kubectl config set-context test-user --cluster=docker-desktop --user=test-user kubectl config set-credentials test-user --token=$TOKEN
kubectl config use-context test-user
Now, test if you have access to resources on namespaces other than the test namespace.
kubectl get pods kubectl get pods -n test kubectl get cm -n test
Similarly, you can also test this accessibility using can-i as shown below,
kubectl auth can-i get pods
Now, you can export the kubeconfig, and share it with your qa team
kubectl config view --minify > qa-config.yaml
For personal training on Kubernetes join the CKA course here