Kubernetes RBAC

Every request to the Kubernetes API, whether from kubectl, a CI pipeline, or a controller running in a Pod, goes through authentication (who are you?) and then authorization (are you allowed to do this?). Role-Based Access Control (RBAC) is the standard authorizer. It grants permissions by attaching Roles (sets of allowed verbs on resources) to subjects (users, groups, ServiceAccounts) through bindings.

RBAC is purely additive: there are no deny rules. A subject can do exactly the union of everything its bindings grant. That makes it easy to reason about and easy to over-grant, which is why least privilege takes deliberate effort.

TL;DR

Quick Example

Let a CI pipeline deploy into the staging namespace, and nothing else:

Core Concepts

Rules: API Groups, Resources, Verbs

Each rule lists apiGroups ("" is the core group for Pods, Services, Secrets, and ConfigMaps; apps for Deployments; batch for Jobs), resources (including subresources like pods/log and pods/exec), optional resourceNames to pin specific objects, and verbs. The read verbs are get, list, and watch; the write verbs are create, update, patch, delete, and deletecollection.

The Four Objects

A useful pattern is to define a ClusterRole once (for example, app-developer) and bind it with a RoleBinding per namespace. The permissions stay consistent while the scope stays limited.

Subjects

Built-in ClusterRoles

Kubernetes ships cluster-admin (everything), admin (full control within a namespace, including RBAC), edit (read/write most objects, no RBAC), and view (read-only, excludes Secrets). They're a reasonable starting point for humans. Workloads almost always need something narrower.

Workload Identity

Pods often need to call cloud APIs as well as the Kubernetes API. Don't mount long-lived cloud keys as Secrets. Map the Pod's ServiceAccount to a cloud identity instead:

The Pod gets short-lived cloud credentials automatically, and access is revoked by editing a role rather than rotating a key. See secrets management.

Best Practices

Least Privilege, Namespaced by Default

Start from zero and add the verbs a subject needs. Prefer RoleBindings over ClusterRoleBindings. Avoid wildcards (resources: ["*"], verbs: ["*"]), which silently grant access to resources added later, CRDs included.

Treat Some Permissions as Admin-Equivalent

Several permissions let a subject escalate to more power than they appear to grant:

Disable Token Automounting Where Unused

Most application Pods never talk to the Kubernetes API. Set automountServiceAccountToken: false on their ServiceAccount or Pod spec so a compromised container has no API credentials to steal.

Audit Regularly

Enable API server audit logging, and periodically review who holds powerful bindings. kubectl auth can-i --list --as <subject> shows a subject's effective permissions; tools like rbac-lookup, kubectl-who-can, and cloud security posture scanners help at scale.

Manage RBAC as Code

Keep Roles and bindings in Git alongside the rest of your manifests and apply them through GitOps. Out-of-band kubectl create rolebinding commands become invisible permissions nobody remembers granting.

Common Mistakes

Granting cluster-admin to a CI Pipeline

Scope CI to the namespaces it deploys to, with a Role that covers only the resource kinds in your manifests.

Using the default ServiceAccount for Everything

Every namespace has a default ServiceAccount, and Pods use it unless told otherwise. Binding permissions to default grants them to every Pod in the namespace. Create one ServiceAccount per workload that needs API access.

Forgetting That view Isn't the Same as "Safe"

view excludes Secrets, but a custom read-only role with resources: ["*"] includes them. Read access to Secrets is often more dangerous than write access to Deployments.

FAQ

What's the difference between a Role and a ClusterRole?

A Role is namespaced and can only grant access to resources in its own namespace. A ClusterRole is cluster-scoped: it can grant access to cluster-level resources (nodes, namespaces, PersistentVolumes) or be reused across many namespaces through RoleBindings.

Can RBAC deny a permission?

No. RBAC only allows. If you need deny-style guardrails, such as "nobody may create privileged Pods", use admission control: Pod Security Admission, ValidatingAdmissionPolicy, or policy engines such as Kyverno and OPA Gatekeeper.

How do I give developers access to their team's namespace?

Bind the built-in edit ClusterRole, or a custom one, to the team's IdP group with a RoleBinding in each of their namespaces. Access then follows group membership in your identity provider, with no per-user bindings to maintain.

How do I find out who can delete a resource?

Use kubectl auth can-i delete pods -n prod --as jane@example.com for one subject, or a tool such as kubectl-who-can delete pods -n prod to list every subject with that permission.

Related Topics

References