Roles & Bindings

Roles and Bindings are the core components of RBAC. A Role defines what actions can be performed, while a Binding connects those permissions to specific users, groups, or ServiceAccounts.

Roles vs ClusterRoles

The key difference is scope:

  • Role - Namespace-scoped, applies only to resources within a single namespace
  • ClusterRole - Cluster-scoped, applies to cluster-wide resources or can be referenced across namespaces
graph TB subgraph Namespace["Namespace: production"] Role[Role<br/>Namespace-scoped] RoleBinding[RoleBinding<br/>Binds Role to subjects] end subgraph Cluster["Cluster-wide"] ClusterRole[ClusterRole<br/>Cluster-scoped] ClusterRoleBinding[ClusterRoleBinding<br/>Binds ClusterRole to subjects] end Role --> RoleBinding ClusterRole --> ClusterRoleBinding

Role Structure

A Role defines permissions using rules. Each rule specifies:

  • apiGroups - Which API group the resource belongs to (empty string for core API)
  • resources - Which resources (pods, services, deployments, etc.)
  • verbs - What actions are allowed (get, list, create, update, delete, patch, watch)
  • resourceNames - Optional: specific resource instances (rarely used)
  • nonResourceURLs - For ClusterRoles only: non-resource endpoints like /healthz

Example: Namespace-scoped Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: deployment-manager
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

This role allows managing deployments and viewing pods in the production namespace only.

Example: Cluster-scoped ClusterRole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-viewer
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "list"]

This ClusterRole allows viewing nodes and namespaces across the entire cluster.

Bindings

Bindings connect roles to subjects (users, groups, or ServiceAccounts):

  • RoleBinding - Binds a Role or ClusterRole to subjects within a namespace
  • ClusterRoleBinding - Binds a ClusterRole to subjects cluster-wide

RoleBinding Example

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deploy-access
  namespace: production
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
  name: ci-cd-bot
  namespace: production
roleRef:
  kind: Role
  name: deployment-manager
  apiGroup: rbac.authorization.k8s.io

This binding grants the deployment-manager role to user alice and the ci-cd-bot ServiceAccount in the production namespace.

ClusterRoleBinding Example

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admins
subjects:
- kind: Group
  name: system:masters
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

This binding grants cluster-admin permissions to all members of the system:masters group.

Important Patterns

Using ClusterRole with RoleBinding

You can reference a ClusterRole in a RoleBinding to grant cluster-wide permissions within a specific namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: admin-in-namespace
  namespace: development
subjects:
- kind: User
  name: bob
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: admin
  apiGroup: rbac.authorization.k8s.io

This gives bob admin permissions (via the built-in admin ClusterRole) but only within the development namespace.

Aggregated ClusterRoles

You can combine multiple ClusterRoles using aggregation labels:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-aggregate
  labels:
    rbac.authorization.k8s.io/aggregate-to-monitoring: "true"
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list", "watch"]

Any ClusterRole with the aggregation label automatically gets these rules added to it.

Common Verbs

  • get - Retrieve a specific resource
  • list - List all resources of a type
  • watch - Watch for changes to resources
  • create - Create new resources
  • update - Update existing resources (full replacement)
  • patch - Partially update resources
  • delete - Delete resources
  • deletecollection - Delete multiple resources at once

Best Practices

  1. Use specific verbs - Don’t use * unless absolutely necessary
  2. Limit resource scope - Specify exact resources rather than *
  3. Namespace isolation - Prefer Roles over ClusterRoles when possible
  4. Reusable ClusterRoles - Create ClusterRoles for common permission sets
  5. Document bindings - Add annotations explaining why permissions were granted

Troubleshooting

Check what permissions a user has:

kubectl auth can-i --list --as=system:serviceaccount:production:my-app

Test specific permissions:

kubectl auth can-i create deployments --namespace=production --as=alice

View all roles and bindings:

kubectl get roles,rolebindings --all-namespaces
kubectl get clusterroles,clusterrolebindings

See Also