20.1 RBAC Concepts: Subjects, Resources, Verbs
Alright, let’s demystify the three core building blocks of RBAC. Forget the jargon for a second. At its heart, every single access control question boils down to answering this: “Who can do what to which thing?” RBAC is just a formal, manageable way to answer that. The “who” is the Subject, the “what” is the Verb, and the “which thing” is the Resource. Get these three concepts locked down, and the rest is just elegant (or sometimes infuriatingly inelegant) implementation.
What’s a Subject? (The “Who”)
The Subject is the entity trying to perform an action. It’s almost always a user, but it can also be a service account (an identity for a machine or application), or sometimes even a group. The key insight here is that you almost never assign permissions directly to an individual user. That would be a management nightmare. Imagine having to update a thousand users individually when a new file share gets added. You’d quit your job.
Instead, you assign users to Roles. The role is the proxy for the subject. The system doesn’t really care that you, Jane Doe, are trying to delete a pod; it cares that you have the “Cluster Admin” role, and that role is allowed to delete pods. This level of indirection is the entire superpower of RBAC. When Jane moves to a new team, you don’t scrub through a million policies; you just remove her from the “Cluster Admin” role and add her to the “App Developer” role. Done.
Here’s a common pitfall: don’t confuse a user’s identity with their permissions. Your company LDAP might say you’re in the “Finance” group, but that’s an identity provider group. In your Kubernetes cluster or your AWS account, that group needs to be mapped to a role that you’ve defined within that system’s RBAC framework. The two are related but distinct concepts.
What’s a Resource? (The “Which Thing”)
The Resource is the object being acted upon—the “noun” in our sentence. This is anything you might want to control access to: a file, a database row, a Kubernetes Pod, an S3 bucket, a virtual machine, a billing account.
In modern API-driven systems (like Kubernetes), resources are usually defined by their API path. This is where it gets fun, because designers can be… creative. Most resources are obvious, like pods or secrets. But some make you wonder if the designer was paid by the hour. Why is it networkpolicies (plural) but podsecuritypolicy (singular)? Who knows. You just have to look it up in the API documentation. It’s absurd, but you gotta know your nouns.
Crucially, you can often control access at different levels of granularity. You might have a role that can read any secret in a namespace (resources: ["secrets"]), and another role that can only read a secret named db-credentials (resourceNames: ["db-credentials"]). The latter is more secure, but also a total pain to manage. This is the constant tension in RBAC: security precision vs. administrative overhead.
What’s a Verb? (The “What”)
The Verb is the action being performed. These are the standard CRUD operations: get, list, create, update, delete. Sometimes they have synonyms—patch is a type of update, watch is a persistent list, deletecollection is a terrifyingly powerful verb that lets you nuke an entire resource type in a namespace with one call (use it with extreme prejudice).
This is where technical accuracy is key. You must understand what the verb actually does in the context of the API. In Kubernetes, being able to get a secret allows you to see its decoded data. That’s a big deal! Meanwhile, being able to create a pod implicitly grants the ability to run any image as any user on your node, which is an even bigger deal. The verb is small, but its implications can be massive.
A classic “questionable choice” is overloading verbs. For example, in many systems, the update verb is also used for the patch operation. If you want to allow one but not the other… tough luck. You have to grant update and hope your users don’t use the more dangerous patch method. It’s not ideal.
Bringing It All Together: The Policy Rule
A permission, or a policy rule, is a combination of these three elements. It’s a statement that grants a set of verbs on a set of resources to a subject (via their role).
Let’s look at a Kubernetes example. This Role definition allows a subject to read and list Pods in a specific namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: my-app-namespace
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "list", "watch"]
But what if you need to let someone troubleshoot Pods? That might require more than just reading them. Here’s a more powerful, and more dangerous, role. I call this the “I’m-from-IT” role.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: my-app-namespace
name: pod-troubleshooter
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"] # Notice we need two resources here
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/exec"] # Exec is a subresource, a different "noun"
verbs: ["create"] # You "create" an exec session into a pod. Weird, but true.
See what we did there? To let someone run kubectl exec, you don’t grant exec on the pods resource. You grant create on the pods/exec subresource. It’s a classic “gotcha” that highlights why you can’t just guess—you have to know the API structure. This is the “in the trenches” knowledge that separates you from the crowd. Always, always check the API docs for the exact resource and verb combinations. Your security depends on it.