Topic 5.1
RBAC & ServiceAccounts
In one line
RBAC decides who (or what) is allowed to do what to the cluster's API — Roles define permissions, RoleBindings grant them to a specific user or ServiceAccount, and least privilege applies exactly as it does everywhere else in this course.
Think of it like this
A building's keycard system — a ROLE is the definition of what a specific keycard TYPE opens (the server room, the supply closet), and a ROLEBINDING is the act of actually issuing one specific person a keycard of that type. Defining the keycard type and handing it to someone are deliberately separate steps.
Key ideas
- 01
RBAC (Role-Based Access Control) governs every interaction with the API server — every single
kubectlcommand, and every request any application makes to the Kubernetes API directly, is checked against RBAC rules before being allowed to proceed. Without any RBAC granted, a user or ServiceAccount can do essentially nothing. - 02
A ROLE (scoped to one namespace) or CLUSTERROLE (cluster-wide) defines a set of PERMISSIONS — which API resources (
pods,deployments,secrets) and which VERBS (get,list,create,delete) are allowed. A Role by itself grants nothing to anyone; it's purely a reusable definition of a permission set. - 03
A ROLEBINDING (or CLUSTERROLEBINDING) is what actually GRANTS a Role's permissions to a specific SUBJECT — a user, a group, or a SERVICEACCOUNT. The same Role can be bound to many different subjects, and a subject can have many different Roles bound to it — this separation (define once, bind many times) mirrors exactly how real organizations define job permissions once and assign them to many employees.
- 04
A SERVICEACCOUNT is an identity for a PROCESS running inside the cluster (a pod), as opposed to a human user — every pod automatically runs AS some ServiceAccount (the
defaultone, if none is specified), and any code inside that pod calling the Kubernetes API directly (a controller, an operator, Phase 8) does so using that ServiceAccount's own granted permissions, exactly as an RBAC-bound identity like any human user. - 05
The exact same LEAST PRIVILEGE principle Linux's own course covered for dedicated service users (Phase 1.3) and Docker's non-root containers applies identically here: a pod's ServiceAccount should be granted ONLY the specific permissions it genuinely needs, never broad cluster-admin access 'to be safe' — a compromised application with an over-privileged ServiceAccount can do far more damage than one correctly scoped to just what it actually requires.
Code & diagrams
Define the permission set once (Role); grant it to a specific identity separately (RoleBinding).
A ServiceAccount scoped to exactly what it needs — read-only access to pods, nothing else.
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: production
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"] # read-only — no create/update/delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-app-can-read-pods
namespace: production
subjects:
- kind: ServiceAccount
name: my-app-sa
namespace: production
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: production
spec:
replicas: 1
selector:
matchLabels: { app: my-app }
template:
metadata:
labels: { app: my-app }
spec:
serviceAccountName: my-app-sa # runs AS this identity, not "default"
containers:
- name: my-app
image: my-registry/my-app:1.5.0Confirm the scoped permissions actually work — and that anything beyond them is correctly denied.
kubectl apply -f rbac.yaml
# Confirm what this ServiceAccount is actually allowed to do
kubectl auth can-i get pods --as=system:serviceaccount:production:my-app-sa -n production
# yes
kubectl auth can-i delete pods --as=system:serviceaccount:production:my-app-sa -n production
# no — exactly as scoped, nothing more
kubectl auth can-i get secrets --as=system:serviceaccount:production:my-app-sa -n production
# no — this Role never granted access to secrets at allExplain it without notes
Why are Role and RoleBinding kept as two separate objects, rather than one combined object that both defines and grants permissions at once?
A pod's ServiceAccount was never explicitly set. What identity is it actually running as, and what does that mean for its permissions?
Practice
Create the example ServiceAccount, Role, and RoleBinding, and use kubectl auth can-i --as= to confirm exactly which actions are allowed and which are correctly denied.
Check what ServiceAccount an existing Deployment in a cluster you have access to is actually running as, and use kubectl auth can-i to see what permissions that ServiceAccount actually has.
Trade-offs
- ↔
Tightly-scoped, least-privilege RBAC is significantly more secure, but it requires genuinely knowing and explicitly declaring every permission a workload actually needs — getting this wrong in the restrictive direction causes a very visible, immediate failure (a clear 'forbidden' error), which is actually a genuinely useful property: it fails safely and loudly, rather than silently allowing something it shouldn't.
Done when you can
I understand the separation between a Role (defines permissions) and a RoleBinding (grants them to a subject).
I know every pod runs as some ServiceAccount, defaulting to 'default' if none is specified.
I can use kubectl auth can-i to verify exactly what a given identity is and isn't permitted to do.