Kubernetes RBAC basics: users, roles and service accounts
Quick answer
Kubernetes RBAC (role-based access control) grants permissions by binding a Role or ClusterRole, which lists allowed actions on resources, to a user, group, or service account through a RoleBinding or ClusterRoleBinding. Roles are namespace-scoped, ClusterRoles apply cluster-wide. Start from least privilege: grant only the verbs and resources a person or workload actually needs, in the narrowest scope that works.
This is standard, open-source Kubernetes behaviour, not specific to any provider or infrastructure choice. It applies equally whether your cluster runs on Bare Metal Compute, Flexible VPS, or Private Cloud, or anywhere else.
What RBAC controls
RBAC decides who, or what, can do what, to which resources, in your cluster. "Who" can be a human user authenticating through a kubeconfig, or a workload authenticating as a service account. "What" is a set of verbs: get, list, watch, create, update, patch, delete, and a few others. "Which resources" means Kubernetes objects: pods, deployments, secrets, config maps, and so on, optionally scoped to a specific namespace.
Without RBAC configured deliberately, it's easy to end up with everyone, and every workload, holding far more access than they need. RBAC exists to make access explicit and auditable rather than implicit.
Roles vs. ClusterRoles
- Role. A set of permissions scoped to a single namespace. A Role defined in the
billingnamespace only grants access to resources inbilling, nowhere else. - ClusterRole. The same idea, but cluster-wide. A ClusterRole can grant access across all namespaces, or to cluster-scoped resources that don't belong to any namespace at all, such as nodes or persistent volumes.
A useful rule of thumb: default to a Role unless you have a specific reason to need cluster-wide scope. Namespace-scoped access is easier to reason about and limits the blast radius if a credential leaks.
RoleBindings vs. ClusterRoleBindings
Defining a Role or ClusterRole doesn't grant anyone anything on its own, it just describes a set of permissions. A binding is what actually attaches that role to a user, group, or service account.
- RoleBinding. Grants a Role (or, notably, a ClusterRole) to a subject within one namespace. You can bind a ClusterRole through a RoleBinding to reuse a common permission set namespace by namespace, without granting cluster-wide access.
- ClusterRoleBinding. Grants a ClusterRole to a subject across the entire cluster.
Example: a read-only, namespace-scoped role
The manifest below defines a Role that can only read pods and their logs in the billing namespace, then binds it to a service account.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: billing
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: billing
subjects:
- kind: ServiceAccount
name: billing-readonly
namespace: billing
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.ioThis grants exactly three verbs, on two resource types, in one namespace, nothing more. It's a reasonable pattern for a monitoring tool, a support engineer, or a CI job that only needs to inspect pod state and logs.
kubeconfig and service accounts
Human users typically authenticate through a kubeconfig file, which points kubectl at a cluster and carries credentials, a certificate, a token, or an external identity-provider login, depending on how the cluster is set up. Each user or team usually gets their own kubeconfig context, scoped through RBAC to only the namespaces and permissions they need.
Workloads running inside the cluster use service accounts instead. Every namespace has a default service account, but running everything under the default is a common way to end up with broader access than intended. Create a dedicated service account per workload, bind it to a purpose-built Role, and mount only that identity into the pod that needs it.
Principle of least privilege
The pattern that keeps RBAC manageable as a cluster grows: grant the smallest set of verbs, on the smallest set of resources, in the smallest scope, that lets a user or workload do its job. Prefer Roles over ClusterRoles, prefer read-only verbs (get, list, watch) over write access unless write access is genuinely needed, and give each workload its own service account rather than sharing one broadly-scoped identity across many pods. Review bindings periodically, since access that made sense when it was granted doesn't always stay that way.