RBAC cheatsheet.

Core resources

  • Role: permissions in a namespace.
  • ClusterRole: cluster-wide.
  • RoleBinding: assign Role to subjects in a namespace.
  • ClusterRoleBinding: assign ClusterRole cluster-wide.
  • ServiceAccount: identity for pods.

ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata: { name: deployer, namespace: prod }

Use in pod:

spec:
  serviceAccountName: deployer

Token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token.

Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: { namespace: prod, name: pod-reader }
rules:
  - apiGroups: [""]
    resources: [pods, pods/log]
    verbs: [get, list, watch]
  - apiGroups: [apps]
    resources: [deployments]
    verbs: [get, list]

RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: { name: deployer-can-read, namespace: prod }
subjects:
  - kind: ServiceAccount
    name: deployer
    namespace: prod
  - kind: User
    name: [email protected]
  - kind: Group
    name: developers
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata: { name: view-everything }
rules:
  - apiGroups: ["*"]
    resources: ["*"]
    verbs: [get, list, watch]

ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata: { name: alice-admin }
subjects:
  - kind: User
    name: [email protected]
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

Verbs

get, list, watch
create, update, patch
delete, deletecollection
*  (all)

Resource names

rules:
  - apiGroups: [""]
    resources: [pods]
    resourceNames: [web, api]      # only these specific pods
    verbs: [get]

Subresources

resources: [pods, pods/log, pods/exec, pods/portforward]

pods/exec is needed for kubectl exec.

Built-in roles

  • cluster-admin: superuser.
  • admin: full admin in namespace.
  • edit: edit but not RBAC.
  • view: read-only.
kubectl get clusterroles

Check permissions

kubectl auth can-i create deployments
kubectl auth can-i create deployments --namespace=prod
kubectl auth can-i '*' '*' --all-namespaces

# As another user
kubectl auth can-i list pods --as=[email protected]
kubectl auth can-i list pods --as=system:serviceaccount:prod:deployer

Pods using SA

kubectl get pods -o jsonpath='{.items[*].spec.serviceAccountName}'

Bind SA to Role concisely

kubectl create rolebinding deployer-reads \
  --role=pod-reader \
  --serviceaccount=prod:deployer \
  -n prod

API access from pod

Pod can talk to K8s API using its SA token:

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
CA=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
curl --cacert $CA -H "Authorization: Bearer $TOKEN" \
  https://kubernetes.default.svc/api/v1/namespaces/prod/pods

Aggregated ClusterRoles

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: my-aggregated
aggregationRule:
  clusterRoleSelectors:
    - matchLabels: { rbac.example.com/aggregate-to-my: "true" }
rules: []                # filled by aggregation
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: my-component
  labels: { rbac.example.com/aggregate-to-my: "true" }
rules:
  - apiGroups: [example.com]
    resources: [things]
    verbs: [get, list]

Composable role definitions.

Impersonation

kubectl --as=[email protected] get pods
kubectl --as=system:serviceaccount:prod:deployer get pods
kubectl --as-group=developers get pods

Useful for testing RBAC.

Audit logs

# /etc/kubernetes/audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Metadata
    resources:
      - group: ""
        resources: [secrets]
  - level: RequestResponse
    resources:
      - group: "rbac.authorization.k8s.io"

Audit logs show who did what. Critical for compliance.

OIDC / SSO

Cluster connects to OIDC provider (Google, GitHub, Okta, Dex):

# kube-apiserver flags
--oidc-issuer-url=https://accounts.google.com
--oidc-client-id=...
--oidc-username-claim=email
--oidc-groups-claim=groups

Users authenticate via OIDC; RBAC matches by username/group claims.

Cloud-managed: EKS uses IAM, GKE uses Google, AKS uses Entra.

Principle of least privilege

Per-service ServiceAccounts:

# Don't use the `default` SA
serviceAccountName: web

Grant only what’s needed:

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

Common mistakes

  • Granting cluster-admin casually.
  • Using default SA everywhere.
  • Wildcards (*) in rules.
  • ClusterRoleBinding when RoleBinding suffices.
  • Forgetting subresources (pods/log, pods/exec).

Read this next

If you want my RBAC presets per role, they’re at rajpoot.dev .


Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .