AWS EKS 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/08/03"
  3integration = ["aws"]
  4maturity = "production"
  5min_stack_comments = "The AWS integration adds the aws.eks_audit data stream in package 8.9.0, which requires Kibana 9.6.0 or later."
  6min_stack_version = "9.6.0"
  7updated_date = "2026/10/21"
  8
  9[rule]
 10author = ["Elastic"]
 11description = """
 12This rule detects potential endpoint enumeration attempts by a single user and source IP address. By looking for a
 13combination of failed/successful API requests across multiple endpoints and a limited number of documents, this rule can
 14detect automated permission enumeration attempts. This behavior is uncommon for regular Kubernetes clusters.
 15"""
 16from = "now-6m"
 17language = "esql"
 18license = "Elastic License v2"
 19name = "AWS EKS Potential Endpoint Permission Enumeration Attempt Detected"
 20note = """## Triage and analysis
 21
 22> **Disclaimer**:
 23> 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.
 24
 25### Investigating AWS EKS Potential Endpoint Permission Enumeration Attempt Detected
 26Detects 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.
 27
 28### Possible investigation steps
 29
 30- 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.
 31- 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.
 32- 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.
 33- 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.
 34- 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.
 35
 36### False positive analysis
 37
 38- 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.
 39- 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.
 40
 41### Response and remediation
 42
 43- 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.
 44- 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.
 45- 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.
 46- 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.
 47- 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."""
 48references = ["https://heilancoos.github.io/research/2025/12/16/kubernetes.html#unauthenticated-api-access"]
 49risk_score = 47
 50rule_id = "64376548-53f9-53f3-869c-02c7d136b572"
 51setup = """This rule reads EKS control-plane audit logs collected by the AWS integration
 52into `logs-aws.eks_audit-*`, where the AWS EKS audit ingest
 53pipelines normalize each audit record under `aws.eks.audit.*`.
 54
 55Enable the `audit` control-plane log type on the EKS cluster, send its
 56CloudWatch log group through the AWS integration, and confirm events carry
 57`data_stream.dataset: aws.eks_audit` and
 58`cloud.provider: aws` before enabling this rule.
 59"""
 60severity = "medium"
 61tags = [
 62    "Domain: Cloud",
 63    "Domain: Containers",
 64    "Platform: AWS",
 65    "Platform: Kubernetes",
 66    "Data Source: AWS",
 67    "Data Source: Amazon Web Services",
 68    "Data Source: Kubernetes API Server Audit Logs",
 69    "Service: AWS EKS",
 70    "Use Case: Threat Detection",
 71    "Tactic: Discovery",
 72    "Rule Type: ES|QL",
 73    "Resources: Investigation Guide",
 74    "Profile: Beta",
 75]
 76timestamp_override = "event.ingested"
 77type = "esql"
 78
 79query = '''
 80from logs-aws.eks_audit-* metadata _id, _index, _version
 81| where aws.eks.audit.stage == "ResponseComplete" and aws.eks.audit.verb in ("get", "list", "watch", "create", "update", "patch")
 82| stats
 83  Esql.document_count = count(),
 84  Esql.kubernetes_audit_annotations_authorization_k8s_io_decision_count_distinct = count_distinct(`aws.eks.audit.annotations.authorization_k8s_io/decision`),
 85  Esql.kubernetes_audit_verb_count_distinct = count_distinct(aws.eks.audit.verb),
 86  Esql.kubernetes_audit_requestURI_count_distinct = count_distinct(aws.eks.audit.requestURI),
 87  Esql.kubernetes_audit_objectRef_resource_count_distinct = count_distinct(aws.eks.audit.objectRef.resource),
 88
 89  Esql.kubernetes_audit_responseStatus_message_values = values(aws.eks.audit.responseStatus.message),
 90  Esql.kubernetes_audit_verb_values = values(aws.eks.audit.verb),
 91  Esql.kubernetes_audit_responseStatus_code_values = values(aws.eks.audit.responseStatus.code),
 92  Esql.kubernetes_audit_objectRef_resource_values = values(aws.eks.audit.objectRef.resource),
 93  Esql.kubernetes_audit_objectRef_namespace_values = values(aws.eks.audit.objectRef.namespace),
 94  Esql.kubernetes_audit_user_username_values = values(aws.eks.audit.user.username),
 95  Esql.kubernetes_audit_user_groups_values = values(aws.eks.audit.user.groups),
 96  Esql.kubernetes_audit_requestURI_values = values(aws.eks.audit.requestURI),
 97  Esql.user_agent_original_values = values(user_agent.original),
 98  Esql.data_stream_namespace_values = values(data_stream.namespace)
 99
100  by aws.eks.audit.user.username, aws.eks.audit.sourceIPs
101| where
102  Esql.kubernetes_audit_annotations_authorization_k8s_io_decision_count_distinct == 2 and
103  Esql.kubernetes_audit_requestURI_count_distinct > 5 and
104  Esql.kubernetes_audit_objectRef_resource_count_distinct > 3 and
105  Esql.document_count < 75
106| keep Esql.*, aws.eks.audit.user.username, aws.eks.audit.sourceIPs
107'''
108
109
110[[rule.threat]]
111framework = "MITRE ATT&CK"
112[[rule.threat.technique]]
113id = "T1613"
114name = "Container and Resource Discovery"
115reference = "https://attack.mitre.org/techniques/T1613/"
116
117
118[rule.threat.tactic]
119id = "TA0007"
120name = "Discovery"
121reference = "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 AWS EKS 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