Skip to content
Back to skills

K8s Rbac Patterns

ASecurity

Kubernetes RBAC reference: the Role and ClusterRole binding model, evaluation logic, escalation paths, least-privilege patterns for developers, CI/CD, monitoring, and break-glass access, plus common misconfigurations. Use when writing RBAC manifests or reviewing who can do what in a cluster.

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 1, 2026
securitygonodekubernetesdebugginggitapifrontendci/cdsecuritydocumentation

Works with

  • api

Security analysis

A100/100

Scanned October 1, 2026

npx -y skills add HermeticOrmus/LibreSecOps-Claude-Code --skill k8s-rbac-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of K8s Rbac Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for K8s Rbac Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/hermeticormus-k8s-rbac-patterns/badge)](https://www.skillsdirectory.com/skills/hermeticormus-k8s-rbac-patterns)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: "k8s-rbac-patterns"
description: "Kubernetes RBAC reference: the Role and ClusterRole binding model, evaluation logic, escalation paths, least-privilege patterns for developers, CI/CD, monitoring, and break-glass access, plus common misconfigurations. Use when writing RBAC manifests or reviewing who can do what in a cluster."
---

# K8s RBAC Patterns

> RBAC design patterns, least-privilege role definitions, common misconfigurations, and privilege escalation prevention.

## Knowledge Base

### RBAC Object Model

Kubernetes RBAC uses four object types:

| Object | Scope | Purpose |
|--------|-------|---------|
| **Role** | Namespace | Defines permissions within a single namespace |
| **ClusterRole** | Cluster-wide | Defines permissions across all namespaces or for cluster-scoped resources |
| **RoleBinding** | Namespace | Binds a Role OR ClusterRole to subjects within a namespace |
| **ClusterRoleBinding** | Cluster-wide | Binds a ClusterRole to subjects across all namespaces |

**Critical distinction**: A ClusterRole bound with a RoleBinding is scoped to that namespace. The same ClusterRole bound with a ClusterRoleBinding applies cluster-wide. This is how you create reusable role definitions with namespace-scoped grants.

### RBAC Evaluation Logic

1. All RBAC rules are **additive** -- there is no deny rule in Kubernetes RBAC
2. If no rule grants access, the request is **denied by default**
3. Rules are evaluated by the API server at request time
4. `system:masters` group bypasses RBAC entirely (built into the API server)
5. The `escalate` and `bind` verbs control whether a user can create roles more powerful than their own

### Privilege Escalation Through RBAC

These permissions enable RBAC-based privilege escalation:

| Permission | Escalation Path |
|-----------|----------------|
| `create pods` | Create a pod with any service account, mounting secrets, using hostPath |
| `create pods/exec` | Exec into a pod running with a more-privileged service account |
| `create serviceaccounts` + `create rolebindings` | Create a SA and bind cluster-admin to it |
| `escalate` on roles | Create or modify roles to have more permissions than you have |
| `bind` on roles | Bind any role (including cluster-admin) to any subject |
| `impersonate` | Act as any user, group, or service account |
| `create secrets` | Create a service account token secret for any SA |
| `patch nodes` | Modify node labels to bypass scheduling constraints |

## Patterns

### Pattern 1: Application Developer Role (Namespace-Scoped)

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: app-developer
rules:
  # Workload management
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets", "statefulsets"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  # Do NOT grant delete on deployments (use rollback instead)

  # Pod debugging (read-only + logs + exec)
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create"]
    # Consider: exec enables command execution as the pod's SA

  # Config and secrets (limited)
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]
    # Note: no create/update on secrets -- handled by CI/CD or secrets operator

  # Services
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

  # HPA
  - apiGroups: ["autoscaling"]
    resources: ["horizontalpodautoscalers"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

  # Events (read-only for debugging)
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["get", "list", "watch"]
---
# Bind to a specific namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-team-app-developer
  namespace: team-alpha
subjects:
  - kind: Group
    name: team-alpha-devs
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: app-developer
  apiGroup: rbac.authorization.k8s.io
```

**Why this works**: Developers can manage their workloads, debug pods, and update configs, but cannot create secrets, delete deployments (preventing accidental destruction), access other namespaces, or modify RBAC. The ClusterRole is reusable across namespaces via RoleBindings.

### Pattern 2: CI/CD Service Account (Minimal Deploy Permissions)

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cicd-deployer
  namespace: production
  annotations:
    description: "CI/CD pipeline deployment account"
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cicd-deployer-role
  namespace: production
rules:
  # Only update existing deployments (cannot create new ones)
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "patch"]
    resourceNames: ["api-server", "worker", "frontend"]
    # resourceNames restricts to specific named resources

  # Can update configmaps for deployment configs
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "update", "patch"]
    resourceNames: ["api-config", "worker-config", "frontend-config"]

  # Can view rollout status
  - apiGroups: ["apps"]
    resources: ["deployments/status", "replicasets"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cicd-deployer-binding
  namespace: production
subjects:
  - kind: ServiceAccount
    name: cicd-deployer
    namespace: production
roleRef:
  kind: Role
  name: cicd-deployer-role
  apiGroup: rbac.authorization.k8s.io
```

**Why this works**: The `resourceNames` field restricts access to specific, named resources. The CI/CD pipeline can only update the exact deployments and configmaps it manages -- not create new ones, not access secrets, not modify RBAC. This is the tightest practical RBAC for a deployment pipeline.

### Pattern 3: Read-Only Monitoring Role

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-reader
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "endpoints", "nodes", "namespaces"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]
  - apiGroups: ["metrics.k8s.io"]
    resources: ["pods", "nodes"]
    verbs: ["get", "list"]
  # Explicitly NOT including: secrets, configmaps, exec, RBAC objects
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: monitoring-reader-binding
subjects:
  - kind: ServiceAccount
    name: prometheus
    namespace: monitoring
roleRef:
  kind: ClusterRole
  name: monitoring-reader
  apiGroup: rbac.authorization.k8s.io
```

**Why this works**: Monitoring tools need broad read access but should never have write access or access to sensitive objects. This role provides visibility into workload state and metrics without exposing secrets, RBAC configurations, or exec capabilities.

### Pattern 4: Emergency Break-Glass ClusterRoleBinding

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: emergency-break-glass
  annotations:
    purpose: "Emergency access only. Usage is monitored and audited."
    contact: "security-team@company.com"
subjects:
  - kind: Group
    name: emergency-responders
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
```

Paired with audit logging that specifically watches for this group:

```yaml
# Audit policy to log all emergency-responder actions
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: RequestResponse
    users: []
    userGroups: ["emergency-responders"]
    resources:
      - group: ""
        resources: ["*"]
```

**Why this works**: Emergency access to cluster-admin must exist (you cannot lock yourself out), but it must be audited at the highest level. The group membership should be managed via your identity provider (not directly in Kubernetes), and usage should trigger immediate security team alerts.

## Anti-Patterns

### Anti-Pattern 1: Using Default Service Accounts

Every namespace has a `default` service account. If you do not create explicit service accounts for your workloads, all pods use `default`. If anyone grants permissions to `default`, all pods in the namespace inherit them.

**Fix**: Create dedicated service accounts per workload. Set `automountServiceAccountToken: false` on the `default` service account and on pods that do not need API access.

### Anti-Pattern 2: ClusterRoleBinding Instead of RoleBinding

Binding a ClusterRole with a ClusterRoleBinding grants permissions across ALL namespaces. Most applications only need access to their own namespace.

**Fix**: Use RoleBinding to bind ClusterRoles to specific namespaces. Reserve ClusterRoleBindings for cluster-wide roles (monitoring, node management, emergency access).

### Anti-Pattern 3: Wildcard Verbs or Resources

```yaml
# BAD
rules:
  - apiGroups: ["*"]
    resources: ["*"]
    verbs: ["*"]
```

This is cluster-admin in disguise. Even `["get", "list", "watch"]` on `["*"]` exposes all secrets in all namespaces.

**Fix**: Enumerate the exact apiGroups, resources, and verbs needed. Use `resourceNames` where possible.

### Anti-Pattern 4: Granting RBAC Management Permissions

```yaml
# BAD -- allows self-escalation
rules:
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
    verbs: ["create", "update", "patch"]
```

Any user with these permissions can create a RoleBinding that grants themselves cluster-admin (or any other role). The `escalate` verb was introduced to prevent this, but many clusters do not have the `ValidatingAdmissionPolicy` or webhook to enforce it.

**Fix**: RBAC management should be restricted to platform administrators and CI/CD pipelines with specific, audited access.

### Anti-Pattern 5: Not Auditing RBAC Changes

RBAC changes are high-impact, low-frequency events. If you are not logging and alerting on RBAC modifications, an attacker can grant themselves persistent access without detection.

**Fix**: Configure audit policy to log all RBAC changes at `RequestResponse` level. Alert on any creation or modification of ClusterRoleBindings, especially those referencing `cluster-admin`.

## References

- [Kubernetes RBAC Documentation](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
- [Kubernetes RBAC Good Practices](https://kubernetes.io/docs/concepts/security/rbac-good-practices/)
- [KubiScan -- RBAC Risk Scanner](https://github.com/cyberark/KubiScan)
- [kubectl-who-can](https://github.com/aquasecurity/kubectl-who-can)
- [rbac-tool](https://github.com/alcideio/rbac-tool)
- [CIS Kubernetes Benchmark -- RBAC Controls](https://www.cisecurity.org/benchmark/kubernetes)
- [Kubernetes Security Audit (Trail of Bits)](https://github.com/trailofbits/audit-kubernetes)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…