08 · Security

Least privilege that works

Grant what the documented behaviour needs. Check access as the workload, and read every denial.

The model

An access decision has three parts: who (a user or ServiceAccount), what (a verb on a resource) and where (a namespace or the whole cluster). Kubernetes RBAC is additive: a request is allowed only if a bound Role or ClusterRole grants it.

A denial is evidence. 401 means the identity was not recognised; 403 means it was recognised and refused. Close that one gap. Widening a role silences the symptom and hands over everything else. For a sign-in, find which hop refused, browser, identity provider or application, and read its reason.

A Role grants nothing outside its namespaceServiceAccount agent in namespace ops is bound to Role pod-reader in ops. Listing pods in ops is allowed; listing pods in shop is refused with 403 because no binding exists there. ServiceAccount ops/agent bound in ops Role pod-reader (ops) pods in opsallowed pods in shop403 Forbidden
Illustrative — fictional names; one identity, grants per namespace.

Worked example

A metrics agent runs as ServiceAccount agent in ops. It lists pods in ops but gets 403 Forbidden in shop. Its Role and RoleBinding exist only in ops. The narrow repair is a Role and RoleBinding in shop for the same rule, not a cluster-wide binding to cluster-admin.

Then ask the API as the agent, and confirm the agent itself succeeds. Your own kubectl access says nothing about its access.

Commands worth running

Example names are fictional. Read before you grant.

kubectl auth can-i list pods -n shop \
  --as=system:serviceaccount:ops:agent

Asks the authorizer on the workload’s behalf and prints yes or no. Impersonation needs its own permission.

kubectl get rolebindings -n shop -o wide

Shows which Role each binding grants, and to which subjects. Read the Role’s rules before editing anything.

openssl s_client \
  -connect web.example:443 \
  -servername web.example </dev/null \
  | openssl x509 -noout -subject -enddate

Shows the certificate actually served. After a rotation the end date should move; if not, the server still holds the old one.

Self-check

References

Practise it