get, list, create, delete) on which resources (nouns: pods, services, secrets).TL;DR (Quick Summary)#
- Subjects: Who is performing the request (User, Group, or
ServiceAccount). - API Groups & Verbs: What operations are allowed (
verbs: ["get", "list", "watch"]onresources: ["pods"]). - Role vs ClusterRole:
- Role: Namespace-scoped access permissions.
- ClusterRole: Cluster-wide access permissions (or cluster-scoped resources like
Nodes,Namespaces,PersistentVolumes).
- RoleBinding vs ClusterRoleBinding: Grants the permissions defined in a Role or ClusterRole to a Subject.
1. RBAC Security Architecture#
graph TD
subgraph Subject["Subject (Who)"]
SA["ServiceAccount: app-monitor-sa
(Namespace: default)"]
end
subgraph Binding["Binding (Connector)"]
RB["RoleBinding: pod-read-binding"]
end
subgraph Permission["Permissions (What)"]
R["'Role: pod-reader
apiGroups: [''"]
resources: ['pods', 'pods/log']
verbs: ['get', 'list', 'watch']"]
end
SA -->|Bound by| RB
RB -->|Refers to| R
2. Roles & RoleBindings (Namespace Scoped)#
Let’s create a read-only Role inside the default namespace that allows viewing Pods and Pod logs, but forbids creating or deleting workloads.
Create rbac-namespace.yaml:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader-role
rules:
- apiGroups: [""] # Core API Group
resources: ["pods", "pods/log", "services"]
verbs: ["get", "list", "watch"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: developer-sa
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-global-binding
namespace: default
subjects:
- kind: ServiceAccount
name: developer-sa
namespace: default
roleRef:
kind: Role
name: pod-reader-role
apiGroup: rbac.authorization.k8s.ioApply manifest:
kubectl apply -f rbac-namespace.yaml3. Testing RBAC Permissions with kubectl auth can-i#
Kubernetes provides a built-in CLI command to test whether a subject is authorized to perform specific actions without having to assume identity:
# Check if developer-sa can list pods in default namespace
kubectl auth can-i list pods --as=system:serviceaccount:default:developer-sa -n defaultExpected Terminal Output:
yesNow check if developer-sa can delete pods:
kubectl auth can-i delete pods --as=system:serviceaccount:default:developer-sa -n defaultExpected Terminal Output:
no4. ClusterRoles & ClusterRoleBindings (Cluster Wide)#
Some resources do not belong to any single namespace (e.g., nodes, namespaces, persistentvolumes). Inspecting these requires a ClusterRole.
Create rbac-cluster.yaml:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-inspector-clusterrole
rules:
- apiGroups: [""]
resources: ["nodes", "persistentvolumes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: bind-node-inspector
subjects:
- kind: ServiceAccount
name: developer-sa
namespace: default
roleRef:
kind: ClusterRole
name: node-inspector-clusterrole
apiGroup: rbac.authorization.k8s.ioApply manifest:
kubectl apply -f rbac-cluster.yaml5. Attaching ServiceAccounts to Pod Specifications#
To allow an application container (e.g., a custom Kubernetes controller, CI/CD runner, or monitoring tool) to communicate with kube-apiserver, attach the ServiceAccount in the PodSpec:
apiVersion: v1
kind: Pod
metadata:
name: k8s-monitoring-agent
spec:
serviceAccountName: developer-sa
containers:
- name: agent
image: bitnami/kubectl:latest
command: ["kubectl", "get", "pods"]6. Summary & Next Steps#
RBAC ensures strict access control across developers, automation agents, and in-cluster Pod service accounts.
In Episode 14: Health Checks & Zero-Downtime Rolling Updates, we will master production availability strategies: Liveness, Readiness, and Startup Probes combined with zero-downtime rolling update strategies!

