On this page
  1. What is RBAC?
  2. What are Roles, ClusterRoles, and bindings?
  3. Why is the default service account a problem?
  4. How do I scope permissions correctly?
  5. Where AI coding assistants get this wrong
  6. Checklist
  7. FAQ
    1. What is the difference between a Role and a ClusterRole?
    2. How do I see what permissions a service account has?
    3. Do I need a service account if my app never calls the Kubernetes API?
  8. Related topics
  9. Sources
concept

What Is Kubernetes RBAC (and What Did Your AI Grant Away)?

RBAC decides which identities can perform which actions on which resources. Generated manifests routinely over-permission service accounts, and the fix is scoping.

Quick answer

  • RBAC maps identities (users and service accounts) to permissions through roles and bindings.
  • A Role grants permissions within a namespace; a ClusterRole grants them cluster-wide.
  • A RoleBinding connects a role to a subject; without a binding, a role does nothing.
  • The default service account is mounted into pods automatically and is often more permissive than the workload needs.
  • The fix for generated manifests is per-workload service accounts with roles that list exact verbs and resources.

What is RBAC?

Role-Based Access Control is Kubernetes’ authorization system. Every request to the API server carries an identity — a human user, or more commonly a pod’s service account — and RBAC decides whether that identity may perform the requested verb on the requested resource. Permissions are expressed as rules: a verb such as get or create, a resource such as secrets or pods, and optionally a resource name. If no rule allows the action, the request is denied.

What are Roles, ClusterRoles, and bindings?

A Role is a set of rules scoped to one namespace. A ClusterRole is the same set of rules but applicable cluster-wide, or reusable across namespaces. Neither grants anything on its own: a RoleBinding attaches a Role (or ClusterRole) to subjects within a namespace, and a ClusterRoleBinding attaches a ClusterRole cluster-wide. That two-step structure — define permissions, then bind them — is why an assistant can generate a role that looks restrictive and a binding that undoes it.

Why is the default service account a problem?

Every namespace has a default service account, and Kubernetes mounts its token into pods unless you explicitly disable it. If that account has any permissions — and generated manifests often bind it to something broad — then every pod in the namespace inherits them, including pods that never intended to call the API. A container running a web app should not be able to list Secrets in its namespace just because it happens to live there. The fix is a dedicated service account per workload with automountServiceAccountToken set to false where the API is not used.

How do I scope permissions correctly?

Start from what the workload does: if it reads a single ConfigMap, its role allows get on that named ConfigMap in its namespace. Avoid wildcards for verbs, resources, and names, which is where most over-permission comes from. Prefer namespaced Roles over ClusterRoles, and when a ClusterRole is genuinely needed, bind it with a RoleBinding scoped to the workload’s namespace rather than cluster-wide. Then test the negative case: confirm the workload fails when it tries to reach something it should not be able to.

Where this bites vibecoders

RBAC is the security control most likely to be widened by an AI assistant acting in good faith. When the app cannot read a Secret, the shortest fix is to bind a broad role — and because the manifests are generated in one pass, nobody notices that the same account can now create pods or read every Secret in the namespace. The permission that made the app work is the permission an attacker inherits with it. Scoping RBAC to the workload’s actual behavior is what stops one compromised container from becoming control of the namespace.

Where AI coding assistants get this wrong

  • Binding workloads to cluster-admin instead of a scoped role.
  • Granting wildcards (verbs: [‘’], resources: [‘’]) as a shortcut.
  • Relying on the default service account and granting the namespace broad rights.
  • Leaving automountServiceAccountToken enabled on pods that never call the API.
  • Creating a ClusterRoleBinding when a RoleBinding would have been sufficient.
  • Never testing that the workload still functions with least privilege.

Checklist

  • Create a dedicated service account per workload.
  • List exact verbs and resources; avoid wildcards.
  • Prefer namespaced Roles and RoleBindings.
  • Set automountServiceAccountToken: false when the API is unused.
  • Never bind a workload to cluster-admin.
  • Audit bindings for subjects that are broader than the workload needs.

FAQ

What is the difference between a Role and a ClusterRole?

A Role grants permissions inside one namespace. A ClusterRole can grant permissions cluster-wide, or be bound within a namespace to reuse the same rule set. If your workload only touches resources in its own namespace, a Role is almost always the right choice.

How do I see what permissions a service account has?

Run kubectl auth can-i --list --as=system:serviceaccount:<namespace>:<name> to list the effective permissions, and inspect the bindings that reference it. Checking positively is the fastest way to find permissions nobody intended to grant.

Do I need a service account if my app never calls the Kubernetes API?

Every pod runs as some service account, so it always has one. What you control is whether its token is mounted. If the app never calls the API, disable automounting so a compromised container has no cluster credential to use.

Sources

Share: