Kubernetes Role-Based Access Control (RBAC) Overview

RBAC in Kubernetes is a way to manage access permissions, specifying who (or what) can do specific operations within a cluster. It uses YAML files to define policies and grant permissions.

Defining Roles and RoleBindings

Role

A Role specifies permissions like get, list, create, delete on specific resources like Pods, Services within a single namespace.

kubectl get roles -n [namespace]
kubectl describe role [role-name] -n [namespace]
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: read-pods
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

RoleBinding

Binds a Role to a set of users, groups, or service accounts. RoleBinding refers to the Role and specifies who gets the permissions.

kubectl get rolebindings -n [namespace]
kubectl describe rolebinding [rolebinding-name] -n [namespace]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-binding
subjects:
- kind: User
  name: "janedoe"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: read-pods
  apiGroup: rbac.authorization.k8s.io

Cluster Roles vs. Namespaced Roles

ClusterRole

Like a Role, but it applies cluster-wide. It grants permissions on cluster-scoped resources or across multiple namespaces.

kubectl get clusterroles
kubectl describe clusterrole [clusterrole-name]

ClusterRoleBinding

Binds a ClusterRole to a set of users, groups, or service accounts cluster-wide.

kubectl get clusterrolebindings
kubectl describe clusterrolebinding [clusterrolebinding-name]

ClusterRoles and RoleBindings can also be used together for cross-namespace permissions.

ServiceAccount Integration

Service accounts are used by pods to interact with the Kubernetes API. You can bind a Role or ClusterRole to a ServiceAccount.

kubectl get serviceaccounts -n [namespace]
kubectl describe serviceaccount [serviceaccount-name] -n [namespace]
subjects:
- kind: ServiceAccount
  name: my-serviceaccount
  namespace: my-namespace

Best Practices and Considerations

  1. Least Privilege: Grant only the permissions that are necessary.
  2. Audit and Monitor: Regularly audit RBAC settings and monitor access logs.
  3. Namespace Segregation: Use Namespaced roles for finer-grained control.
  4. Reuse and Share: Use ClusterRoles for permissions that are reused across namespaces.
  5. Short-lived Certificates: For users connecting via kubectl, prefer using short-lived certificates.

Troubleshooting Exercise

Setup

Create a Role and RoleBinding that should grant read access to Pods in the default namespace but mistakenly restricts it.

kubectl apply -f broken-role.yaml
kubectl apply -f broken-rolebinding.yaml
# broken-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: broken-read-pods
rules:
- apiGroups: [""]
  resources: ["po"]  # Mistakenly typed "po" instead of "pods"
  verbs: ["get", "list"]
# broken-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: broken-read-pods-binding
subjects:
- kind: User
  name: "janedoe"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: broken-read-pods
  apiGroup: rbac.authorization.k8s.io

Troubleshooting Steps

  1. Check the Role and RoleBinding:

    kubectl get role broken-read-pods -n default -o yaml
    kubectl get rolebinding broken-read-pods-binding -n default -o yaml
    
  2. Test Access:

    kubectl auth can-i get pods --as=janedoe -n default
    

Solution

Edit the Role to fix the incorrect resource name from “po” to “pods”.

kubectl edit role broken-read-pods -n default