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
- Kubernetes Potential Endpoint Permission Enumeration Attempt by Anonymous User Detected
- Kubernetes Denied Service Account Request via Unusual User Agent
- Kubernetes Suspicious Self-Subject Review via Unusual User Agent
- Direct Interactive Kubernetes API Request by Common Utilities
- Direct Interactive Kubernetes API Request by Unusual Utilities