Configure Kubernetes RBAC with service accounts and cluster roles for secure access control

Intermediate 25 min Jun 15, 2026 1,450 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Learn to implement Kubernetes Role-Based Access Control (RBAC) with service accounts, cluster roles, and role bindings for granular permissions and secure cluster access management.

Prerequisites

  • Running Kubernetes cluster with kubectl access
  • Cluster admin permissions for RBAC configuration
  • Basic understanding of Kubernetes concepts

What this solves

Kubernetes RBAC provides fine-grained access control for your cluster resources by defining who can perform specific actions on which resources. This tutorial shows you how to create service accounts with appropriate permissions using cluster roles and role bindings, ensuring secure access control while maintaining operational flexibility.

Understanding RBAC components

Kubernetes RBAC consists of four main components that work together to control access. Service accounts represent identities for pods and external systems. Roles and ClusterRoles define permissions for specific actions. RoleBindings and ClusterRoleBindings associate subjects (users, groups, or service accounts) with roles.

Note: ClusterRoles apply cluster-wide while Roles are namespace-specific. ClusterRoleBindings grant cluster-wide permissions while RoleBindings grant namespace-specific permissions.

Step-by-step configuration

Verify RBAC is enabled

Check that RBAC is enabled in your Kubernetes cluster by examining the API server configuration.

kubectl auth can-i list pods --as=system:anonymous
kubectl cluster-info dump | grep -i authorization-mode

Create a dedicated namespace

Create a namespace for testing RBAC configurations to isolate your setup.

kubectl create namespace rbac-demo

Create service accounts

Create service accounts with specific metadata and labels for better organization.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-reader
  namespace: rbac-demo
  labels:
    app: rbac-demo
    role: reader
  annotations:
    description: "Service account for reading pod information"
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: deployment-manager
  namespace: rbac-demo
  labels:
    app: rbac-demo
    role: manager
  annotations:
    description: "Service account for managing deployments"
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cluster-admin-sa
  namespace: rbac-demo
  labels:
    app: rbac-demo
    role: admin
  annotations:
    description: "Service account with cluster-wide admin privileges"
kubectl apply -f serviceaccounts.yaml

Create cluster roles with specific permissions

Define cluster roles with granular permissions for different access levels.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader-role
  labels:
    app: rbac-demo
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: deployment-manager-role
  labels:
    app: rbac-demo
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["events"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: namespace-admin-role
  labels:
    app: rbac-demo
rules:
- apiGroups: [""]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["apps"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["extensions"]
  resources: ["*"]
  verbs: ["*"]
kubectl apply -f clusterroles.yaml

Create namespace-specific roles

Create roles that are scoped to specific namespaces for more granular control.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: rbac-demo
  name: secret-manager
  labels:
    app: rbac-demo
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: rbac-demo
  name: service-manager
  labels:
    app: rbac-demo
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
  resources: ["endpoints"]
  verbs: ["get", "list", "watch"]
kubectl apply -f roles.yaml

Create cluster role bindings

Bind service accounts to cluster roles to grant cluster-wide permissions.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-reader-binding
  labels:
    app: rbac-demo
subjects:
- kind: ServiceAccount
  name: pod-reader
  namespace: rbac-demo
roleRef:
  kind: ClusterRole
  name: pod-reader-role
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: deployment-manager-binding
  labels:
    app: rbac-demo
subjects:
- kind: ServiceAccount
  name: deployment-manager
  namespace: rbac-demo
roleRef:
  kind: ClusterRole
  name: deployment-manager-role
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-binding
  labels:
    app: rbac-demo
subjects:
- kind: ServiceAccount
  name: cluster-admin-sa
  namespace: rbac-demo
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f clusterrolebindings.yaml

Create namespace-specific role bindings

Bind service accounts to namespace roles for scoped permissions.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-manager-binding
  namespace: rbac-demo
  labels:
    app: rbac-demo
subjects:
- kind: ServiceAccount
  name: deployment-manager
  namespace: rbac-demo
roleRef:
  kind: Role
  name: secret-manager
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: service-manager-binding
  namespace: rbac-demo
  labels:
    app: rbac-demo
subjects:
- kind: ServiceAccount
  name: deployment-manager
  namespace: rbac-demo
roleRef:
  kind: Role
  name: service-manager
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f rolebindings.yaml

Configure service account tokens

Create long-lived tokens for service accounts that need persistent access.

apiVersion: v1
kind: Secret
metadata:
  name: pod-reader-token
  namespace: rbac-demo
  annotations:
    kubernetes.io/service-account.name: pod-reader
type: kubernetes.io/service-account-token
---
apiVersion: v1
kind: Secret
metadata:
  name: deployment-manager-token
  namespace: rbac-demo
  annotations:
    kubernetes.io/service-account.name: deployment-manager
type: kubernetes.io/service-account-token
kubectl apply -f serviceaccount-tokens.yaml

Create test pods with service accounts

Deploy pods that use the configured service accounts to test RBAC permissions.

apiVersion: v1
kind: Pod
metadata:
  name: pod-reader-test
  namespace: rbac-demo
  labels:
    app: rbac-demo
    test: pod-reader
spec:
  serviceAccountName: pod-reader
  containers:
  - name: kubectl
    image: bitnami/kubectl:latest
    command: ['sleep', '3600']
  restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
  name: deployment-manager-test
  namespace: rbac-demo
  labels:
    app: rbac-demo
    test: deployment-manager
spec:
  serviceAccountName: deployment-manager
  containers:
  - name: kubectl
    image: bitnami/kubectl:latest
    command: ['sleep', '3600']
  restartPolicy: Never
kubectl apply -f test-pods.yaml

Implementing advanced RBAC policies

Create resource-specific permissions

Configure roles with permissions for specific resources and resource names.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: rbac-demo
  name: specific-resource-manager
  labels:
    app: rbac-demo
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["app-secret", "db-secret"]
  verbs: ["get", "update"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  resourceNames: ["app-deployment"]
  verbs: ["get", "update", "patch"]
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]
  resourceNames: ["app-config"]
kubectl apply -f resource-specific-role.yaml

Implement attribute-based access control

Create roles that use label selectors and field selectors for fine-grained access.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: label-based-access
  labels:
    app: rbac-demo
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["pods/exec"]
  verbs: ["create"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch"]
  resourceNames: []
- apiGroups: [""]
  resources: ["events"]
  verbs: ["get", "list"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods", "nodes"]
  verbs: ["get", "list"]
kubectl apply -f attribute-based-role.yaml

Configure admission control integration

Create roles that work with admission controllers for policy enforcement. This example works well with OPA Gatekeeper configurations.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: admission-controller-reviewer
  labels:
    app: rbac-demo
rules:
- apiGroups: ["admissionregistration.k8s.io"]
  resources: ["validatingadmissionwebhooks", "mutatingadmissionwebhooks"]
  verbs: ["get", "list"]
- apiGroups: [""]
  resources: ["events"]
  verbs: ["create", "patch"]
- apiGroups: ["authorization.k8s.io"]
  resources: ["subjectaccessreviews"]
  verbs: ["create"]
- apiGroups: ["authentication.k8s.io"]
  resources: ["tokenreviews"]
  verbs: ["create"]
kubectl apply -f admission-control-role.yaml

Verify your RBAC setup

Test service account permissions

Verify that each service account has the expected permissions and restrictions.

# Test pod reader permissions
kubectl auth can-i list pods --as=system:serviceaccount:rbac-demo:pod-reader
kubectl auth can-i create deployments --as=system:serviceaccount:rbac-demo:pod-reader

# Test deployment manager permissions
kubectl auth can-i create deployments --as=system:serviceaccount:rbac-demo:deployment-manager
kubectl auth can-i delete secrets --as=system:serviceaccount:rbac-demo:deployment-manager -n rbac-demo

# Test cluster admin permissions
kubectl auth can-i "*" "*" --as=system:serviceaccount:rbac-demo:cluster-admin-sa

Verify permissions from within pods

Test actual API access from the pods using the service accounts.

# Test from pod-reader pod
kubectl exec -n rbac-demo pod-reader-test -- kubectl get pods --all-namespaces
kubectl exec -n rbac-demo pod-reader-test -- kubectl get deployments

# Test from deployment-manager pod
kubectl exec -n rbac-demo deployment-manager-test -- kubectl get deployments
kubectl exec -n rbac-demo deployment-manager-test -- kubectl create deployment test-deploy --image=nginx

Audit RBAC configuration

Review the complete RBAC setup and identify potential security gaps.

# List all service accounts
kubectl get serviceaccounts -n rbac-demo -o wide

# List all role bindings
kubectl get rolebindings,clusterrolebindings -n rbac-demo -o wide

# Check role definitions
kubectl describe clusterrole pod-reader-role
kubectl describe role secret-manager -n rbac-demo

# Verify token secrets
kubectl get secrets -n rbac-demo | grep token

Security best practices

Security Warning: Never use the cluster-admin role for regular applications. Always follow the principle of least privilege when assigning permissions.

Implement these security practices for production RBAC deployments. Use specific resource names when possible instead of wildcard permissions. Regularly audit and rotate service account tokens. Enable audit logging to track RBAC decisions and access patterns.

Create separate service accounts for each application or service component. Group permissions logically and use descriptive names for roles and bindings. Document the purpose and scope of each service account for your team.

For comprehensive cluster security, combine RBAC with network policies and pod security standards to create defense-in-depth protection.

Common issues

SymptomCauseFix
Service account can't access resourcesMissing role bindingCreate appropriate RoleBinding or ClusterRoleBinding
"Forbidden" errors in pod logsInsufficient permissions in roleAdd required verbs and resources to the role definition
Service account token not foundToken secret not createdCreate Secret with kubernetes.io/service-account-token type
Cross-namespace access deniedUsing Role instead of ClusterRoleUse ClusterRole and ClusterRoleBinding for cross-namespace access
Application can't read own metadataMissing self-inspection permissionsAdd permissions for pods/self and configmaps in the same namespace
Service discovery not workingMissing endpoints and services permissionsAdd get/list verbs for services and endpoints resources

Next steps

Running this in production?

Want this handled for you? Setting up RBAC once is straightforward. Keeping it patched, monitored, backed up and tuned across environments is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Sie möchten das nicht selbst verwalten?

Wir betreiben Infrastruktur für Unternehmen, die auf Verfügbarkeit angewiesen sind. Vollständig verwaltet, mit einem festen Ansprechpartner, der Ihre Umgebung kennt.

Sie erhalten einen festen Ansprechpartner, der Ihr Setup kennt

Rotterdam 19:48 · erreichbar per Nachricht, kein Ticketformular