Skip to main content

Command Palette

Search for a command to run...

RBAC & ServiceAccounts in Kubernetes

Who Can Do What — And Why It Matters

Updated
5 min read
RBAC & ServiceAccounts in Kubernetes
D

I'm a DevOps enthusiast and software engineer with 3+ years of hands-on experience building scalable CI/CD pipelines, automating infrastructure, and streamlining deployment workflows. I specialize in tools like Jenkins, Maven, Docker, and Tomcat, and I love turning complex systems into elegant, maintainable solutions. On Hashnode, I share insights, tutorials, and real-world lessons from the trenches—whether it's debugging flaky builds, optimizing deployment strategies, or exploring the latest in cloud-native tech. My goal is to help developers and ops teams collaborate better, ship faster, and learn continuously.4

So far in this Kubernetes journey, we have learned how to:

  • Create clusters using kubeadm and kops

  • Understand Kubernetes architecture

  • Run workloads using Pods, ReplicaSets, and Deployments

  • Expose applications using Services

  • Externalize configuration using ConfigMaps and Secrets

  • Manage persistent storage using PersistentVolumes (PVs), PersistentVolumeClaims (PVCs), and StorageClasses

At this stage, we understand how applications are deployed, configured, networked, and how their data persists across Pod restarts.

Now comes the next critical question:

Who is allowed to create, access, or modify these resources?

In a real Kubernetes environment:

  • Not everyone should have admin access

  • Applications should not run with unrestricted permissions

  • Every action should be intentional, limited, and auditable

Kubernetes enforces this using RBAC (Role-Based Access Control) and ServiceAccounts.


🔹 Why Access Control Matters

Imagine a Kubernetes cluster where:

  • Any Pod can read Secrets

  • Any user can delete Deployments

  • Any application can modify cluster resources

This is not hypothetical — this is how many breaches begin.

In production:

  • Developers should deploy apps, not manage nodes

  • CI/CD systems should create resources, not read Secrets

  • Applications should only access what they strictly need

RBAC exists to prevent accidental damage and security incidents.


🔹 What Is RBAC?

RBAC stands for Role-Based Access Control.

RBAC answers three questions:

  1. Who is making the request?

  2. What are they trying to do?

  3. Is it allowed?

Every request to the Kubernetes API is evaluated against RBAC rules.


🔹 Core RBAC Building Blocks

RBAC in Kubernetes is composed of four resources:

  1. Role

  2. ClusterRole

  3. RoleBinding

  4. ClusterRoleBinding

They work together — none of them are useful alone.


🔹 Role vs ClusterRole

🔸Role

  • Namespace-scoped

  • Grants permissions only within one namespace

🔸ClusterRole

  • Cluster-scoped

  • Grants permissions across all namespaces

  • Commonly used by controllers and system components


🔹 RoleBinding vs ClusterRoleBinding

🔸RoleBinding

  • Grants permissions within a namespace

  • Can bind a Role or a ClusterRole

🔸ClusterRoleBinding

  • Grants permissions cluster-wide

  • Always binds a ClusterRole


🔹 Subjects in RBAC

RBAC permissions are granted to subjects:

  • Users (humans, external identity providers)

  • Groups

  • ServiceAccounts (applications inside the cluster)

For Kubernetes workloads, ServiceAccounts are the most important subject.


🔹 What Is a ServiceAccount?

A ServiceAccount is an identity used by Pods running inside the cluster.

Think of it this way:

  • Users → humans outside the cluster

  • ServiceAccounts → applications inside the cluster

Every Pod runs as a ServiceAccount.

If you do not specify one, Kubernetes assigns the default ServiceAccount automatically.


🔹 How ServiceAccounts Work Internally

When a Pod starts:

  1. Kubernetes assigns a ServiceAccount

  2. A token is generated or reused

  3. The token is mounted into the Pod at:

/var/run/secrets/kubernetes.io/serviceaccount/

Inside the Pod, Kubernetes provides:

  • token → JWT used for authentication

  • ca.crt → API server CA certificate

  • namespace → Pod’s namespace

This allows Pods to authenticate to the Kubernetes API without passwords.


🔹 Seeing ServiceAccounts in Action (Hands-On)

Exec into any running Pod:

kubectl run pod-1 --image=nginx --port=80
kubectl exec -it <pod-name> -- ls /var/run/secrets/kubernetes.io/serviceaccount

You will see:

ca.crt
namespace
token

This token is what Kubernetes uses to identify the Pod.


🔹 Why You Should Avoid the Default ServiceAccount

Using the default ServiceAccount is risky because:

  • It is shared by all Pods in the namespace

  • Permissions often grow over time

  • One compromised Pod affects others

Production rule:

One application → One ServiceAccount → One permission set


🔹 RBAC Flow (Conceptual)

At runtime:

  1. A Pod makes a request to the Kubernetes API

  2. Kubernetes identifies the ServiceAccount

  3. RBAC rules are evaluated

  4. The request is allowed or denied


🔹 Creating a Role (Read-Only Pod Access)

Manifest: pod-reader-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]

Apply and verify:

kubectl apply -f pod-reader-role.yaml
kubectl describe role pod-reader

🔹 Creating a Service Account

Manifest: service-account.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-sa
  namespace: default
kubectl apply -f app-sa.yaml
kubectl get serviceaccount app-sa

🔹 Binding Role to Service Account

Manifest: role-binding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-binding
  namespace: default
subjects:
  - kind: ServiceAccount
    name: app-sa
    namespace: default
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f pod-reader-binding.yaml
kubectl describe rolebinding pod-reader-binding

🔹 Using Service Account in a Pod

Manifest: pod-with-service-account.yaml

apiVersion: v1
kind: Pod
metadata:
  name: rbac-test-pod
spec:
  serviceAccountName: app-sa
  containers:
    - name: app
      image: bitnami/kubectl
      command: ["sleep", "3600"]

🔹 Verifying Permissions from Inside the Pod

kubectl exec -it rbac-test-pod -- sh
kubectl get pods
kubectl delete pod rbac-test-pod

Read works. Delete fails.
RBAC is enforced correctly.


🔹 Debugging RBAC with kubectl auth can-i

This is one of the most important RBAC debugging tools.

Check Permissions as Current User

kubectl auth can-i get pods
kubectl auth can-i delete pods

Check Permissions for a ServiceAccount

kubectl auth can-i get pods --as=system:serviceaccount:default:app-sa -n default

This command answers:

“Would this ServiceAccount be allowed to do this?”


🔹 Real-World RBAC Scenarios

🔸 CI/CD Pipeline (GitHub Actions / Jenkins)

Needs to:

  • Create Deployments

  • Update Services

  • Read Pods

Should NOT:

  • Read Secrets

  • Delete namespaces

→ Use Role + RoleBinding scoped to one namespace.


🔸 Ingress Controller

Needs to:

  • Watch Services and Endpoints

  • Read Ingress resources

  • Work across namespaces

→ Use ClusterRole + ClusterRoleBinding.


🔸 Monitoring Tools (Prometheus)

Needs to:

  • Read Pods, Nodes, Metrics

  • Watch resources cluster-wide

→ Use ClusterRole with read-only permissions.


🔹 RBAC Best Practices

  • Follow least privilege

  • Avoid cluster-admin

  • Create one ServiceAccount per workload

  • Scope permissions tightly

  • Regularly audit access

  • Disable token auto-mounting when not required:

automountServiceAccountToken: false

🔹 Summary

  • ServiceAccounts define identity

  • RBAC defines permissions

  • Bindings connect identity to permissions

  • Every Pod runs as a ServiceAccount

  • Secure clusters start with correct RBAC

If Kubernetes runs your workloads,
RBAC decides what they are allowed to do.