AWS EKS Multi-Resource Discovery
Adversaries who land credentials in a cluster or abuse an over-privileged token, often map the environment before exfiltration or privilege escalation. Rapid get/list traffic across distinct API resource kinds that answer those questions (namespaces, workloads, roles, cluster-wide roles) is a common setup and orientation pattern for both interactive attackers and automated recon scripts. This rule detects cross-resource bursts from a single client fingerprint within a one-minute bucket which may represent reconnaissance.
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/20"
8
9[rule]
10author = ["Elastic"]
11description = """
12Adversaries who land credentials in a cluster or abuse an over-privileged token, often map the environment before
13exfiltration or privilege escalation. Rapid get/list traffic across distinct API resource kinds that answer those
14questions (namespaces, workloads, roles, cluster-wide roles) is a common setup and orientation pattern for both
15interactive attackers and automated recon scripts. This rule detects cross-resource bursts from a single client
16fingerprint within a one-minute bucket which may represent reconnaissance.
17"""
18from = "now-11m"
19language = "esql"
20license = "Elastic License v2"
21name = "AWS EKS Multi-Resource Discovery"
22note = """## Triage and analysis
23
24### Investigating AWS EKS Multi-Resource Discovery
25The rule groups Kubernetes audit `get`/`list` events on namespaces, pods, roles, and clusterroles into one-minute windows
26per `user.name`, `source.ip`, `user_agent.original`, and flags windows where three or more distinct resource types appear.
27That combination is consistent with someone sketching cluster layout and privilege structure rather than touching a single
28resource type. **Allowed and denied** authorizations are both included: failures still signal probing and validate which
29object types the caller attempted to reach.
30
31### Possible investigation steps
32
33- Pivot on `Esql.time_interval` and the same identity or IP in raw audit logs to see ordering (e.g. namespaces first,
34 then roles, then pods) and whether calls succeeded.
35- Review `Esql.decisions` and namespaces touched; correlate with RBAC for that identity to see if scope matches a
36 known job or breaks least-privilege expectations.
37- Hunt for follow-on activity: secret/configmap reads, rolebinding changes, pod exec, anonymous or unusual user agents.
38- Baseline automation: CI, GitOps, and some monitoring agents can read several resource types during sync; exclude
39 known service accounts or source networks if noisy.
40
41### False positive analysis
42
43- Platform operators or runbooks that reconcile RBAC and workload state may legitimately span these resource types in
44 a short window; tune by user, IP allowlist, or user agent when documented.
45- Some installers briefly query namespaces, pods, and roles during upgrades—correlate with change windows.
46
47### Response and remediation
48
49- If malicious, revoke or rotate the implicated credentials, review and tighten RBAC, and inspect for data access or
50 persistence established after the burst."""
51references = ["https://microsoft.github.io/Threat-Matrix-for-Kubernetes/"]
52risk_score = 47
53rule_id = "67ff2b08-37af-53ce-a19e-00acca8515e0"
54setup = """This rule reads EKS control-plane audit logs collected by the AWS integration
55into `logs-aws.eks_audit-*`, where the AWS EKS audit ingest
56pipelines normalize each audit record under `aws.eks.audit.*`.
57
58Enable the `audit` control-plane log type on the EKS cluster, send its
59CloudWatch log group through the AWS integration, and confirm events carry
60`data_stream.dataset: aws.eks_audit` and
61`cloud.provider: aws` before enabling this rule.
62"""
63severity = "medium"
64tags = [
65 "Domain: Cloud",
66 "Domain: Containers",
67 "Platform: AWS",
68 "Platform: Kubernetes",
69 "Data Source: AWS",
70 "Data Source: Amazon Web Services",
71 "Data Source: Kubernetes API Server Audit Logs",
72 "Service: AWS EKS",
73 "Use Case: Threat Detection",
74 "Tactic: Discovery",
75 "Rule Type: ES|QL",
76 "Resources: Investigation Guide",
77 "Profile: Beta",
78]
79timestamp_override = "event.ingested"
80type = "esql"
81
82query = '''
83from logs-aws.eks_audit-* metadata _id, _index, _version
84| eval Esql.time_interval = date_trunc(1 minute, @timestamp)
85| where data_stream.dataset == "aws.eks_audit"
86 and event.action in ("get", "list")
87 and aws.eks.audit.objectRef.resource in ("namespaces", "nodes", "pods", "roles", "configmaps", "serviceaccounts", "clusterroles", "clusterrolebindings", "rolebindings")
88 and source.ip is not null and user.name IS NOT NULL
89 and not to_string(source.ip) in ("127.0.0.1", "::1")
90 and not user.name rlike """(system:serviceaccount:kube-system:|eks:|system:kube-|arn:aws:sts::.*:assumed-role/AWSServiceRoleForAmazonEKS/).*"""
91 and not aws.eks.audit.user.username in ("system:serviceaccount:flux-system:kustomize-controller", "system:serviceaccount:flux-system:helm-controller", "system:serviceaccount:flux-system:source-controller", "system:serviceaccount:security:trivy-operator")
92| stats
93 Esql.unique_resources = count_distinct(aws.eks.audit.objectRef.resource),
94 Esql.enumerated_resources = values(aws.eks.audit.objectRef.resource),
95 Esql.enumerated_namespaces = values(aws.eks.audit.objectRef.namespace),
96 Esql.decisions = values(`aws.eks.audit.annotations.authorization_k8s_io/decision`)
97 by user.name, aws.eks.audit.user.username, source.ip, user_agent.original, Esql.time_interval
98| where Esql.unique_resources >= 3
99| keep Esql.*, aws.eks.audit.user.username, user.name, source.ip, user_agent.original
100'''
101
102
103[[rule.threat]]
104framework = "MITRE ATT&CK"
105[[rule.threat.technique]]
106id = "T1613"
107name = "Container and Resource Discovery"
108reference = "https://attack.mitre.org/techniques/T1613/"
109
110
111[rule.threat.tactic]
112id = "TA0007"
113name = "Discovery"
114reference = "https://attack.mitre.org/tactics/TA0007/"
Triage and analysis
Investigating AWS EKS Multi-Resource Discovery
The rule groups Kubernetes audit get/list events on namespaces, pods, roles, and clusterroles into one-minute windows
per user.name, source.ip, user_agent.original, and flags windows where three or more distinct resource types appear.
That combination is consistent with someone sketching cluster layout and privilege structure rather than touching a single
resource type. Allowed and denied authorizations are both included: failures still signal probing and validate which
object types the caller attempted to reach.
Possible investigation steps
- Pivot on
Esql.time_intervaland the same identity or IP in raw audit logs to see ordering (e.g. namespaces first, then roles, then pods) and whether calls succeeded. - Review
Esql.decisionsand namespaces touched; correlate with RBAC for that identity to see if scope matches a known job or breaks least-privilege expectations. - Hunt for follow-on activity: secret/configmap reads, rolebinding changes, pod exec, anonymous or unusual user agents.
- Baseline automation: CI, GitOps, and some monitoring agents can read several resource types during sync; exclude known service accounts or source networks if noisy.
False positive analysis
- Platform operators or runbooks that reconcile RBAC and workload state may legitimately span these resource types in a short window; tune by user, IP allowlist, or user agent when documented.
- Some installers briefly query namespaces, pods, and roles during upgrades—correlate with change windows.
Response and remediation
- If malicious, revoke or rotate the implicated credentials, review and tighten RBAC, and inspect for data access or persistence established after the burst.
References
Related rules
- AWS EKS Potential Endpoint Permission Enumeration Attempt Detected
- AWS EKS Potential Endpoint Permission Enumeration Attempt by Anonymous User Detected
- AWS EKS Forbidden Request from Unusual User Agent
- AWS EKS Pod Exec Potential Reverse Shell
- AWS EKS Pod Exec with Curl or Wget to HTTPS