Agen.co enables organizations to securely expose enterprise context to internal agents, copilots, and AI workflows through an identity-aware control layer that governs access, reduces risk, and centralizes oversight.
A low-code CIAM platform for managing customer identity as you scale.
Empower your workforce with secure agents
Kubernetes RBAC controls which authenticated users, groups and workloads may perform specific actions through the Kubernetes API. You define permissions in Role or ClusterRole objects, then grant them to subjects with RoleBinding or ClusterRoleBinding objects.
Role
ClusterRole
RoleBinding
ClusterRoleBinding
The critical detail is scope. A ClusterRole is a cluster-scoped definition, but its permissions are not automatically cluster-wide: a RoleBinding can reuse that ClusterRole inside one namespace. A ClusterRoleBinding is what grants a ClusterRole across the cluster.
Kubernetes evaluates authorization after authentication. If no configured authorizer permits the request, the API server rejects it. Within the RBAC authorizer, permissions are additive: roles grant permissions, and there are no RBAC deny rules that subtract them.
Every RBAC rule connects four questions:
get
list
watch
create
update
patch
delete
pods
deployments.apps
pods/log
Kubernetes defines four RBAC object kinds:
This distinction comes directly from the Kubernetes RBAC API model. It prevents a common mistake: selecting ClusterRole because a permission definition should be reusable, then assuming the resulting access must be cluster-wide.
A Role is namespaced. It can define permissions for namespaced resources in that namespace. Use one when the rule itself is specific to a single namespace.
A ClusterRole is not namespaced. It can define permissions for:
/healthz
Choose a ClusterRole when the permission definition must be reused across namespaces or when the target itself is cluster-scoped. Do not infer the final reach of the grant from kind: ClusterRole alone; inspect the binding.
kind: ClusterRole
A RoleBinding exists in one namespace. It can reference a Role in that same namespace or a ClusterRole. In both cases, the resulting grant applies only within the RoleBinding’s namespace.
A ClusterRoleBinding can reference only a ClusterRole. It grants those permissions cluster-wide.
The reusable ClusterRole + namespace RoleBinding pattern is often the safest operational choice for a standard team or workload role: maintain the permission set once, but opt namespaces into it explicitly.
Assume a reporting workload runs in the analytics namespace. It needs to list and watch Pods and read Pod logs there, but it must not access Secrets or Pods in production.
analytics
production
The following manifest creates a dedicated ServiceAccount, a reusable ClusterRole and a RoleBinding that limits the grant to analytics:
apiVersion: v1 kind: ServiceAccount metadata: name: report-reader namespace: analytics --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: report-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: report-reader namespace: analytics subjects: - kind: ServiceAccount name: report-reader namespace: analytics roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: report-reader
Apply the manifest only after the analytics namespace exists:
kubectl apply -f report-reader-rbac.yaml
The empty string in apiGroups: [""] means the core API group. A Deployment, by contrast, belongs to the apps API group and would be written as resources: ["deployments"] with apiGroups: ["apps"]. Subresources are separate permissions: get on pods does not automatically grant get on pods/log.
apiGroups: [""]
apps
resources: ["deployments"]
apiGroups: ["apps"]
Do not stop after kubectl apply succeeds. Test the exact identity, verb, resource and namespace. These checks use ServiceAccount impersonation, so the operator running them must itself be allowed to impersonate that subject.
kubectl apply
# Expected: yes kubectl auth can-i list pods \ --as=system:serviceaccount:analytics:report-reader \ --namespace=analytics # Expected: yes kubectl auth can-i get pods \ --subresource=log \ --as=system:serviceaccount:analytics:report-reader \ --namespace=analytics # Expected: no kubectl auth can-i list pods \ --as=system:serviceaccount:analytics:report-reader \ --namespace=production # Expected: no kubectl auth can-i get secrets \ --as=system:serviceaccount:analytics:report-reader \ --namespace=analytics
The two negative checks are part of the acceptance test. A positive test proves the workload can function; a negative test proves the boundary was not accidentally widened.
To list everything Kubernetes currently allows for that ServiceAccount inside analytics:
kubectl auth can-i --list \ --as=system:serviceaccount:analytics:report-reader \ --namespace=analytics
kubectl auth can-i is a point-in-time authorization query. It does not replace reviewing every binding that can affect the subject or collecting audit records of actual requests.
kubectl auth can-i
Kubernetes does not store normal human users as API objects. An external authentication method establishes a username and group membership; RBAC binds those strings to permissions. Provisioning or disabling the human identity therefore belongs to that external identity system, not to a Kubernetes User object.
User
A ServiceAccount is a Kubernetes API object intended to provide an identity to a workload. Give each workload a dedicated ServiceAccount when it needs Kubernetes API access, then bind only the required permissions.
Modern Kubernetes workloads normally receive short-lived, automatically rotating ServiceAccount tokens through the TokenRequest API and projected volumes. Avoid static, long-lived ServiceAccount token Secrets. If a Pod does not need to call the Kubernetes API, disable automatic token mounting in the Pod specification:
spec: automountServiceAccountToken: false
The Kubernetes ServiceAccount documentation describes the current token and cross-namespace patterns.
Use a RoleBinding instead of a ClusterRoleBinding when the subject only needs access in selected namespaces. A reusable ClusterRole does not require a cluster-wide grant.
Rules such as resources: ["*"] or verbs: ["*"] cover more than today’s objects and operations. Kubernetes is extensible; a wildcard can also grant access to future resource types.
resources: ["*"]
verbs: ["*"]
get, list and watch on Secrets can reveal Secret contents. Permission to create Pods or workload controllers can also permit mounting Secrets, ConfigMaps, volumes or a more privileged ServiceAccount in that namespace. Review effective capability, not just the visible verb name.
Creating or updating roles and bindings is sensitive. Pay particular attention to the bind, escalate and impersonate verbs, as well as permissions to modify roles, clusterroles, rolebindings and clusterrolebindings. Kubernetes normally prevents a user from creating a role or binding that contains permissions the user does not already hold, unless those special privileges were granted.
bind
escalate
impersonate
roles
clusterroles
rolebindings
clusterrolebindings
Do not grant application permissions to the namespace’s default ServiceAccount. Any Pod without an explicit serviceAccountName would inherit them. Use one ServiceAccount per workload or trust boundary, and disable token mounting when it is unnecessary.
default
serviceAccountName
Keep manifests in version control, require review for privileged changes and compare intended policy with the live cluster. If a binding must point to a different role, create a replacement: Kubernetes makes roleRef immutable. kubectl auth reconcile can help reconcile RBAC manifests, including binding replacement.
roleRef
kubectl auth reconcile
For each privileged identity, specify what must be allowed and what must remain denied. Repeat the tests when a role, binding, chart, operator or CRD changes. A new CRD or aggregated role can alter effective permissions without changing the workload’s original manifest.
The official Kubernetes RBAC good-practices guide documents the privilege-escalation risks behind these controls.
ClusterRole aggregation lets a controller combine rules from labeled ClusterRoles into another ClusterRole. Kubernetes uses this mechanism for default user-facing roles such as admin, edit and view, and platform teams can use it to extend a role for CRDs.
admin
edit
view
Treat the aggregated role’s rules as controller-managed. Do not hand-edit or force-apply that field; the aggregation controller overwrites it. Review the selector and every contributing ClusterRole, because a new matching label can add effective permissions.
rules
Start with the failed request, not with the assumption that the role is wrong. Record the subject, verb, API group, resource or subresource, resource name and namespace.
403 Forbidden
system:authenticated
system:serviceaccounts
kubectl auth can-i --as
Inspect the live objects behind the decision:
kubectl get rolebindings --all-namespaces -o wide kubectl get clusterrolebindings -o wide kubectl get rolebinding report-reader -n analytics -o yaml kubectl get clusterrole report-reader -o yaml
If a resource rule still does not match, confirm its API group and whether the request targets a subresource:
kubectl api-resources
Authorization checks tell you whether a request should be allowed now. Kubernetes audit events provide a chronological record of requests handled by the API server, including the requesting identity, verb, resource and response stage at the configured audit level.
Audit logging is configured separately from RBAC. An audit policy determines which events and bodies are recorded; the API server can write them to a log or webhook backend. Managed Kubernetes services expose control-plane auditing through provider-specific settings, so confirm the provider’s retention and export behavior rather than assuming a self-managed configuration. See the official Kubernetes auditing guide.
Use audit evidence to investigate denied requests, privileged changes and permissions that are granted but apparently unused. Do not log sensitive request or response bodies indiscriminately; choose audit levels and retention according to the data and investigation need.
Kubernetes RBAC protects the Kubernetes API: who may read Secrets, modify Deployments, view logs or change cluster configuration. It does not decide whether an end user may view Tenant A’s invoice, edit a project or administer another user inside your SaaS application.
If a B2B SaaS product runs on Kubernetes, it normally needs both layers:
Keep the policy models and enforcement points separate. A Kubernetes namespace is not automatically a customer-tenant authorization boundary, and an application role should not grant cluster privileges. The RBAC guide covers the general model; the authorization architecture guide explains tenant context, policy decisions and application enforcement.
Frontegg’s roles documentation covers application roles and permissions for customer-facing products. Those capabilities complement Kubernetes RBAC; they do not configure or replace the Kubernetes API authorizer.