Kubernetes RBAC Audit Prompt
Audit Kubernetes Role, ClusterRole, RoleBinding, and ClusterRoleBinding for excessive permissions, stale bindings, and dangerous wildcards.
- Target user
- Kubernetes platform engineers and security engineers
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a senior Kubernetes security engineer with deep experience auditing RBAC in production clusters. You know which permissions look harmless and aren't (e.g., `secrets get` = read every credential, `pods/exec create` = arbitrary code execution as the pod's identity). I will provide: - Output of `kubectl get clusterrolebindings -o yaml` (or a subset relevant to the audit) - Output of `kubectl get rolebindings -A -o yaml` - The specific ClusterRoles / Roles referenced by those bindings - Optionally: ServiceAccount inventory (`kubectl get sa -A`) - Audit scope: "all" / specific namespace / specific service account Your job: 1. **Identify dangerous verbs per resource**: - `secrets` + `get/list/watch` → read every credential in scope - `pods/exec` + `create` → arbitrary code execution as any pod's SA - `pods/attach`, `pods/portforward` → similar privilege escalation paths - `*` (wildcard) verb on any resource → effectively admin for that resource - `escalate` + `bind` on roles/clusterroles → can grant themselves more - `serviceaccounts/token` + `create` → mint tokens as any SA (privilege escalation) - `nodes/proxy` → run commands on nodes (effectively node-admin) - `certificatesigningrequests` + `approve` → can issue cluster certs - `mutatingwebhookconfigurations` / `validatingwebhookconfigurations` + write → can intercept & modify any API request - `customresourcedefinitions` + write → can define resources that other controllers act on 2. **Identify dangerous subjects**: - `system:authenticated` or `system:unauthenticated` group bindings — broad - `system:anonymous` user bindings — extremely broad - `default` ServiceAccount bound to anything privileged — pods that don't set `serviceAccountName` get this - Stale ServiceAccounts (bound but the SA no longer exists) 3. **Identify dangerous scopes**: - ClusterRoleBinding to a "tenant" role that should have been a RoleBinding (cross-namespace privilege) - `aggregationRule` ClusterRoles that pull in too many fragments 4. **For each finding** produce: **severity** (critical/high/med/low), **subject**, **role/clusterrole**, **specific verb+resource** of concern, **why it matters**, **suggested fix** as a kubectl diff or yaml patch. 5. **Highlight the "kingmaker" permissions** that allow further privilege escalation, separate from "just" sensitive permissions. The kingmaker set is: `escalate`, `bind`, `impersonate`, `serviceaccounts/token create`, `nodes/proxy`, write on admission webhook configs. 6. **Generate a final summary** with counts per severity and the top 10 most urgent fixes. Be paranoid but practical — a high-severity finding on a single internal-tooling SA is different from the same finding on `system:authenticated`. --- Cluster context: [prod / staging / dev / multi-tenant] Audit scope: [whole cluster / namespace=<X> / service-account=<Y>] RBAC bindings to audit: ```yaml [PASTE clusterrolebindings -o yaml] --- [PASTE rolebindings -A -o yaml] ``` Referenced ClusterRoles / Roles: ```yaml [PASTE relevant ClusterRoles -o yaml] ``` Optional: SA list with sensitive ones flagged: ``` [PASTE] ```
Why this prompt works
RBAC issues compound silently. A ServiceAccount with secrets get looks fine until you realize that ClusterRoleBinding scopes it across all namespaces — including the one with database credentials. Models tend to evaluate each role in isolation; this prompt forces them to compute effective permissions per subject and flag the kingmaker verbs.
How to use it
- Audit by subject, not by role. Pull the full set of bindings for the subject (e.g., a specific SA), then enumerate the union of all roles’ rules.
- Group findings by severity. A cluster with 200 ClusterRoles will have many findings — focus the human attention on the critical few.
- Test scope assumptions. A RoleBinding referencing a ClusterRole IS scoped to the binding’s namespace — that’s correct and common. A ClusterRoleBinding referencing the same ClusterRole is cluster-wide — that’s where audits usually find problems.
- For multi-tenant clusters, audit every namespace that should be isolated; ClusterRoleBindings break tenant boundaries.
Useful commands
# Inventory
kubectl get clusterrolebindings -o yaml > crb.yaml
kubectl get rolebindings -A -o yaml > rb.yaml
kubectl get clusterroles -o yaml > cr.yaml
kubectl get roles -A -o yaml > r.yaml
kubectl get serviceaccounts -A
# Find all bindings for a specific subject
kubectl get clusterrolebindings -o json | jq --arg sa "my-sa" --arg ns "default" \
'.items[] | select(.subjects[]? | .kind=="ServiceAccount" and .name==$sa and .namespace==$ns)'
# Find ClusterRoles with dangerous verbs
kubectl get clusterroles -o json | \
jq '.items[] | select(.rules[]? | (.verbs[]? == "*" or .resources[]? == "*")) | .metadata.name'
# Who can do X? (kubectl can-i, on a specific SA)
kubectl auth can-i --as=system:serviceaccount:<ns>:<sa> get secrets -A
kubectl auth can-i --as=system:serviceaccount:<ns>:<sa> create pods/exec -A
kubectl auth can-i --as=system:serviceaccount:<ns>:<sa> '*' '*'
# Use krew plugin: rbac-tool / rbac-lookup
kubectl krew install rbac-tool rbac-lookup
kubectl rbac-tool lookup <name> # who can do what
kubectl rbac-tool policy-rules -e <subject> # effective rules
kubectl rbac-tool who-can get secrets -A
# Find unused/stale ServiceAccounts
# (SAs with no bindings or no pods using them)
comm -23 <(kubectl get sa -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' | sort) \
<(kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.spec.serviceAccountName}{"\n"}{end}' | sort -u)
Verb cheatsheet (severity at a glance)
| Verb + Resource | Severity | Why |
|---|---|---|
* * * (any verb, any resource) | Critical | Cluster admin |
get/list/watch secrets * | Critical | Reads all credentials |
create pods/exec | Critical | Arbitrary code execution as the target SA |
create serviceaccounts/token | Critical | Mint tokens as any SA — privilege escalation |
* nodes or nodes/proxy | Critical | Node-level command execution |
create/update mutatingwebhookconfigurations | Critical | Can rewrite any request |
escalate roles/clusterroles | Critical | Can grant more than they have |
bind roles/clusterroles | Critical | Can bind any subject to any role |
impersonate users/groups/serviceaccounts | Critical | Can act as anyone |
create customresourcedefinitions | High | Can install controllers that act on other resources |
* deployments, * statefulsets | High | Workload control = code execution via SA chain |
get/list configmaps | Medium | Often contains config but sometimes secrets |
* pods | Medium | Useful, but couple with pods/exec for escalation |
Common findings this catches
defaultSA bound tocluster-adminin a “dev” namespace — every unconfigured pod is cluster admin.system:authenticatedgroup hassecrets getcluster-wide — every authenticated user can read every secret.- A backup operator with
* * *— common but often unnecessary; usually only needs read on most resources + write on its own. - Webhook admission controller SA has cluster-admin — webhooks can be powerful with much less.
- Stale RoleBindings to deleted users — leftover from offboarding; clean up.
- Aggregated ClusterRoles pulling in fragments via
aggregationRulethat you didn’t realize grantedsecrets list. - CI/CD SA with
create deploymentsinkube-system— pipeline compromise = cluster compromise.
Minimal-blast-radius fixes
- Move a ClusterRoleBinding to a RoleBinding when the subject only operates in one namespace.
- Split a wildcard ClusterRole into a narrower one and re-bind only the verbs needed.
- Replace
*verb with explicit verb list —get,list,watchis usually enough for read-only controllers. - Use
resourceNamesto scope a role to specific named resources where possible (works forget/update/patch/delete, notlistorcreate).
When to escalate
- A finding that touches a system-critical SA (
kube-controller-manager,kubelet,kube-proxy) — coordinate with platform team before changing. - Bindings managed by operators / Helm charts / GitOps — fix at the source (chart values, GitOps repo), not by manual
kubectl delete. - Anything that looks like a defense-in-depth control: removing it may unblock a real attack path even if “looks unused.”
Related prompts
-
Kubernetes NetworkPolicy Debug Prompt
Diagnose why pod-to-pod, pod-to-service, or pod-to-external traffic is being dropped by NetworkPolicy — Calico, Cilium, Weave, or upstream defaults.
-
Kubernetes Secrets Management Review Prompt
Audit how Kubernetes Secrets are stored, mounted, and rotated — flag base64-as-encryption myths, env-var leakage, and missing external-secrets / sealed-secrets / KMS integration.
-
Kubernetes YAML Security Review Checklist Prompt
AI-driven security review of Kubernetes manifests — privilege, capabilities, network exposure, secret handling, and admission-policy compliance.