CKSKubernetes 1.35

Lessons

RBAC: give exactly the verbs asked for

updated 2026-10-22 by seed

The four objects, and when each is right

objectscopeuse when
Rolenamespacepermissions inside one namespace
ClusterRoleclustercluster-scoped resources, or a reusable permission set
RoleBindingnamespacegrants a Role or a ClusterRole inside one namespace
ClusterRoleBindingclustergrants cluster-wide — the dangerous one

A ClusterRole bound with a RoleBinding is the trick question: the rules are
cluster-shaped, the effect is namespaced.

Task: a user who can only read Pods and logs in one namespace

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: {name: pod-reader, namespace: prod}
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: {name: pod-reader-binding, namespace: prod}
subjects:
- kind: User
  name: jane            # exact string from the CSR / certificate CN
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

roleRef is immutable — to change what a binding grants you delete and
recreate it. kubectl auth reconcile does that for you:

kubectl auth reconcile -f /tmp/rbac.yaml --remove-extra-permissions

Prove it — always

kubectl auth can-i list pods -n prod --as jane
kubectl auth can-i delete pods -n prod --as jane        # must be "no"
kubectl auth can-i --list -n prod --as jane             # the whole effective set
kubectl auth can-i list pods --as=system:serviceaccount:prod:api

--as requires your own account to be allowed to impersonate; as cluster-admin
it is fine, and it is the only honest way to check.

Cleaning up an over-permissive role

The task usually gives you a role with * verbs or secrets access and asks you
to reduce it to what a workload needs:

kubectl get clusterrole over-permissive -o yaml > /tmp/cr.yaml
# keep only the apiGroups/resources/verbs the task lists, delete the rest
kubectl apply -f /tmp/cr.yaml
kubectl auth can-i --list --as=system:serviceaccount:prod:api

Watch for resources: ["*"], verbs: ["*"], apiGroups: ["*"], and for
secrets in a role that only ever reads configmaps. Deleting a rule is safe;
deleting the whole role breaks the workload and the marker checks the workload.

Default roles you should recognise

  • cluster-admin — * on everything. Bind it to a named user for a task, never to a workload.
  • admin — full control inside a namespace, not of the namespace object.
  • edit — read/write most objects, no RBAC, no Secrets read in some versions.
  • view — read-only on most, never Secrets.
  • system:aggregate-to-* — the aggregation labels that build admin/edit/view.

Aggregated ClusterRoles

kind: ClusterRole
metadata:
  name: monitoring-read
  labels: {rbac.example.com/aggregate-to-view: "true"}
rules:
- apiGroups: [""]
  resources: ["pods", "nodes"]
  verbs: ["get", "list", "watch"]

If the label matches the view aggregator, the rules land inside view
automatically. The exam rarely asks for this, but it explains why some rules seem
to come from nowhere when you read kubectl get clusterrole view -o yaml.