Detection rules › Elastic
Kubernetes Service Account Modified RBAC Objects
Detects write operations performed by Kubernetes service accounts against RBAC resources (Roles, ClusterRoles, RoleBindings, ClusterRoleBindings). Service accounts typically do not manage RBAC directly; this activity may indicate token abuse, misconfigured permissions, or unauthorized privilege escalation.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | T1098.006 Account Manipulation: Additional Container Cluster Roles |
| Privilege Escalation | T1098.006 Account Manipulation: Additional Container Cluster Roles |
Event coverage
| Provider | Event | Title |
|---|---|---|
| Kubernetes-clusterrolebindings | create-clusterrolebindings | create clusterrolebindings |
| Kubernetes-clusterrolebindings | update-clusterrolebindings | update clusterrolebindings |
| Kubernetes-clusterrolebindings | patch-clusterrolebindings | patch clusterrolebindings |
| Kubernetes-clusterrolebindings | delete-clusterrolebindings | delete clusterrolebindings |
| Kubernetes-clusterroles | create-clusterroles | create clusterroles |
| Kubernetes-clusterroles | update-clusterroles | update clusterroles |
| Kubernetes-clusterroles | patch-clusterroles | patch clusterroles |
| Kubernetes-clusterroles | delete-clusterroles | delete clusterroles |
| Kubernetes-rolebindings | create-rolebindings | create rolebindings |
| Kubernetes-rolebindings | update-rolebindings | update rolebindings |
| Kubernetes-rolebindings | patch-rolebindings | patch rolebindings |
| Kubernetes-rolebindings | delete-rolebindings | delete rolebindings |
| Kubernetes-roles | create-roles | create roles |
| Kubernetes-roles | update-roles | update roles |
| Kubernetes-roles | patch-roles | patch roles |
| Kubernetes-roles | delete-roles | delete roles |
Rules detecting the same action
Other rules on this platform that filter on the same API call or operation.
- Kubernetes Cluster-Admin Role Binding Created (Elastic)
- Kubernetes Creation of a RoleBinding Referencing a ServiceAccount (Elastic)
- Kubernetes Creation or Modification of Sensitive Role (Elastic)
- Kubernetes RBAC Wildcard Elevation on Existing Role (Elastic)
- Kubernetes Rolebinding Modification (Sigma)
- Kubernetes Sensitive RBAC Change Followed by Workload Modification (Elastic)
Rule body elastic
[metadata]
creation_date = "2026/02/04"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Detects write operations performed by Kubernetes service accounts against RBAC resources (Roles,
ClusterRoles, RoleBindings, ClusterRoleBindings). Service accounts typically do not manage RBAC
directly; this activity may indicate token abuse, misconfigured permissions, or unauthorized
privilege escalation.
"""
index = ["logs-kubernetes.audit_logs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Kubernetes Service Account Modified RBAC Objects"
note = """ ## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Kubernetes Service Account Modified RBAC Objects
This rule detects Kubernetes service accounts performing allowed write actions on RBAC resources such as Roles and RoleBindings, which is atypical because service accounts rarely administer permissions. It matters because stolen or over-privileged service account tokens can silently alter authorization to gain or retain elevated access across the cluster. An attacker commonly uses a compromised workload’s token to create or patch a binding that grants cluster-admin privileges to their service account for persistent control.
### Possible investigation steps
- Retrieve the full audit event and diff the before/after RBAC object to identify newly granted subjects, verbs, resources, and cluster-admin or wildcard permissions.
- Trace the acting service account to its owning workload (Deployment/Pod) and node, then review recent image changes, restarts, exec sessions, and container logs around the event time for compromise indicators.
- Determine whether the change is attributable to an expected controller or GitOps/CI automation by correlating with change tickets, pipeline runs, and repository commits for RBAC manifests.
- Validate whether the service account token may be abused by checking for unusual API access patterns, source IPs/user agents, and cross-namespace activity compared to its baseline behavior.
- Contain if suspicious by reverting the RBAC change, rotating the service account token (and any mounted secrets), and tightening the service account’s Role/ClusterRole to least privilege.
### False positive analysis
- A platform automation running in-cluster (e.g., a controller or CI job using a service account) legitimately applies RBAC manifests during routine deployment, upgrades, or namespace onboarding, resulting in create/patch/update of Roles or RoleBindings.
- A Kubernetes operator or housekeeping workflow running under a service account intentionally adjusts RBAC as part of maintenance (e.g., rotating access, reconciling drift, or cleaning up obsolete bindings) and triggers allowed delete or update actions on RBAC resources.
### Response and remediation
- Immediately remove or quarantine the offending service account by deleting its RoleBindings/ClusterRoleBindings and restarting or scaling down the owning workload to stop further RBAC writes.
- Revert the unauthorized RBAC object changes by restoring the last known-good Roles/Bindings from GitOps/manifests (or `kubectl rollout undo` where applicable) and verify no new subjects gained wildcard or cluster-admin-equivalent access.
- Rotate credentials by recreating the service account or triggering token re-issuance, deleting any mounted legacy token secrets, and redeploying workloads to ensure old tokens cannot be reused.
- Hunt and eradicate persistence by searching for additional recently modified RBAC objects and newly created service accounts in the same namespaces, then remove unauthorized accounts/bindings and scan the implicated container images for backdoors.
- Escalate to incident response and cluster administrators immediately if any change grants `cluster-admin`, introduces `*` verbs/resources, or binds a service account to privileged ClusterRoles across namespaces.
- Harden going forward by enforcing least-privilege RBAC, enabling admission controls to restrict RBAC modifications to approved identities/namespaces, and using short-lived projected service account tokens with workload identity constraints.
"""
references = [
"https://heilancoos.github.io/research/2025/12/16/kubernetes.html#overly-permissive-role-based-access-control",
]
risk_score = 47
rule_id = "f2e21713-1eac-4908-a782-1b49c7e9d53b"
severity = "medium"
tags = [
"Data Source: Kubernetes",
"Domain: Kubernetes",
"Use Case: Threat Detection",
"Tactic: Privilege Escalation",
"Tactic: Persistence",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:"kubernetes.audit_logs" and kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
kubernetes.audit.user.username:(
system\:serviceaccount\:* and not (
"system:serviceaccount:kube-system:clusterrole-aggregation-controller" or
"system:serviceaccount:kube-system:generic-garbage-collector"
)
) and
kubernetes.audit.objectRef.resource:("clusterrolebindings" or "clusterroles" or "rolebindings" or "roles") and
kubernetes.audit.verb:("create" or "delete" or "patch" or "update")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.006"
name = "Additional Container Cluster Roles"
reference = "https://attack.mitre.org/techniques/T1098/006/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.006"
name = "Additional Container Cluster Roles"
reference = "https://attack.mitre.org/techniques/T1098/006/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
Stages and Predicates
Stage 1: query
data_stream.dataset:"kubernetes.audit_logs" and kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
kubernetes.audit.user.username:(
system\:serviceaccount\:* and not (
"system:serviceaccount:kube-system:clusterrole-aggregation-controller" or
"system:serviceaccount:kube-system:generic-garbage-collector"
)
) and
kubernetes.audit.objectRef.resource:("clusterrolebindings" or "clusterroles" or "rolebindings" or "roles") and
kubernetes.audit.verb:("create" or "delete" or "patch" or "update")
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
kubernetes.audit.user.username | in | system:serviceaccount:kube-system:clusterrole-aggregation-controller, system:serviceaccount:kube-system:generic-garbage-collector |
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
data_stream.dataset | eq |
|
kubernetes.audit.annotations.authorization_k8s_io/decision | eq |
|
kubernetes.audit.objectRef.resource | in |
|
kubernetes.audit.user.username | wildcard |
|
kubernetes.audit.verb | in |
|