K8s by Example: RBAC

RBAC controls who can do what in the cluster. Two pieces: a Role defines what actions are allowed on which resources, and a RoleBinding grants that Role to users or ServiceAccounts. Use ClusterRole and ClusterRoleBinding when you need cluster-wide access.

role.yaml

Role defines permissions within a namespace. apiGroups specifies which API group the resource belongs to: "" for core resources (pods, services, configmaps), “apps” for deployments, “rbac.authorization.k8s.io” for roles. verbs are the allowed actions.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
rolebinding.yaml

RoleBinding grants a Role to subjects (user, group, or ServiceAccount) within a namespace. The Role and RoleBinding must be in the same namespace. Can have multiple subjects.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
  - kind: ServiceAccount
    name: my-app
    namespace: default
  - kind: User
    name: jane@example.com
    apiGroup: rbac.authorization.k8s.io
  - kind: Group
    name: developers
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
clusterrole.yaml

ClusterRole + ClusterRoleBinding for cluster-wide access. Use sparingly and prefer namespace-scoped roles. ClusterRoles can also be bound to specific namespaces via RoleBinding.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-reader
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]
---
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
  - kind: ServiceAccount
    name: monitoring
    namespace: monitoring
roleRef:
  kind: ClusterRole
  name: secret-reader
---
kind: RoleBinding
metadata:
  name: read-secrets-in-default
  namespace: default
subjects:
  - kind: ServiceAccount
    name: my-app
    namespace: default
roleRef:
  kind: ClusterRole
  name: secret-reader
role-verbs.yaml

Common verbs: get, list, watch, create, update, patch, delete, deletecollection. Use * for all verbs (dangerous). Access subresources like pods/log, pods/exec separately.

rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]

  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["*"]

  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

  - apiGroups: [""]
    resources: ["pods/log", "pods/exec"]
    verbs: ["get", "create"]
role-resourcenames.yaml

Resource names restrict access to specific objects. Useful for granting access to one ConfigMap or Secret without access to all. Note: resourceNames doesn’t apply to create/list operations.

rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["my-app-config"]
    verbs: ["get", "update"]

  - apiGroups: ["apps"]
    resources: ["deployments"]
    resourceNames: ["my-app"]
    verbs: ["get", "update", "patch"]
clusterrole-aggregation.yaml

Aggregated ClusterRoles combine rules from multiple ClusterRoles. Built-in roles like admin, edit, view use aggregation. Add permissions by creating ClusterRoles with matching labels.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring
aggregationRule:
  clusterRoleSelectors:
    - matchLabels:
        rbac.example.com/aggregate-to-monitoring: "true"
rules: []
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-pods
  labels:
    rbac.example.com/aggregate-to-monitoring: "true"
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
rolebinding-builtin.yaml

Built-in ClusterRoles: cluster-admin (superuser), admin (namespace admin), edit (read/write most resources), view (read-only). Bind these for common access patterns.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: namespace-admin
  namespace: my-team
subjects:
  - kind: User
    name: alice@example.com
roleRef:
  kind: ClusterRole
  name: admin
  apiGroup: rbac.authorization.k8s.io
---
kind: RoleBinding
metadata:
  name: namespace-viewer
  namespace: my-team
subjects:
  - kind: Group
    name: contractors
roleRef:
  kind: ClusterRole
  name: view
terminal

Debug RBAC with kubectl auth can-i. Check permissions for yourself or impersonate other users/ServiceAccounts. List all permissions to understand effective access.

$ kubectl auth can-i create pods
yes

$ kubectl auth can-i delete deployments -n production
no

$ kubectl auth can-i get secrets \
    --as=system:serviceaccount:default:my-app
no

$ kubectl auth can-i '*' '*' --as=jane@example.com
no

$ kubectl auth can-i --list
Resources                          Non-Resource URLs   Verbs
pods                               []                  [get list watch]
configmaps                         []                  [get list]
...

$ kubectl auth can-i --list \
    --as=system:serviceaccount:default:my-app

Index | GitHub | Use arrow keys to navigate |