Request pipeline

Client request
    1. Authentication : who is the caller?
    2. Authorization  : is the caller allowed? (RBAC)
    3. Admission      : is the object valid?
    etcd
  • Passes RBAC but still rejected at admission (ResourceQuota, Pod Security)
  • Admission runs after RBAC

RBAC primitives

ResourceScopePurpose
RoleNamespaceDefines allowed verbs on resources
ClusterRoleCluster-wideSame but cluster-scoped
RoleBindingNamespaceBinds Role to user/group/SA
ClusterRoleBindingCluster-wideBinds ClusterRole cluster-wide
  • Core resources: apiGroups: [""]; Deployments: apiGroups: [apps]
  • For exec: pods/exec resource. For logs: pods/log

RBAC: create role + binding

kubectl create role pod-reader --verb=get,list,watch --resource=pods -n dev
kubectl create rolebinding pod-reader-binding --role=pod-reader --serviceaccount=dev:my-sa -n dev
kubectl create rolebinding pod-reader-binding --role=pod-reader --user=jane -n dev

kubectl create clusterrole node-reader --verb=get,list --resource=nodes
kubectl create clusterrolebinding node-reader-binding --clusterrole=node-reader --serviceaccount=default:my-sa
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: read-only
rules:
- apiGroups: [""]
  resources: [pods, services]
  verbs: [list, get, watch]
- apiGroups: [apps]
  resources: [deployments]
  verbs: [list, get, watch]

Subresources (exec, logs)

rules:
- apiGroups: [""]
  resources: [pods]
  verbs: [get, list]
- apiGroups: [""]
  resources: [pods/exec]    # kubectl exec
  verbs: [create]
- apiGroups: [""]
  resources: [pods/log]     # kubectl logs
  verbs: [get]

ClusterRoleBinding YAML

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-reader-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: node-reader
subjects:
- kind: ServiceAccount
  name: my-sa
  namespace: default         # required for SA subjects
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io

Verify permissions

TaskCommand
Test if action allowedkubectl auth can-i get pods --as=system:serviceaccount:dev:my-sa
Test current userkubectl auth can-i delete deployments
List all permissionskubectl auth can-i --list

Kubeconfig

kubectl config view
kubectl config set-context --current --namespace=<ns>
kubectl config current-context
kubectl config get-contexts
kubectl config use-context <context>

Built-in ClusterRoles

  • cluster-admin: all namespaces
  • admin: full NS access incl. RBAC
  • edit: read/write NS (no RBAC objects)
  • view: read-only (no Secrets)

ServiceAccounts

kubectl create serviceaccount my-sa
kubectl run pod --image=nginx --serviceaccount=my-sa
kubectl describe serviceaccount my-sa
spec:
  serviceAccountName: my-sa
  automountServiceAccountToken: false
  • SA token auto-mounted at /var/run/secrets/kubernetes.io/serviceaccount/token
  • SA format for --as: system:serviceaccount:<namespace>:<sa-name>

Admission control

Two phases

PhaseBehaviour
MutatingModify object (inject defaults, sidecars)
ValidatingCheck rules; cannot modify

Built-in plugins

PluginWhat it does
LimitRangerApplies LimitRange defaults; enforces min/max
ResourceQuotaRejects objects exceeding namespace totals
ServiceAccountAuto-mounts SA token
DefaultStorageClassSets default storageClassName on PVCs
PodSecurityEnforces Pod Security Standards

Pod Security admission labels

kubectl label namespace production \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/enforce-version=latest

kubectl label namespace staging \
  pod-security.kubernetes.io/audit=restricted
LabelEffect
pod-security.kubernetes.io/enforceBlock violating Pods
pod-security.kubernetes.io/auditLog violations
pod-security.kubernetes.io/warnReturn warning

Debugging admission vs RBAC failures

Error containsLayerFix
Forbidden + user cannotAuthorizationFix Role/RoleBinding verbs
Forbidden + exceeded quotaAdmission (ResourceQuota)Reduce resources or raise quota
Forbidden + LimitRange / maxAdmission (LimitRanger)Adjust container resources
Forbidden + PodSecurity / violatesAdmission (Pod Security)Fix securityContext
kubectl apply -f pod.yaml --dry-run=server
kubectl get events -n <ns> --sort-by='.lastTimestamp'

Exam gotchas

  • Pattern: create SA, create Role, bind, verify with auth can-i
  • Deployments need separate rule with apiGroups: [apps]
  • RBAC allowed =/= Pod created: check admission if Forbidden mentions quota/LimitRange/PodSecurity
  • ResourceQuota namespaces: every container needs requests and limits; LimitRange provides defaults
  • enforce=restricted: needs runAsNonRoot, dropped capabilities, no privileged containers

Practice scenario: Deployment, Service, RBAC

Tasks

  • NS prod → Deployment payment-api (python:3.9, 2 replicas)
  • SA payment-app → read ConfigMaps in prod
  • Service payment-svc: port 8080 → target 5000
  • SA auditor → get/list Secrets only
Solution
kubectl create ns prod
kubectl create deploy payment-api --image=python:3.9 --replicas=2 -n prod
kubectl create sa payment-app -n prod
kubectl create role config-reader --verb=get,list --resource=configmaps -n prod
kubectl create rolebinding payment-binding --role=config-reader --serviceaccount=prod:payment-app -n prod
kubectl expose deploy payment-api --port=8080 --target-port=5000 --name=payment-svc -n prod
kubectl create sa auditor -n prod
kubectl create role secret-reader --verb=get,list --resource=secrets -n prod
kubectl create rolebinding auditor-binding --role=secret-reader --serviceaccount=prod:auditor -n prod
kubectl auth can-i get configmaps --as=system:serviceaccount:prod:payment-app -n prod