A Wildcard Verb in a ClusterRole Quietly Grants Cluster-Wide Write Access
A ClusterRole edited for a debugging session and left with verbs: ["*"] silently grants cluster-wide write and delete access, because RBAC applies wildcards literally regardless of the role's original intent.
Operational summary
At a glance
- Symptom
- A platform team notices that a service account intended only to read Pod status in one namespace can also delete Deployments, modify ConfigMaps and…
- Likely cause
- Kubernetes RBAC rules are additive and verb-matching is literal.
- Impact
- Any workload or user bound to the affected ClusterRole gained the ability to modify or delete workloads, secrets-adjacent objects (ConfigMaps) and RBAC objects themselves across all namespaces, materially…
- Verification signal
- Validation confirms the corrected role grants only the intended verbs and only within the intended scope, using the same read-only commands used during diagnosis.
- Safe correction
- The correction is to replace the wildcard verb list with the explicit minimal verb set the workload actually requires, and to convert the binding scope to namespaced where…
- Rollback or recovery
- If the corrected, narrower role breaks a legitimate workload dependency that was relying on the broader access, the rollback path is to restore the previous ClusterRole and binding…
Symptom
A platform team notices that a service account intended only to read Pod status in one namespace can also delete Deployments, modify ConfigMaps and create new RoleBindings in unrelated namespaces. No RoleBinding names the service account directly for those actions, and audit logs show the account authorised via a ClusterRoleBinding that the team believed was scoped to read-only monitoring.
False Assumption
The team assumed that because the ClusterRole was named monitoring-reader and was originally written with verbs: ["get", "list", "watch"], its permissions remained narrow. A later edit, made to unblock a debugging session, replaced the verb list with verbs: ["*"] on the same resource entries, on the assumption that the wildcard applied only to the existing get/list/watch semantics for that resource type and would be reverted before merge. Kubernetes RBAC does not track intent; a wildcard verb applies to every verb Kubernetes recognises for the listed resources, including create, update, patch, delete and deletecollection, for as long as the rule exists.
Root Cause
Kubernetes RBAC rules are additive and verb-matching is literal. A rule with verbs: ["*"] matches all verbs for the matched apiGroups and resources, with no implicit restriction to the verbs originally intended by whoever authored the rule. Because the ClusterRole was bound cluster-wide via a ClusterRoleBinding rather than a namespaced RoleBinding, the effective grant applied across every namespace simultaneously. The debugging edit was never reverted because the change passed code review as a one-line diff with no automated policy check flagging wildcard verbs, and no alerting existed for ClusterRole modifications.
Impact
Any workload or user bound to the affected ClusterRole gained the ability to modify or delete workloads, secrets-adjacent objects (ConfigMaps) and RBAC objects themselves across all namespaces, materially expanding the blast radius of a single compromised or misused service account and creating a path to further privilege escalation through RoleBinding creation.
Diagnosis
Verification relies on reading current cluster RBAC objects directly rather than trusting role names or prior documentation. In an isolated or non-production cluster with equivalent RBAC objects, confirm the actual verb list bound to the account, then confirm the binding scope.
- List the ClusterRoleBindings referencing the suspect subject to confirm binding scope is cluster-wide, not namespaced.
- Inspect the referenced ClusterRole’s rules to see the literal verb and resource lists as currently stored, not as originally documented.
- Use
kubectl auth can-iagainst the specific service account to confirm which verbs are actually granted for a sample sensitive resource.
Correction
The correction is to replace the wildcard verb list with the explicit minimal verb set the workload actually requires, and to convert the binding scope to namespaced where cluster-wide access is not a genuine requirement.
- Edit the ClusterRole definition to replace
verbs: ["*"]with the explicit list needed, for exampleverbs: ["get", "list", "watch"]for a read-only monitoring role. - Apply the corrected ClusterRole in the isolated validation cluster first, not directly in production.
- If cluster-wide scope was never required, replace the ClusterRoleBinding with a namespaced RoleBinding limited to the namespaces the workload actually operates in.
- Re-run the diagnosis commands against the corrected objects to confirm the verb list and binding scope now match intended scope before promoting the change.
Validation
Validation confirms the corrected role grants only the intended verbs and only within the intended scope, using the same read-only commands used during diagnosis. Re-run kubectl auth can-i for the service account against a sensitive resource and a destructive verb (for example delete on Deployments) in a namespace outside its intended scope; the expected result is a denial. Confirm the ClusterRole’s rules no longer contain a wildcard verb entry, and confirm the binding object type and scope match the intended namespace boundary. Only promote the change to production once these checks pass in the isolated cluster.
Rollback
If the corrected, narrower role breaks a legitimate workload dependency that was relying on the broader access, the rollback path is to restore the previous ClusterRole and binding definitions from version control (the manifests should already be tracked there before any RBAC edit is applied) rather than re-introducing a wildcard verb as a quick fix. Apply the prior known-good manifest, re-run the affected workload’s functional check to confirm it operates again, and open a tracked follow-up to identify the specific minimal verb the workload needs before re-attempting the narrower correction. Do not leave a wildcard verb rule in place as a permanent workaround; treat any rollback to broader access as temporary and time-boxed.
Prevention
Prevent recurrence by treating RBAC objects as reviewed, version-controlled configuration with the same rigour as workload manifests. Require that any pull request introducing or modifying a ClusterRole is flagged automatically when it contains a wildcard verb or a wildcard resource entry, so reviewers cannot approve the change without an explicit justification comment. Prefer namespaced Roles and RoleBindings by default, and require an explicit, documented reason before a ClusterRole is bound cluster-wide via a ClusterRoleBinding. Periodically re-run the same kubectl auth can-i style checks used in diagnosis as a scheduled, read-only audit against production RBAC objects, so a debugging-driven wildcard edit that was never reverted is caught by policy rather than by an incident report.
Apply the safer control
Before you change production
Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.
Fix commands and configuration
monitoring-readerverbs: ["get", "list", "watch"]verbs: ["*"]Verify, roll back or escalate
Verify
Validation confirms the corrected role grants only the intended verbs and only within the intended scope, using the same read-only commands used during diagnosis.
Rollback
If the corrected, narrower role breaks a legitimate workload dependency that was relying on the broader access, the rollback path is to restore the previous ClusterRole and binding definitions from version control (the manifests should already be tracked there before…
Escalate
Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.