RBAC and ServiceAccounts

Kubernetes · lesson 21 of 32 · 4 min read

Give people and pods only the API access they actually need, using Roles and bindings.

Open this lesson in the learning hub

Key points

  • Every pod runs as a ServiceAccount. Leave it unset and it gets default, which should be granted nothing at all.
  • A Role lists verbs on resources inside one namespace. A ClusterRole is the same idea across the whole cluster.
  • A binding joins a role to a subject. A RoleBinding may point at a ClusterRole to reuse it in a single namespace.
  • RBAC is additive and deny-by-default. There are no deny rules, so a permission can be granted but never subtracted.
  • If a pod never calls the API, set automountServiceAccountToken: false and it stops carrying a usable token around.
  • Prove it before you ship: kubectl auth can-i delete pods --as=system:serviceaccount:prod:ci-bot.

Example

apiVersion: v1
kind: ServiceAccount
metadata:
  name: ci-bot
  namespace: prod
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployer
  namespace: prod
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "patch"]      # no delete, no secrets
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-bot-deployer
  namespace: prod
subjects:
  - kind: ServiceAccount
    name: ci-bot
    namespace: prod
roleRef:
  kind: Role
  name: deployer
  apiGroup: rbac.authorization.k8s.io
---
# in the pod template
spec:
  serviceAccountName: ci-bot
  automountServiceAccountToken: false    # for pods that never call the API

Bind the smallest Role that works, then prove it with kubectl auth can-i.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Kubernetes course, and every lesson in it is listed on the Kubernetes contents page.