23

RBAC: Role and RoleBinding

Video: Day 23/40 — Kubernetes RBAC Explained (Role Based Access Control) • https://www.youtube.com/watch?v=uGcDt7iNFkE • Duration: ~22 min

Key terms

TermMeaning
RBACRole-based access control
RoleA namespaced permission set
RoleBindingGrants a Role to a subject in a namespace
VerbThe action (get/list/create/...)
ResourceThe object type a rule covers
apiGroupThe API family a resource belongs to
SubjectThe user/group/ServiceAccount being granted

Problem & solution

Once requests are authenticated, you need a precise, auditable way to grant least-privilege permissions within a namespace instead of all-or-nothing access. Roles and RoleBindings define exactly who can do what.

Solution: Grant least-privilege access with a namespaced Role (verbs x resources) bound to a user or group via a RoleBinding.

The analogy

Think of an office worker handed a keycard that opens only a few specific doors, and only inside one building on a large campus. A Role is the list of doors that card is allowed to open, the exact verbs and resources, while a RoleBinding is the moment security links that card to your name. Swipe the same card at another building and nothing happens, because both the card and the doors it opens live inside a single namespace.

Where this fits in the cluster

The same cluster entities appear in every day's notes; the diagram below shows where this day's topic fits.

The idea

RBAC answers "what can this identity do?" with two halves:

   ROLE         -> a set of PERMISSIONS (verbs on resources)  [namespaced]
   ROLEBINDING  -> ATTACHES a Role to a user / group / SA

A Role grants nothing by itself until a RoleBinding connects it to someone. Both are namespaced (cluster-wide equivalents = Day 24).

Permission = verbs x resources x apiGroups

A single rule is the combination of which verbs are allowed on which resources in which apiGroups.

   verbs:      get list watch create update patch delete
   resources:  pods deployments services configmaps ...
   apiGroups:  "" (core: pods, svc), "apps" (deployments), etc.

First, create a user (cert) — recap of Day 21/23

Before binding permissions you need an identity, so generate the user's cert via the CSR flow from Day 21.

openssl genrsa -out krishna.key 2048
openssl req -new -key krishna.key -out krishna.csr -subj "/CN=krishna"
# submit CSR -> approve -> pull signed cert:
kubectl get csr krishna -o jsonpath='{.status.certificate}' | base64 -d > krishna.crt

Role (the permissions)

The Role defines what may be done. Here an on-call engineer gets read-only access to pods and their logs in the default namespace — exactly what you grant a teammate who needs to debug a running app but must not change anything.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
  - apiGroups: [""]                      # "" = core API group
    resources: ["pods", "pods/log"]      # read pods and stream their logs
    verbs: ["get", "watch", "list"]

RoleBinding (attach Role to the user)

The RoleBinding is what actually grants the permissions, connecting the Role to a specific subject such as our user.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
  - kind: User
    name: krishna             # case-sensitive; must match CN
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role                  # Role or ClusterRole
  name: pod-reader            # must match the Role name above
  apiGroup: rbac.authorization.k8s.io

Imperative shortcuts

The same Role and RoleBinding can be created in one command each, without writing YAML.

kubectl create role pod-reader \
  --verb=get,list,watch --resource=pods,pods/log -n default

kubectl create rolebinding read-pods \
  --role=pod-reader --user=krishna -n default

Verify

Confirm the binding works by impersonating the user and checking both an allowed and a denied action.

kubectl auth whoami
kubectl auth can-i list pods                    # as yourself (admin -> yes)
kubectl auth can-i list pods --as krishna       # -> yes (in default)
kubectl auth can-i delete pods --as krishna     # -> no (not granted)
kubectl auth can-i list pods --as krishna -n kube-system   # -> no (other ns)

End-to-end example: an on-call engineer reads pods and logs in one namespace

A namespaced Role + RoleBinding lets on-call engineer amy read pods and their logs in dev (to debug the app) but gives her nothing in prod.

Graph legend — each step maps to a concrete object or decision:

Graph stepMaps toWhat it does
kubectl logs deploy/app -n deva get on the pods/log subresourceReads container logs to debug the app
AuthN user amy group dev-teamthe x509 authn pluginIdentifies CN=amy, group dev-team
AuthZ RoleBinding in devRoleBinding read-pods -> Role pod-reader (ns dev)Grants get/list/watch on pods and pods/log
200 OK, pod logs streamedthe allow pathReturns the requested logs
no RoleBinding for amy in prodabsence of any binding in prodRBAC default-deny applies outside dev
403 Forbiddenthe deny pathSame identity, no permission in another namespace

End-to-end flow

A namespaced Role plus RoleBinding grants access in one namespace and nowhere else.

Graph legend — each node maps to a concrete object or decision:

Graph nodeMaps toWhat it does
amy: kubectl logs/get pods -n devthe client requestReads pods and their logs in dev
api-server AuthN: user=amythe authn layerResolves the cert to user amy
AuthZ: look for a RoleBinding in devthe RBAC authorizerSearches dev for a binding covering amy
RoleBinding -> Role pod-readerRoleBinding read-podsLinks amy to the pod-reader Role
Role allows get/list pods and pods/logthe pod-reader Role rulesPermits read access to pods and their logs
403 Forbidden in other namespacesRBAC default-denyNo binding outside dev means no access

Key takeaways

  • Role = permissions, RoleBinding = who gets them. Both namespaced.
  • A rule is verbs x resources x apiGroups; core group is "".
  • Subject name must match the cert CN exactly (case-sensitive).
  • Test with kubectl auth can-i <verb> <resource> --as <user>.

Checklist

  • [ ] Created the krishna user cert via CSR
  • [ ] Created a pod-reader Role and a read-pods RoleBinding
  • [ ] Verified access with --as krishna (allowed verb + denied verb)
  • [ ] Confirmed the binding is scoped to its namespace only