GKE API Request Failure Burst by User
Detects bursts of failed GKE API requests from a single user identity within a five-minute window. Repeated authorization failures across multiple actions can indicate credential stuffing, RBAC probing, or reconnaissance with stolen tokens.
Rule type: esql
Rule indices:
Rule Severity: medium
Risk Score: 47
Runs every: 5m
Searches indices from: now-11m
Maximum alerts per execution: 100
References:
- https://cloud.google.com/kubernetes-engine/docs/how-to/audit-logging
- https://attack.mitre.org/techniques/T1613/
Tags:
- Domain: Cloud
- Domain: Kubernetes
- Data Source: GCP
- Data Source: Google Cloud Platform
- Use Case: Threat Detection
- Tactic: Discovery
- Resources: Investigation Guide
Version: 1
Rule authors:
- Elastic
Rule license: Elastic License v2
The rule aggregates failed Kubernetes API calls per user.email, source IP, and user agent in five-minute buckets and
alerts when failures reach ten or more.
- Review
Esql.actionsandEsql.resourcesfor targeted API operations. - Validate whether the identity should exist and whether the source IP is expected.
- Hunt for later successful calls indicating privilege escalation.
- Misconfigured automation or CI jobs with stale credentials may generate bursts; exclude known service accounts.
The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule.
from logs-gcp.audit-* metadata _id, _index, _version
| eval Esql.time_interval = date_trunc(5 minutes, @timestamp)
| where data_stream.dataset == "gcp.audit"
and service.name == "k8s.io"
and event.outcome == "failure"
and event.type != "allowed"
and user.email is not null
and not to_string(user.email) rlike "(system:serviceaccount:|system:gke-spiffe-controller|system:kube-scheduler|system:node:).*"
| stats
Esql.unique_actions = count_distinct(event.action),
Esql.failures_count = count(*),
Esql.actions = values(event.action),
Esql.resources = values(orchestrator.resource.name)
by user.email, source.ip, user_agent.original, data_stream.namespace, Esql.time_interval
| where Esql.failures_count >= 10
| keep Esql.*, user.email, source.ip, user_agent.original, data_stream.namespace
Framework: MITRE ATT&CK
Tactic:
- Name: Discovery
- Id: TA0007
- Reference URL: https://attack.mitre.org/tactics/TA0007/
Technique:
- Name: Container and Resource Discovery
- Id: T1613
- Reference URL: https://attack.mitre.org/techniques/T1613/