08 - Namespaces, RBAC & Security Basics
Why this matters
This is how multi-tenant clusters stay safe — who can do what, to which resources, in which namespace. Get this wrong and any compromised pod/service account can become a cluster-admin.
Read this first — Definitions & Explanations
Namespace
A scope for names and access. Lets you split environments/teams (dev, prod) and apply RBAC/quotas per space. Cluster-scoped objects (nodes, PVs, StorageClasses) live outside namespaces.
RBAC
Role-Based Access Control: who can do what on which resources.
Role vs ClusterRole
- Role: permissions inside one namespace
- ClusterRole: cluster-wide permissions (or reusable permission sets)
RoleBinding / ClusterRoleBinding
Binds a Role/ClusterRole to subjects: users, groups, or ServiceAccounts.
ServiceAccount
Identity for processes running in Pods (not humans). Controllers and apps use ServiceAccounts to call the API.
Least privilege
Grant only the verbs/resources needed (get/list/watch on pods — not * on *.*). Over-privileged ServiceAccounts are a common breach path.
Official docs (read for detail)
Key Concepts
- Namespaces: logical isolation (not a security boundary by itself!)
- ServiceAccounts: identity for pods/processes (not humans)
- Role / RoleBinding: namespace-scoped permissions
- ClusterRole / ClusterRoleBinding: cluster-wide permissions
- Default ServiceAccount auto-mounting — a common accidental privilege leak
kubectl auth can-i— the tool to actually check permissions- Aggregated ClusterRoles
- Security basics preview:
securityContext, running as non-root (deep dive in Phase 3)
YouTube search terms
- "Kubernetes RBAC explained Role RoleBinding ClusterRole"
- "Kubernetes ServiceAccounts explained"
- "Kubernetes namespaces are not a security boundary"
Hands-on lab (on prod-sim)
kubectl create namespace team-a
kubectl create serviceaccount deployer -n team-a
# Give it permission to only manage deployments in team-a, nothing else
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-a
name: deployment-manager
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get","list","watch","create","update","patch","delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployer-binding
namespace: team-a
subjects:
- kind: ServiceAccount
name: deployer
namespace: team-a
roleRef:
kind: Role
name: deployment-manager
apiGroup: rbac.authorization.k8s.io
EOF
# Prove the scoped permissions
kubectl auth can-i create deployments --as=system:serviceaccount:team-a:deployer -n team-a # yes
kubectl auth can-i delete secrets --as=system:serviceaccount:team-a:deployer -n team-a # no
kubectl auth can-i create deployments --as=system:serviceaccount:team-a:deployer -n default # no (namespace-scoped)
# See what the default ServiceAccount can do (should be almost nothing by default)
kubectl auth can-i --list --as=system:serviceaccount:team-a:default -n team-a
# Disable auto-mounting the SA token where it's not needed (good hardening habit)
kubectl patch serviceaccount default -n team-a -p '{"automountServiceAccountToken": false}'
Notes
(fill in your own words after watching + labbing)