Kubernetes RBAC: Roles, ClusterRoles and Security (2026)
Kubernetes RBAC (Role-Based Access Control) controls who can do what within a cluster. Combined with Pod Security Standards, securityContext, and NetworkPolicies, it forms the security foundation for production Kubernetes. This guide covers the full security model from API access control to container-level hardening.
Table of Contents
1. RBAC API Objects
| Object | Scope | Purpose |
|---|---|---|
| Role | Namespace | Defines permissions within a namespace |
| ClusterRole | Cluster-wide | Permissions across all namespaces or cluster resources |
| RoleBinding | Namespace | Assigns a Role (or ClusterRole) to users/groups/SA within a namespace |
| ClusterRoleBinding | Cluster-wide | Assigns a ClusterRole across the entire cluster |
2. Roles and ClusterRoles
# Namespace-scoped Role — allow reading pods and logs in 'production'
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: production
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: [] # deny exec explicitly
---
# ClusterRole — allow reading nodes cluster-wide (node info is not namespaced)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
resources: ["nodes", "pods"]
verbs: ["get", "list"]
*) in production RBAC rules. Be explicit about resources and verbs. The principle of least privilege means granting only what is needed — use kubectl auth can-i --list --as system:serviceaccount:namespace:name to audit what a service account can do.3. Bindings
# Bind the pod-reader Role to a developer user in the production namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-pod-reader
namespace: production
subjects:
- kind: User
name: alice@example.com # matches the user in kubeconfig/OIDC
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: dev-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
---
# ClusterRoleBinding — give monitoring service account cluster-wide read access
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-cluster-reader
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
roleRef:
kind: ClusterRole
name: node-reader
apiGroup: rbac.authorization.k8s.io
4. Service Accounts
# Create a dedicated SA for each application — never use the default SA
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
namespace: production
annotations:
# For EKS: bind SA to IAM role via IRSA
eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/myapp-s3-reader
automountServiceAccountToken: false # disable unless needed
---
# Give the SA permission to read its own namespace's configmaps
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: configmap-reader
namespace: production
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["myapp-config"] # restrict to specific named resources!
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: myapp-configmap-reader
namespace: production
subjects:
- kind: ServiceAccount
name: myapp
namespace: production
roleRef:
kind: Role
name: configmap-reader
apiGroup: rbac.authorization.k8s.io
5. Pod Security Standards
Pod Security Standards (PSS) replaced PodSecurityPolicy in Kubernetes 1.25. Three levels:
- Privileged: No restrictions — for system workloads
- Baseline: Minimal restrictions — prevents known privilege escalations
- Restricted: Heavily restricted — drops all capabilities, requires non-root
# Apply PSS to a namespace via labels
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
# Enforce the restricted policy — pods that violate are REJECTED
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.29
# Audit — violations are logged but allowed
pod-security.kubernetes.io/audit: restricted
# Warn — violations show a warning but are allowed
pod-security.kubernetes.io/warn: restricted
6. securityContext
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: production
spec:
template:
spec:
# Pod-level security context
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: myapp
image: myapp:1.0
# Container-level security context
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"] # drop ALL Linux capabilities
# add: ["NET_BIND_SERVICE"] # only add if binding ports < 1024
volumeMounts:
- name: tmp
mountPath: /tmp # writable temp dir (readOnlyRootFilesystem)
- name: var-run
mountPath: /var/run
volumes:
- name: tmp
emptyDir: {}
- name: var-run
emptyDir: {}
7. Auditing RBAC
# Check what a service account can do
kubectl auth can-i --list \
--as system:serviceaccount:production:myapp \
-n production
# Check a specific permission
kubectl auth can-i create deployments \
--as system:serviceaccount:production:myapp \
-n production
# Who can do something sensitive (requires cluster-admin)
kubectl get clusterrolebindings -o json | \
jq '.items[] | select(.roleRef.name == "cluster-admin") | .subjects'
# View all RoleBindings in a namespace
kubectl get rolebindings,clusterrolebindings -n production -o wide
Frequently Asked Questions
What is the difference between Role and ClusterRole?
Roles are namespace-scoped — they grant permissions only within the namespace they're defined in. ClusterRoles are cluster-scoped and can grant permissions on cluster-level resources (nodes, PersistentVolumes, namespaces themselves) or be reused across namespaces via RoleBindings.
Can I use a ClusterRole with a RoleBinding?
Yes — this is actually a common pattern. Define a ClusterRole once with standard permissions, then use RoleBindings in each namespace to grant those permissions namespace-specifically. Avoids duplicating Role definitions across namespaces.
Should I disable automountServiceAccountToken?
Yes for most application pods. The default ServiceAccount token gives access to the Kubernetes API — if a container is compromised, the attacker gains API access. Set automountServiceAccountToken: false on the ServiceAccount, and only enable it for pods that actually need API access.
How do I implement just-in-time RBAC for production access?
Use tools like Teleport or aws-iam-authenticator with time-bounded IAM assume-role for humans. For kubectl access, integrate with your IdP (OIDC/LDAP) so access is based on current group membership rather than static kubeconfig credentials.