Kubernetes Potential Endpoint Permission Enumeration Attempt Detected

This rule detects potential endpoint enumeration attempts by a single user and source IP address. By looking for a combination of failed/successful API requests across multiple endpoints and a limited number of documents, this rule can detect automated permission enumeration attempts. This behavior is uncommon for regular Kubernetes clusters.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/02/02"
  3integration = ["kubernetes"]
  4maturity = "production"
  5updated_date = "2026/02/09"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10This rule detects potential endpoint enumeration attempts by a single user and source IP address. By looking for a
 11combination of failed/successful API requests across multiple endpoints and a limited number of documents, this rule
 12can detect automated permission enumeration attempts. This behavior is uncommon for regular Kubernetes clusters.
 13"""
 14language = "esql"
 15license = "Elastic License v2"
 16name = "Kubernetes Potential Endpoint Permission Enumeration Attempt Detected"
 17note = """ ## Triage and analysis
 18
 19> **Disclaimer**:
 20> 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.
 21
 22### Investigating Kubernetes Potential Endpoint Permission Enumeration Attempt Detected
 23
 24Detects a single Kubernetes identity from one IP issuing a burst of API calls across many resources and URLs with a mix of allowed and denied outcomes, consistent with automated RBAC probing rather than normal operations. This matters because attackers use it to map what they can access and identify high-value objects (secrets, pods, nodes) before escalation or lateral movement. A common pattern is running a script that iterates list/get/watch on dozens of API endpoints until it finds ones that return data.
 25
 26### Possible investigation steps
 27
 28- Expand the timeline around the alert for the same identity and source to reconstruct the full API-call sequence and identify which resource types returned successful data, prioritizing secrets, configmaps, nodes, pods, and RBAC objects.  
 29- Determine whether the source IP maps to a cluster node, pod egress/NAT, VPN, or an external host using infrastructure and network telemetry, and confirm it matches expected administrative or automation origins.  
 30- Validate whether the acting identity is a human user, service account, or external auth integration and review recent sign-ins/token issuance and current RBAC bindings for unexpected or overly broad access.  
 31- Hunt for follow-on actions from the same identity or IP that indicate escalation or execution, such as modifying role bindings, creating privileged pods, accessing secret data, or initiating exec/port-forward operations.  
 32- If the activity is not clearly legitimate, contain by rotating or disabling the credential and tightening permissions, then search for the same enumeration behavior across other identities and sources to scope impact.
 33
 34### False positive analysis
 35
 36- A cluster administrator or platform engineer using kubectl from a single workstation/VPN IP to troubleshoot RBAC issues may rapidly test get/list/watch across multiple resources and endpoints, producing a mix of allowed and forbidden responses within a short window.  
 37- A newly deployed or updated in-cluster component using a service account may probe several Kubernetes API resources during initialization or capability detection and encounter intermittent authorization denials due to incomplete RBAC bindings, generating diverse requestURIs/resources with both success and failure outcomes.
 38
 39### Response and remediation
 40
 41- Quarantine the actor by disabling the implicated user or service account (revoke kubeconfig/token and delete associated Secrets for service-account tokens) and, if the source IP is external, block it at the API server ingress/load balancer while preserving access for known admin networks.  
 42- Eradicate the access path by rotating any credentials the identity could have used (OIDC refresh tokens, client certs, static kubeconfigs) and removing unexpected RBAC RoleBindings/ClusterRoleBindings or groups that grant broad read access discovered during review.  
 43- Validate impact and recover by reviewing what endpoints returned successful data during the burst (especially secrets, configmaps, nodes, pods, and RBAC objects), rotating any exposed application secrets, and restarting affected workloads after credential updates.  
 44- Escalate immediately to incident response if the same identity subsequently creates/patches RBAC bindings, deploys privileged pods/daemonsets, performs exec/port-forward, or accesses secret data across multiple namespaces.  
 45- Harden by enforcing least-privilege RBAC for humans and service accounts, segmenting API access with network controls (private endpoint/VPN allowlists), and enabling short-lived tokens with regular rotation plus alerting on repeated mixed allow/deny probing across many resources.
 46"""
 47references = [
 48    "https://heilancoos.github.io/research/2025/12/16/kubernetes.html#unauthenticated-api-access"
 49]
 50risk_score = 47
 51rule_id = "a337c3f8-e264-4eb4-9998-22669ca52791"
 52severity = "medium"
 53tags = [
 54  "Data Source: Kubernetes",
 55  "Domain: Kubernetes",
 56  "Use Case: Threat Detection",
 57  "Tactic: Discovery",
 58  "Resources: Investigation Guide",
 59]
 60timestamp_override = "event.ingested"
 61type = "esql"
 62query = '''
 63from logs-kubernetes.audit_logs-* metadata _id, _index, _version
 64| where kubernetes.audit.stage == "ResponseComplete" and kubernetes.audit.verb in ("get", "list", "watch", "create", "update", "patch")
 65| stats
 66  Esql.document_count = count(),
 67  Esql.kubernetes_audit_annotations_authorization_k8s_io_decision_count_distinct = count_distinct(`kubernetes.audit.annotations.authorization_k8s_io/decision`),
 68  Esql.kubernetes_audit_verb_count_distinct = count_distinct(kubernetes.audit.verb),
 69  Esql.kubernetes_audit_requestURI_count_distinct = count_distinct(kubernetes.audit.requestURI),
 70  Esql.kubernetes_audit_objectRef_resource_count_distinct = count_distinct(kubernetes.audit.objectRef.resource),
 71  
 72  Esql.kubernetes_audit_responseStatus_message_values = values(kubernetes.audit.responseStatus.message),
 73  Esql.kubernetes_audit_verb_values = values(kubernetes.audit.verb),
 74  Esql.kubernetes_audit_responseStatus_code_values = values(kubernetes.audit.responseStatus.code),
 75  Esql.kubernetes_audit_objectRef_resource_values = values(kubernetes.audit.objectRef.resource),
 76  Esql.kubernetes_audit_objectRef_namespace_values = values(kubernetes.audit.objectRef.namespace),
 77  Esql.kubernetes_audit_user_username_values = values(kubernetes.audit.user.username),
 78  Esql.kubernetes_audit_user_groups_values = values(kubernetes.audit.user.groups),
 79  Esql.kubernetes_audit_requestURI_values = values(kubernetes.audit.requestURI),
 80  Esql.kubernetes_audit_userAgent_values = values(kubernetes.audit.userAgent),
 81  Esql.data_stream_namespace_values = values(data_stream.namespace)
 82  
 83  by kubernetes.audit.user.username, kubernetes.audit.sourceIPs
 84| where
 85  Esql.kubernetes_audit_annotations_authorization_k8s_io_decision_count_distinct == 2 and
 86  Esql.kubernetes_audit_requestURI_count_distinct > 5 and
 87  Esql.kubernetes_audit_objectRef_resource_count_distinct > 3 and
 88  Esql.document_count < 75
 89| keep Esql.*, kubernetes.audit.user.username, kubernetes.audit.sourceIPs
 90'''
 91
 92[[rule.threat]]
 93framework = "MITRE ATT&CK"
 94
 95[[rule.threat.technique]]
 96id = "T1613"
 97name = "Container and Resource Discovery"
 98reference = "https://attack.mitre.org/techniques/T1613/"
 99
100[rule.threat.tactic]
101id = "TA0007"
102name = "Discovery"
103reference = "https://attack.mitre.org/tactics/TA0007/"

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 Potential Endpoint Permission Enumeration Attempt Detected

Detects a single Kubernetes identity from one IP issuing a burst of API calls across many resources and URLs with a mix of allowed and denied outcomes, consistent with automated RBAC probing rather than normal operations. This matters because attackers use it to map what they can access and identify high-value objects (secrets, pods, nodes) before escalation or lateral movement. A common pattern is running a script that iterates list/get/watch on dozens of API endpoints until it finds ones that return data.

Possible investigation steps

  • Expand the timeline around the alert for the same identity and source to reconstruct the full API-call sequence and identify which resource types returned successful data, prioritizing secrets, configmaps, nodes, pods, and RBAC objects.
  • Determine whether the source IP maps to a cluster node, pod egress/NAT, VPN, or an external host using infrastructure and network telemetry, and confirm it matches expected administrative or automation origins.
  • Validate whether the acting identity is a human user, service account, or external auth integration and review recent sign-ins/token issuance and current RBAC bindings for unexpected or overly broad access.
  • Hunt for follow-on actions from the same identity or IP that indicate escalation or execution, such as modifying role bindings, creating privileged pods, accessing secret data, or initiating exec/port-forward operations.
  • If the activity is not clearly legitimate, contain by rotating or disabling the credential and tightening permissions, then search for the same enumeration behavior across other identities and sources to scope impact.

False positive analysis

  • A cluster administrator or platform engineer using kubectl from a single workstation/VPN IP to troubleshoot RBAC issues may rapidly test get/list/watch across multiple resources and endpoints, producing a mix of allowed and forbidden responses within a short window.
  • A newly deployed or updated in-cluster component using a service account may probe several Kubernetes API resources during initialization or capability detection and encounter intermittent authorization denials due to incomplete RBAC bindings, generating diverse requestURIs/resources with both success and failure outcomes.

Response and remediation

  • Quarantine the actor by disabling the implicated user or service account (revoke kubeconfig/token and delete associated Secrets for service-account tokens) and, if the source IP is external, block it at the API server ingress/load balancer while preserving access for known admin networks.
  • Eradicate the access path by rotating any credentials the identity could have used (OIDC refresh tokens, client certs, static kubeconfigs) and removing unexpected RBAC RoleBindings/ClusterRoleBindings or groups that grant broad read access discovered during review.
  • Validate impact and recover by reviewing what endpoints returned successful data during the burst (especially secrets, configmaps, nodes, pods, and RBAC objects), rotating any exposed application secrets, and restarting affected workloads after credential updates.
  • Escalate immediately to incident response if the same identity subsequently creates/patches RBAC bindings, deploys privileged pods/daemonsets, performs exec/port-forward, or accesses secret data across multiple namespaces.
  • Harden by enforcing least-privilege RBAC for humans and service accounts, segmenting API access with network controls (private endpoint/VPN allowlists), and enabling short-lived tokens with regular rotation plus alerting on repeated mixed allow/deny probing across many resources.

References

Related rules

to-top