Chapter 43 of 47 · Security

Access control: RBAC

Everything in Kubernetes is a request to the API server: "list Pods", "delete this Deployment", "read that Secret". RBAC (Role-Based Access Control) decides which requests are allowed. Think of it as the key cards in an office building: each card opens some doors and not others.

Who are you, and what may you do?

Every request goes through two checks at the front desk of the API server:

Authentication, then authorizationA request first passes authentication, which answers who you are, then authorization (RBAC), which answers whether you may do this. Only then does the API server act. Request"delete pod posts-1" 1 · AuthenticationWho are you?certificate, token, SSO 2 · AuthorizationMay you do this?RBAC rules Doneor 403 Forbidden like showing your ID cardlike checking which doors it opens

Subjects: users, groups, ServiceAccounts

A subject is whoever is making the request.

User

A person, like alice. Only a name inside a certificate or token; there is no User object to create.

Group

A set of users, like developers. Comes from the same login system. Bind a role to a group instead of to ten people.

ServiceAccount

An identity for programs running in Pods, like a CI tool or a controller. A real Kubernetes object, living in a namespace.

The four objects

RBAC is just two questions: what is allowed (a Role) and who gets it (a binding). Each comes in a namespace version and a cluster-wide version:

Inside one namespaceWhole cluster
What is allowedRoleClusterRole
Who gets itRoleBindingClusterRoleBinding
A binding connects subjects to a role Subjectsalice, developers, posts-sa RoleBindingthe "key card" Rolelist of allowed actions Roles say nothing about who. Bindings say nothing about what. Together they grant access.
Handy mix: a RoleBinding can point to a ClusterRole. You define a role like "pod-reader" once, cluster-wide, and grant it per namespace. Kubernetes already ships useful ClusterRoles: view, edit, admin and cluster-admin.

Writing a Role

A rule is three lists: which API groups, which resources, which verbs. Click the parts:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: blog-editor
  namespace: blog
rules:
  - apiGroups: ["", "apps"]
    resources: ["pods", "services", "configmaps", "deployments"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-edit
  namespace: blog
subjects:
  - kind: Group
    name: developers
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: blog-editor
  apiGroup: rbac.authorization.k8s.io

verbs

The actions: get (one), list and watch (many), create, update, patch, delete. Read-only access is just get, list, watch.

Try it: can they do it?

This cluster has four subjects and four bindings. Pick a subject, an action and a namespace. The answer is exactly what kubectl auth can-i would say:

Try: alice deleting Pods in blog (yes) and in payments (no). bob listing Pods anywhere (yes, a ClusterRoleBinding). anyone reading secrets (no one).

ServiceAccounts for your Pods

Every Pod runs as a ServiceAccount. If you do not choose one, it gets the namespace's default ServiceAccount. Kubernetes can mount a short-lived token for it into the Pod, so code in the Pod can call the API.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: posts-sa
  namespace: blog
---
# in the Deployment's Pod template
spec:
  serviceAccountName: posts-sa
  containers:
    - name: posts
      image: micro-posts:1.0

Give the app its own ServiceAccount, and bind only the Role it needs, for example "read ConfigMaps". Never give extra rights to default; every Pod in the namespace would get them.

kubectl auth can-i

$ kubectl auth can-i create deployments -n blog
yes

$ kubectl auth can-i get secrets -n blog --as=alice
no

$ kubectl auth can-i list configmaps -n blog \
    --as=system:serviceaccount:blog:posts-sa
yes

$ kubectl auth can-i --list -n blog --as=alice     # everything alice may do

--as lets an admin test as someone else, without logging in as them. Use it after every RBAC change.

Dangerous permissions

Some rights look harmless but quietly give away much more. Pick the safe answer:

Also watch out for pods/exec (a shell in any container), escalate and bind on roles (grant yourself more), and impersonate (act as anyone).

RBAC for the blog app

WhoGetsHow
posts, comments, query, moderation, event-busNothingautomountServiceAccountToken: false
Developers (group)Edit in blog, no SecretsRoleBinding to a custom Role, or to edit if Secret access is acceptable
Support teamRead-onlyRoleBinding to view
CI pipelineUpdate Deployments in blogIts own ServiceAccount + a small Role
Cluster admins (2 people)EverythingClusterRoleBinding to cluster-admin

Good RBAC pairs well with network rules (chapter 28) and locked-down containers (chapter 42).

Recap

Quick check

alice has a RoleBinding to the ClusterRole edit in namespace blog. Can she edit Deployments in payments?
Show answer

No. A RoleBinding only grants access inside its own namespace, even when it points to a ClusterRole. Only a ClusterRoleBinding reaches every namespace.

RBAC: common questions

What is the difference between a Role and a ClusterRole?

A Role grants permissions inside one namespace. A ClusterRole is defined cluster-wide and can cover cluster resources like nodes; it can be granted per namespace with a RoleBinding or everywhere with a ClusterRoleBinding.

How do I check if a user can do something?

Run kubectl auth can-i with the verb, resource and namespace, and add --as to test as another user or ServiceAccount.