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.

1. RBAC API Objects

ObjectScopePurpose
RoleNamespaceDefines permissions within a namespace
ClusterRoleCluster-widePermissions across all namespaces or cluster resources
RoleBindingNamespaceAssigns a Role (or ClusterRole) to users/groups/SA within a namespace
ClusterRoleBindingCluster-wideAssigns 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"]
Pro Tip: Never use wildcards (*) 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.