Kubernetes RBAC Wildcard Elevation on Existing Role

Flags an existing Role or ClusterRole being changed (patch or update) so the effective rules become cluster-admin-like: wildcard on every API resource and wildcard on every verb. That is usually a deliberate privilege expansion, not a typo. RequestResponse audit and the response body are required so the detection reads the merged role after apply; loopback source IPs are ignored.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/04/27"
  3integration = ["kubernetes"]
  4maturity = "production"
  5updated_date = "2026/09/18"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Flags an existing Role or ClusterRole being changed (patch or update) so the effective rules become cluster-admin-like:
 11wildcard on every API resource and wildcard on every verb. That is usually a deliberate privilege expansion, not a typo.
 12RequestResponse audit and the response body are required so the detection reads the merged role after apply; loopback
 13source IPs are ignored.
 14"""
 15false_positives = [
 16    """
 17    Platform installers, GitOps controllers, and emergency break-glass roles sometimes ship or widen wildcard
 18    ClusterRoles; correlate with change records and narrow by user or service account when baselined.
 19    """,
 20]
 21from = "now-9m"
 22interval = "5m"
 23language = "esql"
 24license = "Elastic License v2"
 25name = "Kubernetes RBAC Wildcard Elevation on Existing Role"
 26note = """## Triage and analysis
 27
 28### Investigating Kubernetes RBAC Wildcard Elevation on Existing Role
 29
 30Someone patched or updated a Role or ClusterRole so the stored rules grant star verbs and star resources—near
 31cluster-admin breadth on that scope. Confirm the actor (user, group, impersonation), client, and non-loopback source
 32IP; then see who can bind that role.
 33
 34### Possible investigation steps
 35
 36- Diff the role YAML before and after; list RoleBindings and ClusterRoleBindings that reference it and which subjects
 37  gained the widened access.
 38- In the same window, check secret reads, exec, and further RBAC changes from the same identity.
 39
 40### False positive analysis
 41
 42- Approved GitOps or vendor upgrades sometimes widen a known ClusterRole; allowlist stable automation when documented.
 43
 44### Response and remediation
 45
 46- Revert the role, drop unexpected bindings, rotate credentials for the actor, and block future wildcard RBAC outside
 47  governed pipelines (policy-as-code, PR-only RBAC).
 48"""
 49references = [
 50    "https://attack.mitre.org/techniques/T1098/006/",
 51    "https://kubernetes.io/docs/reference/access-authn-authz/rbac/",
 52]
 53risk_score = 73
 54rule_id = "c8f4a2e1-9b3d-4c7e-8f2a-1d0e5b6c7a89"
 55severity = "high"
 56tags = [
 57    "Data Source: Kubernetes",
 58    "Domain: Kubernetes",
 59    "Use Case: Threat Detection",
 60    "Tactic: Privilege Escalation",
 61    "Resources: Investigation Guide",
 62    "Noise: Low",
 63    "Performance: Normal",
 64    "Rule Type: ES|QL",
 65    "Platform: Kubernetes",
 66    "Domain: Containers",
 67    "Domain: Cloud",
 68]
 69timestamp_override = "event.ingested"
 70type = "esql"
 71query = '''
 72from logs-kubernetes.audit_logs-* metadata _id, _index, _version
 73| where
 74  kubernetes.audit.objectRef.resource in ("roles", "clusterroles") and
 75  kubernetes.audit.verb in ("update", "patch") and
 76  `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" and
 77  kubernetes.audit.level == "RequestResponse" and
 78  kubernetes.audit.stage == "ResponseComplete" and
 79  kubernetes.audit.sourceIPs is not null and
 80  not kubernetes.audit.sourceIPs in ("::1", "127.0.0.1") and
 81  KQL(""" kubernetes.audit.responseObject.rules.verbs:"*" and kubernetes.audit.responseObject.rules.resources:"*" """)
 82| keep user.name, user_agent.original, event.action, source.ip, kubernetes.audit.verb, kubernetes.audit.objectRef.resource, kubernetes.audit.objectRef.name, kubernetes.audit.requestURI, kubernetes.audit.user.username, kubernetes.audit.user.groups, `kubernetes.audit.annotations.authorization_k8s_io/decision`, event.original, _id, _version, _index, data_stream.namespace
 83'''
 84
 85[[rule.threat]]
 86framework = "MITRE ATT&CK"
 87
 88[[rule.threat.technique]]
 89id = "T1098"
 90name = "Account Manipulation"
 91reference = "https://attack.mitre.org/techniques/T1098/"
 92
 93[[rule.threat.technique.subtechnique]]
 94id = "T1098.006"
 95name = "Additional Container Cluster Roles"
 96reference = "https://attack.mitre.org/techniques/T1098/006/"
 97
 98[rule.threat.tactic]
 99id = "TA0004"
100name = "Privilege Escalation"
101reference = "https://attack.mitre.org/tactics/TA0004/"

Triage and analysis

Investigating Kubernetes RBAC Wildcard Elevation on Existing Role

Someone patched or updated a Role or ClusterRole so the stored rules grant star verbs and star resources—near cluster-admin breadth on that scope. Confirm the actor (user, group, impersonation), client, and non-loopback source IP; then see who can bind that role.

Possible investigation steps

  • Diff the role YAML before and after; list RoleBindings and ClusterRoleBindings that reference it and which subjects gained the widened access.
  • In the same window, check secret reads, exec, and further RBAC changes from the same identity.

False positive analysis

  • Approved GitOps or vendor upgrades sometimes widen a known ClusterRole; allowlist stable automation when documented.

Response and remediation

  • Revert the role, drop unexpected bindings, rotate credentials for the actor, and block future wildcard RBAC outside governed pipelines (policy-as-code, PR-only RBAC).

References

Related rules

to-top