Kubernetes Role-Based Access Control (RBAC) is the mechanism for controlling which users and service accounts can perform which actions on which resources within a Kubernetes cluster. Without RBAC configuration, all authenticated users (and service accounts in pods) have full admin access — a significant security risk in multi-team environments. RBAC uses four resource types: Role (defines permissions within a namespace), ClusterRole (defines permissions cluster-wide or used as a template), RoleBinding (grants a Role to a user/group/service account in a namespace), and ClusterRoleBinding (grants a ClusterRole cluster-wide). This guide covers configuring RBAC on RHEL 9 Kubernetes to implement least-privilege access for developers, CI/CD service accounts, and read-only operators.
Prerequisites
- Kubernetes cluster running on RHEL 9 with RBAC enabled (enabled by default since Kubernetes 1.8)
Step 1 — View Current RBAC Configuration
# Check if RBAC is enabled
kubectl api-versions | grep rbac
# View existing ClusterRoles
kubectl get clusterroles | grep -v system:
# View existing RoleBindings in a namespace
kubectl get rolebindings -n myapp
Step 2 — Developer Role (Namespace-Scoped)
# /tmp/developer-rbac.yaml
# Role: allows developers to manage deployments and view pods
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: myapp
name: developer
rules:
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods", "pods/log", "services", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"] # Allows kubectl exec into pods
---
# Bind the role to a user
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: myapp
subjects:
- kind: User
name: jane.developer
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
kubectl apply -f /tmp/developer-rbac.yaml
Step 3 — CI/CD Service Account
# Create a service account for CI/CD pipeline
kubectl create serviceaccount cicd-deployer -n myapp
# Grant permission to update deployment images only
kubectl create role deployment-updater
--verb=get,patch,update
--resource=deployments
-n myapp
kubectl create rolebinding cicd-deployer-binding
--role=deployment-updater
--serviceaccount=myapp:cicd-deployer
-n myapp
# Get the service account token for CI/CD pipelines
kubectl create token cicd-deployer -n myapp --duration=8760h
Step 4 — Read-Only Cluster Viewer
# Use the built-in ClusterRole "view" for read-only access
kubectl create clusterrolebinding ops-viewer
--clusterrole=view
--user=ops-team-user
# Verify what a user can do
kubectl auth can-i list pods --namespace myapp --as jane.developer
kubectl auth can-i delete deployments --namespace myapp --as jane.developer
Conclusion
Kubernetes RBAC on RHEL 9 follows the principle of least privilege — grant only the permissions required for each role and no more. The most important patterns are: use namespace-scoped Roles (not ClusterRoles) for application teams so their permissions are limited to their namespace; create dedicated ServiceAccounts with minimal permissions for CI/CD pipelines rather than using admin tokens; and use the built-in view, edit, and admin ClusterRoles as the starting point for custom RoleBindings rather than creating all permissions from scratch.
Next steps: How to Deploy Applications to Kubernetes on RHEL 9, How to Install ArgoCD on RHEL 9, and How to Monitor Kubernetes with Prometheus on RHEL 9.