Overall Analogy: Building Access Card System#

RBAC is easy to understand when compared to a building access card system:

Building Access AnalogyKubernetes RBACRole
Access permission set (3rd floor server room access)RoleDefine allowed operations within a specific Namespace
Master key for all buildingsClusterRoleDefine allowed operations across the entire cluster
Grant permission to employee badgeRoleBindingAssign a Role to a user
Grant access to all branchesClusterRoleBindingAssign a ClusterRole to a user
Employee badgeServiceAccountAuthentication identity used by Pods
“Access only necessary areas” principlePrinciple of Least PrivilegeGrant only required permissions

In this way, RBAC is like systematically managing “who can do what and where.”


Target Audience: Operators setting up security and access control for Kubernetes clusters Prerequisites: Namespace, Pod, ServiceAccount basic concepts After reading this: You will understand how to manage access permissions using RBAC

TL;DR
  • RBAC controls Kubernetes API access based on roles
  • Role defines Namespace-scoped permissions, ClusterRole defines cluster-scoped permissions
  • RoleBinding/ClusterRoleBinding assigns roles to users

What Is RBAC?#

RBAC (Role-Based Access Control) is a mechanism that controls access to the Kubernetes API based on the roles of users or services.

ComponentDescription
RoleDefine allowed operations (permissions) within a Namespace
ClusterRoleDefine permissions across the entire cluster
RoleBindingAssign a Role to a user in a specific Namespace
ClusterRoleBindingAssign a ClusterRole to a user across the entire cluster
ServiceAccountAuthentication identity for Pods to access the Kubernetes API

RBAC Component Relationships#

flowchart TB
    subgraph Subjects["Subjects (Who)"]
        U["User"]
        G["Group"]
        SA["ServiceAccount"]
    end

    subgraph Bindings["Bindings (Connection)"]
        RB["RoleBinding<br>Namespace scope"]
        CRB["ClusterRoleBinding<br>Cluster scope"]
    end

    subgraph Roles["Roles (What)"]
        R["Role<br>Namespace scope"]
        CR["ClusterRole<br>Cluster scope"]
    end

    subgraph Resources["Resources (Where)"]
        POD["Pods"]
        SVC["Services"]
        DEP["Deployments"]
        NS["Namespaces"]
        NODE["Nodes"]
    end

    U --> RB
    U --> CRB
    G --> RB
    G --> CRB
    SA --> RB
    SA --> CRB

    RB --> R
    RB --> CR
    CRB --> CR

    R --> POD
    R --> SVC
    R --> DEP
    CR --> POD
    CR --> SVC
    CR --> DEP
    CR --> NS
    CR --> NODE

Role vs ClusterRole#

Role (Namespace Scope)#

Defines permissions for resources within a specific Namespace.

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

ClusterRole (Cluster Scope)#

Defines permissions for resources across the entire cluster.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-reader
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "list"]

Available Verbs#

VerbDescriptionHTTP Method
getRetrieve a single resourceGET
listRetrieve a list of resourcesGET
watchWatch for resource changesGET (watch)
createCreate a resourcePOST
updateModify a resourcePUT
patchPartially modify a resourcePATCH
deleteDelete a resourceDELETE

RoleBinding vs ClusterRoleBinding#

RoleBinding#

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: team-a
subjects:
- kind: User
  name: developer-kim
  apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
  name: app-sa
  namespace: team-a
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding#

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-nodes
subjects:
- kind: Group
  name: ops-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: node-reader
  apiGroup: rbac.authorization.k8s.io
ItemRoleBindingClusterRoleBinding
ScopeSpecific NamespaceEntire cluster
Referenceable RoleRole, ClusterRoleClusterRole only
Use casePer-team permissionsCluster admin permissions
Tip: ClusterRole + RoleBinding Combination
Referencing a ClusterRole with a RoleBinding applies that permission only to a specific Namespace, not the entire cluster. This is useful for reusing common permission sets across multiple Namespaces.

ServiceAccount#

Pods access the Kubernetes API through ServiceAccounts.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-sa
  namespace: team-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: team-a
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      serviceAccountName: app-sa    # Specify ServiceAccount
      containers:
      - name: app
        image: my-app:1.0
Warning
If you don’t specify a ServiceAccount, the default ServiceAccount is used. In production, always create a dedicated ServiceAccount and grant only minimum permissions.

Principle of Least Privilege#

You must follow the Principle of Least Privilege when configuring RBAC.

PrincipleDescription
Grant only required permissionsAvoid using * (wildcard)
Prefer Namespace scopeUse Role over ClusterRole
Use dedicated ServiceAccountsAvoid using the default SA
Perform regular permission auditsClean up unnecessary permissions

Comparison of incorrect and correct examples.

# Bad example: Overly broad permissions
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]

# Good example: Specify only needed permissions
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "update"]

Built-in ClusterRoles#

Kubernetes provides commonly used permission sets by default.

ClusterRoleDescription
cluster-adminFull permissions across the entire cluster
adminManage most resources within a Namespace
editRead/write resources within a Namespace (cannot modify RBAC)
viewRead-only access to resources within a Namespace
# Check built-in ClusterRoles
kubectl get clusterroles | grep -E "^(cluster-admin|admin|edit|view)"

Hands-on: Configuring RBAC#

Create ServiceAccount and Role#

# Create ServiceAccount
kubectl create serviceaccount app-sa -n team-a

# Create Role
kubectl apply -f role.yaml

# Create RoleBinding
kubectl apply -f rolebinding.yaml

# Verify permissions
kubectl auth can-i get pods --as system:serviceaccount:team-a:app-sa -n team-a
# yes

kubectl auth can-i delete pods --as system:serviceaccount:team-a:app-sa -n team-a
# no

Test Permissions#

# Check a user's permissions
kubectl auth can-i list deployments --as developer-kim -n team-a

# Check all permissions for the current user
kubectl auth can-i --list -n team-a

Frequently Used kubectl Commands#

CommandDescription
kubectl get roles -n <namespace>List Roles
kubectl get rolebindings -n <namespace>List RoleBindings
kubectl get clusterrolesList ClusterRoles
kubectl describe role <name> -n <namespace>Role details
kubectl auth can-i <verb> <resource> --as <user>Check permissions
kubectl create role <name> --verb=<verbs> --resource=<resources>Create Role

Next Steps#

Now that you understand RBAC, proceed to the following:

GoalRecommended Document
Batch job executionJobs and CronJobs
Network policiesNetworkPolicy
Resource isolationNamespace