Cluster Security & Authorization: RBAC, ServiceAccounts, and Admission Webhooks
Understanding the 3-phase API security pipeline: Authentication, Authorization, and Admission Control.
Part 17 in Series — Catch up on the previous article: Kubernetes Scheduler Internals: Filtering (Predicates), Scoring (Priorities), and Affinities (Part 16) before diving into this post.
An attacker gains Remote Code Execution (RCE) inside a vulnerable web analytics Pod running in a production Kubernetes cluster.
The attacker checks the local filesystem and discovers a JWT token automatically mounted by Kubernetes:
cat /var/run/secrets/kubernetes.io/serviceaccount/token
Using this token, the attacker issues a curl request directly to the internal API server:
curl -k -H "Authorization: Bearer $(cat /var/run/.../token)" \
https://kubernetes.default.svc/api/v1/namespaces/default/pods
In an unhardened cluster, the API Server responds with HTTP 200 OK and returns full cluster secrets, node IP lists, and pod manifests.
The attacker uses the token to delete production workloads across the entire cluster.
When the cluster enforces strict Role-Based Access Control (RBAC) and Admission Webhooks:
The API Server immediately rejects the attacker’s request with:
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:web-api" cannot list resource "pods" in API group "" in the namespace "default"
How does kube-apiserver secure cluster access using Authentication, RBAC Authorization, and Admission Webhooks?
1. The 3-Phase API Security Pipeline
Every HTTP request submitted to kube-apiserver must pass through a strict 3-phase security pipeline before any state modification is written to etcd:
[ Incoming HTTP REST Request ]
|
v
+-------------------------------------------------------------------+
| PHASE 1: AUTHENTICATION (Who are you?) |
| Validates identity via X.509 Certs, OIDC Tokens, or ServiceAccount|
+-------------------------------------------------------------------+
|
v Authenticated Subject (User / ServiceAccount)
+-------------------------------------------------------------------+
| PHASE 2: AUTHORIZATION (What are you allowed to do?) |
| Evaluates RBAC Rules (Roles, ClusterRoles, RoleBindings) |
+-------------------------------------------------------------------+
|
v Authorized Request
+-------------------------------------------------------------------+
| PHASE 3: ADMISSION CONTROL (Is the payload valid & compliant?) |
| Executed by Mutating Webhooks & Validating Webhooks |
+-------------------------------------------------------------------+
|
v Validated Payload
[ Persist State Change to etcd Storage ]
2. Phase 1: Authentication (ServiceAccounts & Identity)
Kubernetes distinguishes between two types of identities:
- Human Users: Authenticated via X.509 Client Certificates, OIDC providers (Okta, Google Workspace), or Webhook tokens. (Kubernetes does not store user accounts in
etcd). - ServiceAccounts: Managed identities stored in
etcdassigned to Pods for in-cluster API communication.
apiVersion: v1
kind: ServiceAccount
metadata:
name: payment-processor-sa
namespace: production
When a Pod runs with serviceAccountName: payment-processor-sa, the Kubelet automatically projects a short-lived, auto-rotating JWT ServiceAccount token into /var/run/secrets/kubernetes.io/serviceaccount/token.
3. Phase 2: Authorization (RBAC Mechanics)
Once identity is authenticated, the API Server evaluates Role-Based Access Control (RBAC).
RBAC uses four core objects to define permissions:
RBAC ARCHITECTURE
|
+------------------------------+------------------------------+
| |
v v
[ Permissions Definition ] [ Identity Binding ]
- Role (Namespace-Scoped) - RoleBinding (Namespace-Scoped)
- ClusterRole (Cluster-Wide) - ClusterRoleBinding (Cluster-Wide)
Defining Permissions (Role / ClusterRole)
A Role grants permissions on specific API Groups, Resources, and Verbs (get, list, watch, create, update, delete):
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""] # "" indicates core API group
resources: ["pods", "configmaps"]
verbs: ["get", "list", "watch"] # NO 'delete' or 'create' permissions!
Binding Permissions (RoleBinding)
A RoleBinding links a Role to a ServiceAccount or User:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: production
subjects:
- kind: ServiceAccount
name: payment-processor-sa
namespace: production
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Least-Privilege Security Principle: Grant ServiceAccounts minimum required verbs on specific namespaces. Never assign cluster-admin bindings to application workloads!
4. Phase 3: Admission Control & Webhooks
Even if an authenticated request is authorized by RBAC, it must pass Admission Controllers.
Admission controllers inspect and modify request payloads before they are written to etcd.
[ Authorized Request ]
|
v
+-------------------------------------------------------------------+
| 1. Mutating Admission Webhooks |
| Modifies payload (e.g., injects Istio sidecar, adds default labels)|
+-------------------------------------------------------------------+
|
v
+-------------------------------------------------------------------+
| 2. Object Schema Validation |
| Verifies YAML schema syntax and data types |
+-------------------------------------------------------------------+
|
v
+-------------------------------------------------------------------+
| 3. Validating Admission Webhooks |
| Validates rules (e.g., blocks root containers, enforces limits)|
| Returns ALLOW or REJECT |
+-------------------------------------------------------------------+
A. Mutating Admission Webhooks
Can modify incoming resource manifests.
- Use Case: Linkerd or Istio service meshes use Mutating Webhooks to automatically inject sidecar proxy containers into newly created Pod manifests.
B. Validating Admission Webhooks
Can accept or reject incoming resource manifests.
- Use Case: Policy engines (OPA Gatekeeper, Kyverno) execute business rules (e.g., “Reject any Pod where
imageuses tag:latestor runs asroot”).
Summary & Next Steps
Kubernetes enforces security across a 3-phase execution pipeline:
- Authentication verifies identity via X.509 client certificates or ServiceAccount JWT tokens.
- RBAC Authorization enforces least-privilege permissions by linking
ServiceAccountstoRoles(get,list,watch). - Mutating Webhooks modify incoming resource manifests (e.g., sidecar injection).
- Validating Webhooks enforce cluster security compliance policies before persisting state changes to
etcd.
In the next article, we examine Extending Kubernetes: Custom Resource Definitions (CRDs) and the Operator Pattern.
References & Further Reading
- CNCF Istio Project. Istio Service Mesh Architecture & Envoy xDS Control Plane. Istio Docs.
- CNCF Linkerd Project. Linkerd Lightweight Rust-based Service Mesh Architecture. Linkerd Docs.
- Posta, C. (2021). Istio in Action. Manning Publications.
Part 18: Extending Kubernetes: Custom Resource Definitions (CRDs) and the Operator Pattern
Continue to Part 18 →