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

Intermediate 25 min Jun 15, 2026 14 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

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.