Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

Kubernetes Consulting

Designing Kubernetes RBAC That Actually Enforces Least Privilege

Kubernetes RBAC controls who can do what to which resources. We design roles around job functions, map them to your identity provider's groups, tighten service accounts, remove standing cluster-admin access, and add checks so permissions do not drift back to over-broad as teams and deadlines push.

Key takeaways

  • Humans should authenticate through your identity provider and receive access through groups, not individual bindings.
  • Namespace-scoped Roles are the default, and ClusterRoles bound cluster-wide are the exception.
  • Service accounts need the same scrutiny as people, since most breaches involve a workload credential.
  • Wildcards, secrets read access and permission to create pods or bind roles are escalation paths.
  • Least privilege decays without automation, so we add review and policy checks.

The access problem nobody notices until an audit

Kubernetes ships with a capable authorisation system and, in most clusters, an access model nobody designed. Early on, an engineer needed to get unblocked, so they were given cluster-admin. A CI job needed to deploy, so it got a broad ClusterRole. Months later, a contractor leaves, and nobody can say which of forty bindings they held.

Kubernetes RBAC with least privilege is the discipline of replacing that history with a model you can explain. It is a recurring request in our Kubernetes consulting engagements, and a standard section of every production readiness audit.

How RBAC works, briefly

RBAC has four objects. A Role grants permissions inside one namespace, a ClusterRole grants them cluster-wide or can be reused in a namespace, and a RoleBinding or ClusterRoleBinding attaches a role to a user, group or service account. The key rule: a ClusterRole bound through a RoleBinding is limited to that namespace, which lets you define a role once and reuse it safely per namespace.

RBAC is additive only. There are no deny rules, so the way to restrict access is to grant less.

What good looks like

  • Humans come from your identity provider, and bindings reference groups, never individuals.
  • A handful of well named roles per job function, not a role per person.
  • Namespace-scoped access by default. Cluster-wide rights belong to a small platform group.
  • No standing cluster-admin for daily work. Elevated access is time-limited and logged.
  • Automation uses dedicated service accounts with only the verbs it needs.
  • Every binding has an owner, and a review process removes stale ones.

The role model we start from

We tailor this with your team leads, but the shape is usually:

RoleScopeCan do
viewerNamespaceRead workloads, events, logs; no secrets
developerTeam namespacesManage deployments, services, config in non-production; read in production
operatorClusterRestart workloads, drain nodes, read most resources
platform-adminClusterManage CRDs, RBAC, cluster add-ons; use sparingly

A namespace scoped example, reusing a built-in role:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: payments-developers-edit
  namespace: payments
subjects:
  - kind: Group
    name: oidc:payments-developers
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: edit
  apiGroup: rbac.authorization.k8s.io

You can test the effect before and after any change:

kubectl auth can-i --list --namespace payments --as-group oidc:payments-developers --as dummy
kubectl auth can-i get secrets -n payments --as dummy --as-group oidc:payments-developers

Note that the built-in edit role can read secrets in its namespace, which may be more than you want for some teams. When it is, we write a custom Role instead.

Connecting to your cloud identity

On EKS, IAM principals map to Kubernetes users and groups through access entries (or the older aws-auth ConfigMap). On AKS, Entra ID groups feed straight into bindings. On GKE, Google identities and groups work with RBAC. In each case the principle is the same: the identity provider owns who someone is and which groups they belong to, and Kubernetes owns what those groups may do. Joiners and leavers then need only a directory change.

Service accounts and workload identity

Most real-world incidents involve a workload credential, not a human one. We tighten three things:

  1. Default service account. Pods that do not call the API should not mount a token. Set automountServiceAccountToken: false on service accounts and pod specs where it is not needed.
  2. Per-workload service accounts with narrowly scoped Roles instead of sharing one account across an app.
  3. Cloud permissions via workload identity (IRSA or EKS Pod Identity, Entra Workload ID, GKE Workload Identity), not through the node’s role, which every pod on the node would inherit.

Escalation paths to remove

Some permissions are more powerful than they look:

  • get, list or watch on secrets.
  • create on pods, or pods/exec, which can reach other service accounts’ tokens in the namespace.
  • impersonate, escalate and bind on roles.
  • Wildcards (*) in verbs, resources or apiGroups.
  • nodes/proxy and access to the kubelet API.

We scan for these, then decide case by case. Blocking all of them breaks real work, so the answer is usually to restrict them to a few well controlled identities.

Worked example: removing a standing cluster-admin grant

Say five engineers hold cluster-admin through a single binding to a group. We do not delete it on day one. First we create the replacement roles and bind them to the same group, then ask the engineers to work with the narrower access for a week and report anything blocked. Each blocked action is either a legitimate need, which we add to a role, or a habit, which we retire.

Only then do we remove the old binding, keeping a break-glass role that requires an approval step and expires on its own. Because the sequence is additive first and subtractive last, nobody loses access mid-incident.

Trade-offs and when RBAC alone is not enough

RBAC controls API access. It does not stop a compromised pod from talking to other pods (that is network policy), or from running as root (that is pod security standards). For policy that RBAC cannot express, such as forbidding privileged containers, we add admission control with Kyverno or OPA Gatekeeper. For very small teams, an elaborate role model can cost more than it protects. Four roles and a good identity group structure is plenty.

Common failure modes

  • Fine-grained roles that nobody understands, so everyone asks for cluster-admin.
  • A CI service account with cluster-admin because narrowing it took effort.
  • Dev and production sharing identities, so a developer’s laptop can change production.
  • Role changes made by hand, never recorded. We store RBAC in Git and apply it through GitOps so changes are reviewable.
  • Reviews done once and never repeated.

Delivery and how to tell it works

We deliver the role model, bindings as code, the identity mapping, a list of removed grants, and a review checklist. Signs of success: cluster-admin is bound to a short, named list; a new joiner gets access by joining a group; and an access review takes an hour, not a week. For wider cloud context see our Terraform work on IAM. To discuss your own cluster, get in touch.

References

How we deliver it

  1. 01

    Inventory current access

    We list every binding, who or what it grants, and which ones are actually used according to audit logs.

  2. 02

    Define role model

    A small set of roles per job function (viewer, developer, operator, platform admin) is agreed with your team leads.

  3. 03

    Wire up identity

    Cloud IAM, Entra ID or Google groups are mapped to Kubernetes groups, with no static user credentials.

  4. 04

    Fix workload identity

    Service accounts get minimal rights and cloud permissions are issued through workload identity, not node roles.

  5. 05

    Roll out safely

    New bindings are applied alongside old ones, verified with access checks, then old broad grants are removed.

  6. 06

    Add guardrails and review

    Policy checks block risky bindings in CI, and a recurring access review keeps the model honest.

Tools and technologies

kubectl auth can-irbac-toolKubescapeKubiScanKyvernoOPA GatekeeperAWS IAMMicrosoft Entra IDGoogle Cloud IAMTerraformArgo CD

Frequently asked questions

What is least privilege in Kubernetes RBAC?
It means each user and workload receives only the verbs, resources and namespaces needed for its job, nothing more. In practice that means namespace-scoped Roles, no wildcards, no standing cluster-admin, and separate identities for automation. Permissions are reviewed regularly, because needs and teams change.
How do we connect RBAC to our SSO or IAM?
Authentication comes from the cloud provider or an OIDC identity provider, and RBAC bindings reference groups from it. On EKS you map IAM principals through access entries or the aws-auth ConfigMap, on AKS you integrate Entra ID, and on GKE you use Google identities. Individual user bindings should be avoided.
Which RBAC permissions are the most dangerous?
Reading secrets, creating or exec-ing into pods, impersonation, and the ability to create or bind roles all allow escalation. A user who can create pods in a namespace can often mount any secret or service account there. Wildcard verbs and resources hide these risks.
Should developers have access to production?
Usually read access to logs and workload status, and no routine write access. Changes should flow through the pipeline or GitOps. For incidents, a time-limited elevated role with an audit trail works better than a permanent admin binding. The exact policy depends on team size and compliance needs.
How do we find over-privileged accounts?
List bindings to cluster-admin and wildcard roles, then compare granted permissions with actual usage from audit logs. Tools like kubectl auth can-i --list, rbac-tool and Kubescape help. The output needs human judgement, since an unused permission is not always unneeded.

Talk to an engineer about kubernetes rbac least privilege

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.