Kubernetes RBAC and service account security
Ryan Nakamura
Feb 2026
1 tab
# Service Account for the application
apiVersion: v1
kind: ServiceAccount
metadata:
name: web-app-sa
namespace: production
annotations:
# For AWS IAM roles (IRSA)
eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/web-app-role
automountServiceAccountToken: true
---
# Role: permissions within a namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: web-app-role
namespace: production
rules:
# Read ConfigMaps and Secrets
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
# Manage pods (for debugging)
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
# Read services
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list"]
---
# Bind role to service account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: web-app-binding
namespace: production
subjects:
- kind: ServiceAccount
name: web-app-sa
namespace: production
roleRef:
kind: Role
name: web-app-role
apiGroup: rbac.authorization.k8s.io
---
# ClusterRole for read-only cluster access
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-viewer
rules:
- apiGroups: [""]
resources: ["namespaces", "nodes", "pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch"]
---
# Developer role: deploy to staging
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer-staging
namespace: staging
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: [""]
resources: ["pods", "pods/log", "pods/exec"]
verbs: ["get", "list", "create"]
- apiGroups: [""]
resources: ["services", "configmaps"]
verbs: ["get", "list"]
---
# Bind developer group
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-staging-binding
namespace: staging
subjects:
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer-staging
apiGroup: rbac.authorization.k8s.io
---
# CI/CD service account (limited deploy permissions)
apiVersion: v1
kind: ServiceAccount
metadata:
name: ci-deployer
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ci-deployer-role
namespace: production
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "update", "patch"]
resourceNames: ["web-app", "worker"]
- apiGroups: ["apps"]
resources: ["deployments/status"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-deployer-binding
namespace: production
subjects:
- kind: ServiceAccount
name: ci-deployer
namespace: production
roleRef:
kind: Role
name: ci-deployer-role
apiGroup: rbac.authorization.k8s.io
1 file · yaml
Explain with highlit
Kubernetes RBAC (Role-Based Access Control) restricts cluster access by user, group, or service account. Roles define permissions within a single namespace using rules with apiGroups, resources, and verbs. ClusterRoles apply cluster-wide. RoleBindings link Roles to subjects (users, groups, service accounts). ClusterRoleBindings grant cluster-wide access. Service accounts provide identity for Pods. Each namespace has a default service account. Custom service accounts limit Pod permissions. automountServiceAccountToken: false prevents unnecessary token mounting. RBAC verbs include get, list, watch, create, update, patch, delete. Aggregate ClusterRoles combine multiple roles. Regular RBAC audits prevent privilege escalation.