Skip to main content

Kubernetes Ep 13: RBAC, ServiceAccounts & Security

Rachmat Hidayat
Author
Rachmat Hidayat
Learn & sharing insights on TypeScript, Go, Kubernetes, DevOps, DevSecOps, SRE, Platform Engineering, AI/ML Engineering, and MLOps.
kubernetes - This article is part of a series.
Part 13: This Article
Security in Kubernetes follows the Principle of Least Privilege. Role-Based Access Control (RBAC) regulates who (Users, Groups, or ServiceAccounts) can perform which actions (verbs: 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"] on resources: ["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.io

Apply manifest:

kubectl apply -f rbac-namespace.yaml

3. 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 default

Expected Terminal Output:

yes

Now check if developer-sa can delete pods:

kubectl auth can-i delete pods --as=system:serviceaccount:default:developer-sa -n default

Expected Terminal Output:

no

4. 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.io

Apply manifest:

kubectl apply -f rbac-cluster.yaml

5. 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!

kubernetes - This article is part of a series.
Part 13: This Article