Fatskills
Practice. Master. Repeat.
Study Guide: TECH **Kubernetes RBAC: Zero-Fluff, Hands-On Guide**
Source: https://www.fatskills.com/kubernetes/chapter/tech-kubernetes-rbac-zero-fluff-hands-on-guide

TECH **Kubernetes RBAC: Zero-Fluff, Hands-On Guide**

By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.

⏱️ ~8 min read

Kubernetes RBAC: Zero-Fluff, Hands-On Guide

(Roles, RoleBindings, ClusterRoles, ClusterRoleBindings)


1. What This Is & Why It Matters

RBAC (Role-Based Access Control) in Kubernetes is how you control who can do what in your cluster. Think of it like a security badge system in an office: - Roles define what actions are allowed (e.g., "read files," "open doors").
- RoleBindings assign those roles to who (users, service accounts, groups).
- ClusterRoles and ClusterRoleBindings do the same, but cluster-wide (not just in one namespace).

Why This Matters in Production

  • Security: Without RBAC, anyone with kubectl access can delete pods, read secrets, or even take over the cluster.
  • Compliance: Auditors (SOC2, HIPAA, GDPR) will ask: "Who has access to what?" RBAC answers that.
  • Team Scaling: You don’t want devs accidentally deleting production databases. RBAC lets you restrict permissions per team (e.g., "Devs can only deploy to staging").
  • Disaster Recovery: If a rogue script or compromised service account runs kubectl delete --all, RBAC can block it.

Real-World Scenario

You’re a DevOps engineer at a fintech startup. Your CI/CD pipeline deploys to production, but a junior dev accidentally merges a PR that deletes all pods in default. Without RBAC, the pipeline has full admin access—game over. With RBAC, you restrict the CI/CD service account to only deploy to production and nothing else.


2. Core Concepts & Components

Term Definition Production Insight
Role Defines what actions (verbs) are allowed on which resources in a namespace. Always scope to the least privilege. Example: Don’t give get on secrets unless absolutely needed.
RoleBinding Assigns a Role to a subject (user, group, or service account) in a namespace. If a RoleBinding points to a non-existent Role, the subject gets no permissions.
ClusterRole Like a Role, but cluster-wide (not namespace-scoped). Use for admin tasks (e.g., cluster-admin) or read-only access to all namespaces.
ClusterRoleBinding Assigns a ClusterRole to a subject (user, group, or service account) cluster-wide. ⚠️ Dangerous! A ClusterRoleBinding to cluster-admin gives full control over the cluster.
Subject Who/what gets permissions: User, Group, or ServiceAccount. Service accounts are most common in CI/CD. Never use default service accounts in production.
Verbs Actions allowed: get, list, create, delete, watch, patch, etc. watch is resource-intensive—avoid granting it unless needed (e.g., for kubectl get pods --watch).
Resources Kubernetes objects: pods, deployments, secrets, nodes, etc. * (wildcard) means all resourcesnever use in production unless absolutely necessary.
ResourceNames Restricts permissions to specific instances of a resource (e.g., pods/my-pod). Useful for fine-grained control (e.g., "Only allow access to secrets/db-password").


3. Step-by-Step Hands-On: Restrict a CI/CD Service Account


Prerequisites

  • A running Kubernetes cluster (Minikube, EKS, AKS, or GKE).
  • kubectl configured to access the cluster.
  • A namespace for testing (e.g., ci-cd).

Goal

Create a service account for CI/CD that can only deploy to ci-cd namespace and cannot touch anything else.


Step 1: Create a Namespace

kubectl create namespace ci-cd

Step 2: Create a Service Account

kubectl create serviceaccount ci-cd-sa -n ci-cd

Verify:


kubectl get serviceaccounts -n ci-cd

Output:


NAME       SECRETS   AGE
ci-cd-sa   1         5s
default    1         10s

Step 3: Define a Role (What the SA Can Do)

Create role.yaml:


apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: ci-cd
  name: ci-cd-deployer
rules:
- apiGroups: ["", "apps", "batch"]  # "" = core API group
  resources: ["pods", "deployments", "jobs", "services"]
  verbs: ["get", "list", "create", "update", "delete", "patch"]

Apply:


kubectl apply -f role.yaml

Step 4: Bind the Role to the Service Account

Create rolebinding.yaml:


apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-cd-deployer-binding
  namespace: ci-cd
subjects:
- kind: ServiceAccount
  name: ci-cd-sa
  namespace: ci-cd
roleRef:
  kind: Role
  name: ci-cd-deployer
  apiGroup: rbac.authorization.k8s.io

Apply:


kubectl apply -f rolebinding.yaml

Step 5: Test the Permissions

Get the service account token:


kubectl get secret -n ci-cd $(kubectl get serviceaccount ci-cd-sa -n ci-cd -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode

Save the token to a variable:


TOKEN=$(kubectl get secret -n ci-cd $(kubectl get serviceaccount ci-cd-sa -n ci-cd -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode)

Test access (should work):


kubectl --token=$TOKEN -n ci-cd get pods

Test access (should fail):


kubectl --token=$TOKEN -n default get pods

Output:


Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:ci-cd:ci-cd-sa" cannot list resource "pods" in API group "" in the namespace "default"

Step 6: (Optional) Grant Read-Only Access to All Namespaces

If CI/CD needs to read cluster-wide resources (e.g., nodes), create a ClusterRole:


apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ci-cd-reader
rules:
- apiGroups: [""]
  resources: ["nodes", "namespaces"]
  verbs: ["get", "list"]

Bind it with a ClusterRoleBinding:


apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ci-cd-reader-binding
subjects:
- kind: ServiceAccount
  name: ci-cd-sa
  namespace: ci-cd
roleRef:
  kind: ClusterRole
  name: ci-cd-reader
  apiGroup: rbac.authorization.k8s.io

Apply:


kubectl apply -f clusterrole.yaml -f clusterrolebinding.yaml

Test:


kubectl --token=$TOKEN get nodes


4. ? Production-Ready Best Practices


Security

  • Least Privilege: Start with no permissions, then add only what’s needed.
  • Avoid Wildcards: Never use resources: ["*"] or verbs: ["*"] in production.
  • Service Accounts: Always create dedicated SAs for apps/CI/CD—never use default.
  • Audit Logs: Enable Kubernetes audit logging to track who did what.
  • Network Policies: Combine RBAC with NetworkPolicies to restrict pod-to-pod communication.

Cost Optimization

  • RBAC doesn’t cost money, but misconfigured permissions can lead to breaches (which cost $$$).
  • Use namespaces to isolate teams/projects (e.g., dev, staging, prod).

Reliability & Maintainability

  • Naming Conventions:
  • Roles: team-resource-verb (e.g., dev-pods-reader).
  • RoleBindings: team-resource-verb-binding (e.g., dev-pods-reader-binding).
  • Label Everything: Use labels like environment: prod to filter RBAC rules.
  • Idempotency: Use kubectl apply (not create) so updates don’t fail.

Observability

  • Monitor RBAC Changes: Use tools like kube-audit or Open Policy Agent (OPA) to alert on suspicious RBAC modifications.
  • Check Permissions: Use kubectl auth can-i to verify access: bash kubectl auth can-i create pods --as=system:serviceaccount:ci-cd:ci-cd-sa -n ci-cd


5. ⚠️ Common Mistakes & Traps

Mistake Symptom Fix/Prevention
Using cluster-admin everywhere CI/CD pipeline deletes production pods. Never use cluster-admin for service accounts. Use fine-grained Roles.
Forgetting apiGroups kubectl commands fail with forbidden even though RBAC is configured. Always specify apiGroups (e.g., apps for deployments).
Binding to default SA Apps in default namespace have no permissions. Always create dedicated service accounts.
Using * in resources A compromised pod can delete all secrets in the cluster. Never use resources: ["*"]. List resources explicitly.
Not testing RBAC CI/CD pipeline fails in production because permissions were never tested. Test with kubectl auth can-i before deploying.


6. ? Exam/Certification Focus (CKA, CKAD, CKS)


Typical Question Patterns

  1. "Which RBAC resource is namespace-scoped?"
  2. Role and RoleBinding.
  3. ❌ ClusterRole and ClusterRoleBinding (cluster-wide).

  4. "How do you grant a user read-only access to all pods in a namespace?"

  5. Create a Role with verbs: ["get", "list"] and bind it with a RoleBinding.

  6. "What’s the difference between a Role and a ClusterRole?"

  7. Role = Namespace-scoped.
  8. ClusterRole = Cluster-wide (e.g., nodes, namespaces).

  9. "How do you check if a service account can delete pods?"
    bash
    kubectl auth can-i delete pods --as=system:serviceaccount:namespace:sa-name

⚠️ Trap Distinctions

Concept Trap
Role vs. ClusterRole A Role can’t grant access to nodes or namespaces.
RoleBinding vs. ClusterRoleBinding A RoleBinding can’t bind a ClusterRole to a ClusterRoleBinding (and vice versa).
* in verbs verbs: ["*"] includes deletenever use in production.
ServiceAccount Tokens Tokens are long-lived by default. Rotate them regularly.

Scenario-Based Question

"You need to allow a CI/CD pipeline to deploy to staging but not production. How?"
- ✅ Answer:
- Create a Role in staging with verbs: ["create", "update", "delete"] on deployments.
- Bind it to the CI/CD ServiceAccount with a RoleBinding.
- Do not grant any permissions in production.


7. ? Hands-On Challenge


Challenge

A monitoring tool (Prometheus) needs to read all pods and nodes in the cluster but should not modify anything. Create the minimal RBAC setup for it.

Solution

  1. ClusterRole (read-only for pods and nodes):
    ```yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
    name: prometheus-reader
    rules:
  2. apiGroups: [""]
    resources: ["pods", "nodes"]
    verbs: ["get", "list", "watch"]
    ```
  3. ClusterRoleBinding (bind to Prometheus SA):
    ```yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
    name: prometheus-reader-binding
    subjects:
  4. kind: ServiceAccount
    name: prometheus
    namespace: monitoring
    roleRef:
    kind: ClusterRole
    name: prometheus-reader
    apiGroup: rbac.authorization.k8s.io
    ```
  5. Apply:
    bash
    kubectl apply -f prometheus-clusterrole.yaml -f prometheus-clusterrolebinding.yaml
    Why it works:
  6. ClusterRole grants read-only access to pods and nodes cluster-wide.
  7. ClusterRoleBinding assigns it to the Prometheus service account.
  8. No delete or create permissions = safe.

8. ? Rapid-Reference Crib Sheet

Command/Concept Example Notes
Create a Role kubectl apply -f role.yaml Always specify apiGroups.
Create a RoleBinding kubectl apply -f rolebinding.yaml Binds a Role to a subject in a namespace.
Create a ClusterRole kubectl apply -f clusterrole.yaml Grants cluster-wide permissions.
Create a ClusterRoleBinding kubectl apply -f clusterrolebinding.yaml Binds a ClusterRole to a subject cluster-wide.
Check permissions kubectl auth can-i create pods --as=system:serviceaccount:ns:sa-name Critical for debugging.
List Roles kubectl get roles -n namespace Use -A for all namespaces.
List RoleBindings kubectl get rolebindings -n namespace Use -A for all namespaces.
List ClusterRoles kubectl get clusterroles Cluster-wide.
List ClusterRoleBindings kubectl get clusterrolebindings Cluster-wide.
⚠️ Default ServiceAccount default SA in every namespace has no permissions by default. Never use it in production.
⚠️ cluster-admin Gives full control over the cluster. Never bind to a service account.
⚠️ * in resources resources: ["*"] = all resources (dangerous!). Avoid in production.
⚠️ * in verbs verbs: ["*"] = all actions (including delete). Never use in production.


9. ? Where to Go Next

  1. Kubernetes RBAC Official Docs – The definitive source.
  2. Kubernetes Security Best Practices (CNCF) – Real-world security guidance.
  3. Open Policy Agent (OPA) for Kubernetes – Advanced policy enforcement.
  4. kubectl auth can-i Explained – How to test permissions.

Final Thought

RBAC is not optional in production. Start restrictive, then loosen permissions as needed. A single misconfigured ClusterRoleBinding can take down your entire clustertest everything with kubectl auth can-i.

Now go lock down your cluster! ?



ADVERTISEMENT