Dev.to Security 🔐 Cybersecurity 👁 0 📖 3 min read

Kubernetes RBAC — Control Who Can Do What in Your Cluster (2026)

Without RBAC properly configured: A developer can accidentally delete production pods A compromised app can read ALL secrets in the cluster CI/CD pipelines have unlimited cluster access RBAC uses 4 objects: Role —

Without RBAC properly configured:

  • A developer can accidentally delete production pods
  • A compromised app can read ALL secrets in the cluster
  • CI/CD pipelines have unlimited cluster access

RBAC uses 4 objects:

  • Role — namespace-scoped permissions
  • ClusterRole — cluster-wide permissions
  • RoleBinding — attach Role to a user/serviceaccount
  • ClusterRoleBinding — attach ClusterRole cluster-wide

Check Permissions First

# What can YOU do?
kubectl auth can-i get pods
kubectl auth can-i delete deployments
kubectl auth can-i get secrets -n production

# What can a specific user do?
kubectl auth can-i get pods --as=john.doe -n dev
kubectl auth can-i delete pods --as=john.doe -n dev  # no
kubectl auth can-i get secrets --as=john.doe -n dev  # no

Create a Role (Namespace-Scoped)

# developer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer-role
  namespace: dev
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["configmaps", "services"]
    verbs: ["get", "list"]
  # Explicitly NO access to secrets!
kubectl apply -f developer-role.yaml
kubectl describe role developer-role -n dev

Bind Role to User

# rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: dev
subjects:
  - kind: User
    name: john.doe
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer-role
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f rolebinding.yaml

# Test permissions
kubectl auth can-i get pods --as=john.doe -n dev    # yes ✅
kubectl auth can-i delete pods --as=john.doe -n dev  # no ✅
kubectl auth can-i get secrets --as=john.doe -n dev  # no ✅

ClusterRole — Cluster-Wide Permissions

# cluster-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-reader
rules:
  - apiGroups: ["", "apps", "batch"]
    resources: ["*"]
    verbs: ["get", "list", "watch"]
  # Still NO secrets access!

Built-in ClusterRoles you can use:

# View available built-in roles
kubectl get clusterroles | grep -v system

# Common ones:
# cluster-admin  - full access (be very careful!)
# admin          - full access in namespace
# edit           - read/write most resources
# view           - read-only most resources

ServiceAccounts for Applications

Applications in pods should use ServiceAccounts — never hardcoded credentials:

# Create ServiceAccount
kubectl create serviceaccount myapp-sa -n default

# Create Role with MINIMUM permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: myapp-role
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get"]
    resourceNames: ["myapp-config"]  # Only THIS configmap!
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]
    resourceNames: ["myapp-secret"]  # Only THIS secret!
# Bind ServiceAccount to Role
kubectl create rolebinding myapp-binding \
  --role=myapp-role \
  --serviceaccount=default:myapp-sa

# Use in Deployment spec:
# serviceAccountName: myapp-sa

RBAC for CI/CD Pipelines

# Create namespace and ServiceAccount for CI/CD
kubectl create namespace ci-cd
kubectl create serviceaccount github-actions -n ci-cd
# deployer role - just enough to update deployments
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: deployer
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
kubectl apply -f deployer-role.yaml

kubectl create clusterrolebinding github-actions-binding \
  --clusterrole=deployer \
  --serviceaccount=ci-cd:github-actions

# CI/CD can deploy but CANNOT:
# - Read secrets
# - Delete resources
# - Access other namespaces

Audit RBAC — Who Has What Access

# List all roles in namespace
kubectl get roles -n dev
kubectl get rolebindings -n dev

# List cluster-wide
kubectl get clusterroles | grep -v system
kubectl get clusterrolebindings | grep -v system

# What can a serviceaccount do?
kubectl auth can-i --list \
  --as=system:serviceaccount:default:myapp-sa

# Describe binding to see subjects
kubectl describe rolebinding developer-binding -n dev

RBAC Best Practices

Practice Why
Least privilege always Limit blast radius
Roles over ClusterRoles Namespace isolation
ServiceAccounts for apps No hardcoded credentials
Never use cluster-admin for apps Too dangerous
resourceNames for specific access Extra restriction
Audit RBAC quarterly Remove unused permissions

Practice Kubernetes Interview Questions

535+ real DevOps interview questions — Kubernetes, Docker, AWS, Terraform and more.

Completely free at devopsrise.vercel.app

Mock interview mode with timer available!

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.