How Kubernetes Decides Who Can Do What
Summary
- Every request to the Kubernetes API server passes through three gates in order: authentication (who are you), authorization (are you allowed), and admission (should this specific object be accepted).
- Insight: RBAC never grants identity. It only maps an already-authenticated identity to a set of allowed verbs on resources.
- Key Concepts: the API server is the single policy enforcement point, subjects are users, groups, and ServiceAccounts, RBAC binds subjects to Roles, and verbs name actions like
get,list,create, anddelete. - When to Use: you need this model any time you design cluster access, debug a
Forbiddenerror, or scope a pipeline or workload down to least privilege. - Limitations/Trade-offs: RBAC is additive and has no deny rule, so you cannot subtract a permission once any binding grants it.
- Related Topics: RBAC Roles and bindings, ServiceAccounts, and OIDC-based human login.
Foundations
The Kubernetes API server is the front door to the cluster.
Nothing changes state without going through it - not kubectl, not a controller, not a pod calling the API.
Because everything funnels through one process, access control lives there too.
A request arrives as an HTTP call carrying credentials.
The API server must answer two separate questions before it touches etcd.
First, who is making this request? That is authentication (authN).
Second, is this identity permitted to perform this action on this resource? That is authorization (authZ).
Keeping these two questions distinct is the core mental model.
Kubernetes has no user database and does not store passwords for humans.
Instead it trusts external mechanisms to prove identity and then reasons only about the resulting identity string and its groups.
Mechanics & Interactions
Authentication runs a chain of configured authenticators until one accepts the request.
Common authenticators include X.509 client certificates, bearer tokens, and OIDC tokens from a corporate identity provider.
ServiceAccounts authenticate with signed JSON Web Tokens issued by the cluster itself.
The output of a successful authentication is a username and a list of groups - nothing more.
If no authenticator accepts the credentials, the request is treated as the system:anonymous user.
Authorization then evaluates that identity against the enabled authorizers.
The API server can run several authorization modules, typically Node, RBAC, and Webhook, in a configured order.
Each authorizer returns allow, deny, or no-opinion.
The first module to return an explicit allow wins, and the request proceeds.
If every module abstains, the request is denied by default.
RBAC is the module most teams work with directly.
RBAC evaluates a request as a tuple: the verb, the API group and resource, and optionally the resource name and namespace.
It searches for a Role or ClusterRole, referenced by a binding to your identity, whose rules match that tuple.
A namespaced Role plus a RoleBinding grants access inside one namespace.
A ClusterRole plus a ClusterRoleBinding grants access cluster-wide, across all namespaces and to cluster-scoped objects like nodes.
A ClusterRole can also be referenced by a namespaced RoleBinding, which reuses one permission set in a chosen namespace.
RBAC is purely additive.
There are no deny rules, so the effective permission of a subject is the union of every rule from every binding that applies to it.
After authorization succeeds, admission controllers run.
Admission is where mutating and validating webhooks, Pod Security Standards, and quota checks decide whether this particular object is acceptable.
Admission can reject a request that RBAC already allowed, which is why a create can still fail with a policy message.
Advanced Considerations & Applications
Least privilege in Kubernetes means shaping the verb and resource surface as tightly as the workload allows.
Prefer narrow Roles scoped to one namespace over broad ClusterRoles.
Reserve cluster-admin for a small, audited set of break-glass identities.
Wildcards in rules, such as verbs: ["*"] or resources: ["*"], quietly grant future resources too, so avoid them in application-facing Roles.
Some verbs are more dangerous than they look.
escalate and bind let a subject grant permissions it does not itself hold, and impersonate lets it act as another user or group.
Access to the pods/exec and pods/attach subresources is effectively shell access into running workloads.
Reading secrets is equivalent to reading the credentials inside them.
Workloads authenticate as their pod's ServiceAccount, so pod identity is a first-class authZ subject, not an afterthought.
The aggregate-to-* label mechanism lets you compose ClusterRoles from smaller labeled pieces, which is how the built-in view, edit, and admin roles grow.
Common Misconceptions
RBAC authenticates users. It does not. Authentication happens first and separately, and RBAC only maps the resulting identity to permissions.
A deny rule can block a permission. RBAC has no deny. If any binding grants an action, the subject can do it. Removal means editing or deleting bindings, not adding a deny.
Namespaces are a security boundary by themselves. A namespace scopes RBAC and objects, but a ClusterRoleBinding or a wildcard rule can cross it instantly. The boundary is only as strong as the bindings.
cluster-admin is required to manage a namespace. The built-in admin ClusterRole, bound with a namespaced RoleBinding, gives full control of one namespace without any cluster-wide power.
ServiceAccount tokens are static forever. Modern clusters issue short-lived, audience-scoped projected tokens that expire and are rotated, not permanent secrets.
FAQs
Why did my request fail with "Forbidden" but my teammate's worked? Authorization is per-identity. Your username and groups did not match any binding granting that verb and resource, while theirs did.
In what order do authN, authZ, and admission run? Authentication first, then authorization, then admission controllers, and only then is the object persisted.
Can I see whether an action is allowed without performing it?
Yes. Use kubectl auth can-i <verb> <resource> to ask the API server directly, optionally with --as to test another subject.
Is RBAC the only authorizer? No. Node authorization gates kubelet access and Webhook authorization can defer to an external service, but RBAC is the general-purpose module for humans and workloads.
Do controllers and operators use RBAC too? Yes. They run as ServiceAccounts and are subject to the exact same authorization checks as any other client.
Related
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).