Kubernetes RBAC Role Based Access Control Explained

Kubernetes runs many workloads, and not everyone who touches the cluster should be able to do everything. A developer should deploy apps. A monitoring tool should only read metrics. A junior engineer should not delete production databases. RBAC (Role-Based Access Control) is the system that enforces these boundaries inside Kubernetes.

RBAC answers one question: Who can do what, on which resources?

The Real-World Problem RBAC Solves

Picture a hospital. Doctors read patient records. Nurses update medication logs. Receptionists book appointments. Nobody gets access to everything — only what their job requires. Kubernetes RBAC works the same way for your cluster.

Without RBAC, every user and every application inside the cluster would have the same level of access. One misconfigured script could wipe all deployments. RBAC prevents that.

The Four Building Blocks of RBAC

1. Subject — Who Is Asking?

A subject is the identity that wants to perform an action. Kubernetes recognises three types of subjects:

  • User — A human administrator or developer who authenticates with the cluster.
  • Group — A collection of users treated as one unit (e.g., the developers group).
  • ServiceAccount — A non-human identity assigned to a Pod so the app itself can call the Kubernetes API.

2. Resource — What Is Being Touched?

Resources are the Kubernetes objects the subject wants to interact with — Pods, Deployments, ConfigMaps, Secrets, Services, Nodes, and so on.

3. Verb — What Action Is Requested?

Verbs describe the operation. The most common ones are:

  • get — Read a single resource.
  • list — Read all resources of a type.
  • watch — Stream changes to a resource.
  • create — Make a new resource.
  • update — Modify an existing resource.
  • patch — Partially modify a resource.
  • delete — Remove a resource.

4. Role / ClusterRole — The Permission Set

A Role bundles together a list of verbs on a list of resources. Think of it as a job description: "This role can get and list Pods."

RBAC Diagram: The Access Flow

┌─────────────────────────────────────────────────────┐
│                  RBAC Access Check                  │
│                                                     │
│  Subject          Role               Resource       │
│  ───────          ────               ────────       │
│  [User: Alice] ──► [Role: Pod-Reader] ──► [Pods]    │
│                    verbs: get, list                 │
│                                                     │
│  [ServiceAccount: │                                 │
│   app-backend] ──►[Role: Secret-Reader]─► [Secrets] │
│                    verbs: get                       │
│                                                     │
│  API Server checks: Does the binding exist?         │
│   YES → Allow   │   NO → 403 Forbidden              │
└─────────────────────────────────────────────────────┘

Role vs ClusterRole: The Namespace Boundary

This is one of the most important distinctions in RBAC.

Role (Namespace-Scoped)

A Role only applies inside one specific namespace. If you create a Role in the production namespace, it has zero effect in the staging namespace.

Use a Role when you want to give someone access to resources inside one namespace and nowhere else.

ClusterRole (Cluster-Wide)

A ClusterRole applies across the entire cluster, across all namespaces. It also covers resources that do not belong to any namespace at all, such as Nodes, PersistentVolumes, and Namespaces themselves.

Use a ClusterRole for platform admins, monitoring agents, and any tool that needs to read resources in all namespaces.

Namespace-Scoped vs Cluster-Scoped

  ┌──────────────────────────────────────────────┐
  │               CLUSTER                        │
  │                                              │
  │  ┌─────────────┐    ┌─────────────┐          │
  │  │  Namespace  │    │  Namespace  │          │
  │  │ production  │    │  staging    │          │
  │  │             │    │             │          │
  │  │  [Role A]   │    │  [Role B]   │          │
  │  │  ↕ only     │    │  ↕ only     │          │
  │  │  here       │    │  here       │          │
  │  └─────────────┘    └─────────────┘          │
  │                                              │
  │  [ClusterRole C] ──► affects ALL above       │
  │  + cluster-level resources (Nodes etc.)      │
  └──────────────────────────────────────────────┘

RoleBinding and ClusterRoleBinding: The Glue

Creating a Role does nothing on its own. A RoleBinding connects a subject to a Role. Without the binding, the Role is just a definition sitting unused.

  • RoleBinding — Connects a subject to a Role or ClusterRole inside one namespace.
  • ClusterRoleBinding — Connects a subject to a ClusterRole across the entire cluster.

A ClusterRole can also be referenced by a RoleBinding. This is a powerful pattern: define the permission set once as a ClusterRole, then reuse it in many namespaces via individual RoleBindings.

Writing Your First Role: A Practical Example

Scenario: A developer named Alice should be able to read Pods in the production namespace, but nothing else.

Step 1 — Create the Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: pod-reader
rules:
- apiGroups: [""]        # "" means the core API group
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

The apiGroups: [""] field refers to the core Kubernetes API group, which contains Pods, Services, ConfigMaps, and Secrets. For other resources like Deployments, you use apps as the apiGroup.

Step 2 — Create the RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-alice
  namespace: production
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Now Alice can run kubectl get pods -n production successfully. Any other action — like deleting a pod or reading Secrets — will return a 403 error.

ServiceAccounts: RBAC for Applications

When a Pod needs to call the Kubernetes API (for example, a monitoring agent that lists all running pods), it uses a ServiceAccount. RBAC applies to ServiceAccounts exactly the same way it applies to human users.

Every namespace gets a default ServiceAccount automatically. By default, this ServiceAccount has no RBAC permissions. You bind a Role to it when the application actually needs API access.

Example: Giving a Monitoring App Read Access to All Pods

# ClusterRole: read pods in all namespaces
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-monitor
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
# Bind it to the ServiceAccount in the monitoring namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-monitor-binding
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: monitoring
roleRef:
  kind: ClusterRole
  name: pod-monitor
  apiGroup: rbac.authorization.k8s.io

Aggregated ClusterRoles

Kubernetes ships with a set of default ClusterRoles. Three of the most important are:

  • cluster-admin — Full access to everything. Reserve this for break-glass scenarios only.
  • view — Read-only access to most resources in a namespace (no Secrets).
  • edit — Read and write access to most resources; cannot modify RBAC rules.
  • admin — Full namespace control including managing RoleBindings, but cannot touch cluster-level resources.

You can extend these built-in roles using aggregation rules. You create a ClusterRole with a special label, and Kubernetes automatically merges its permissions into the target built-in role. This lets operators extend the view or edit role for custom resources without touching the original definition.

Common RBAC Patterns in Production

Pattern 1: Namespace Isolation per Team

Each team owns one namespace. Each team's group gets the edit ClusterRole bound via a RoleBinding in their namespace only. No team can read or modify another team's namespace.

Pattern 2: Read-Only Access for CI Pipelines

A CI/CD pipeline needs to verify deployments but not change them. Bind the view ClusterRole to the pipeline's ServiceAccount.

Pattern 3: Least Privilege for Operators

Kubernetes operators (custom controllers) often need broad access. Scope their ClusterRole to only the resources they actually manage. Do not grant cluster-admin to operators.

Auditing and Debugging RBAC

Check What a User Can Do

# Can Alice delete pods in production?
kubectl auth can-i delete pods --namespace=production --as=alice

# Output: no

List All RoleBindings in a Namespace

kubectl get rolebindings -n production -o wide

Describe a Role to See Its Rules

kubectl describe role pod-reader -n production

Find Who Has Access to a Resource

# Install kubectl-who-can plugin
kubectl who-can delete pods -n production

RBAC Pitfalls to Avoid

  • Wildcard verbs and resources — Avoid verbs: ["*"] or resources: ["*"] in production roles. List only what is needed.
  • Granting cluster-admin broadly — A compromised account with cluster-admin can destroy the entire cluster. Use it only for emergency access.
  • Ignoring ServiceAccount permissions — Pods run as the default ServiceAccount unless specified otherwise. Keep the default ServiceAccount permission-free and create dedicated ServiceAccounts for apps that need API access.
  • Not reviewing bindings regularly — Old bindings for departed employees or decommissioned tools accumulate. Audit bindings quarterly.
  • Binding ClusterRole via ClusterRoleBinding when RoleBinding is enough — If access is only needed in one namespace, use a RoleBinding. A ClusterRoleBinding gives cluster-wide access unnecessarily.

RBAC and Secrets: A Special Case

The built-in view ClusterRole deliberately excludes Secrets. Secrets contain passwords, tokens, and certificates. Even if a user can read all other resources in a namespace, they cannot read Secrets unless you explicitly grant them get on the secrets resource.

Treat Secret access as a separately gated permission. Most developers do not need to read Secrets directly — they just need the app to use them via environment variables or volume mounts.

Key Points

  • RBAC controls who (subject) can do what (verb) on which resources in Kubernetes.
  • A Role scopes permissions to one namespace; a ClusterRole applies cluster-wide.
  • Permissions take effect only when a RoleBinding or ClusterRoleBinding connects a subject to a role.
  • ServiceAccounts give Pods an identity for API calls — bind roles to them just like human users.
  • Always follow the principle of least privilege: grant only the verbs and resources an identity actually needs.
  • Use kubectl auth can-i to debug access issues quickly.
  • Audit bindings regularly and remove anything no longer needed.

Leave a Comment