Detection rules › Elastic
Kubernetes Service Account Token Created via TokenRequest API
Detects the creation of a Kubernetes service account token through the TokenRequest API by a non-system identity. The TokenRequest API allows users and workloads to programmatically generate short-lived tokens for any service account they have create permissions on, without accessing the filesystem or the mounted projected token. Attackers who have gained initial access to a cluster can abuse this API to mint tokens for more privileged service accounts, pivot to cloud provider resources via IRSA/workload identity, or generate long-lived tokens that persist beyond pod termination. Unlike mounted service account tokens which are detectable through file access monitoring, tokens created via the TokenRequest API leave no filesystem footprint, they are only visible in Kubernetes audit logs as a create verb on the serviceaccounts/token subresource. This rule excludes legitimate system components such as the kubelet, kube-controller-manager, and cloud provider managed identities (EKS, AKS, GKE) that routinely create tokens for pod lifecycle management.
Known false positives
- New automation, admission webhooks, or platform agents that legitimately call the TokenRequest API under a non-standard user string may require narrow exclusions by user.name or source IP.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Kubernetes | create-serviceaccounts-token: create serviceaccounts/token |
Rules detecting the same action
These rules filter on the same operation.
- Azure AKS Service Account Token Created via TokenRequest API (Elastic)
- Direct Interactive Kubernetes API Request by Unusual Utilities (Elastic)
- GKE Service Account Token Created via TokenRequest API (Elastic)
- K8s Serviceaccount Created (Falco)
- Kubernetes Long-Lived Service Account Token Created (Panther)
- New Kubernetes Service Account Created (Sigma)
- Service Account Created in Kube Namespace (Falco)
Rule body
[metadata]
creation_date = "2026/05/05"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/05/05"
[rule]
author = ["Elastic"]
description = """
Detects the creation of a Kubernetes service account token through the TokenRequest API by a non-system identity. The
TokenRequest API allows users and workloads to programmatically generate short-lived tokens for any service account
they have create permissions on, without accessing the filesystem or the mounted projected token. Attackers who have
gained initial access to a cluster can abuse this API to mint tokens for more privileged service accounts, pivot to
cloud provider resources via IRSA/workload identity, or generate long-lived tokens that persist beyond pod
termination. Unlike mounted service account tokens which are detectable through file access monitoring, tokens created
via the TokenRequest API leave no filesystem footprint, they are only visible in Kubernetes audit logs as a create
verb on the serviceaccounts/token subresource. This rule excludes legitimate system components such as the kubelet,
kube-controller-manager, and cloud provider managed identities (EKS, AKS, GKE) that routinely create tokens for pod
lifecycle management.
"""
false_positives = [
"""
New automation, admission webhooks, or platform agents that legitimately call the TokenRequest API under a
non-standard user string may require narrow exclusions by user.name or source IP.
""",
]
from = "now-6m"
index = ["logs-kubernetes.audit_logs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Kubernetes Service Account Token Created via TokenRequest API"
note = """## Triage and analysis
### Investigating Kubernetes Service Account Token Created via TokenRequest API
This alert indicates a successful `create` against the `serviceaccounts/token` subresource (TokenRequest API), which
issues a new service account token without a filesystem read. In EKS and other managed clusters, this can be abused to
mint tokens for more privileged service accounts (including IRSA-linked ones) and pivot to cloud APIs.
#### What to review first
- Actor and origin:
- `user.name` / `kubernetes.audit.user.username`
- `source.ip` / `kubernetes.audit.sourceIPs`
- `user_agent.original` / `kubernetes.audit.userAgent`
- For cloud identity, review `kubernetes.audit.user.extra.*` (e.g., `arn`, `principalId`).
- Targeted service account:
- `kubernetes.audit.objectRef.namespace` and `kubernetes.audit.objectRef.name`
- `kubernetes.audit.requestURI` (should resemble `/api/v1/namespaces/<ns>/serviceaccounts/<sa>/token`)
- Token issuance hints:
- `kubernetes.audit.annotations.authentication_kubernetes_io/issued-credential-id` (token JTI/issued credential id)
#### Scoping
- Identify which Role/ClusterRoleBindings grant the actor `create` on `serviceaccounts/token` in the affected namespace.
- Pivot on the same `user.name` and `source.ip` for follow-on secret reads, pod exec, RBAC changes, or cloud API calls.
### Response and remediation
- If unauthorized, remove/revert the RBAC permission that allows TokenRequest (`serviceaccounts/token`) and rotate the
affected service account credentials where applicable.
- For IRSA/workload identity cases, rotate/revoke the cloud role session pathways and review cloud audit logs for API
activity from the time window of the token mint.
"""
references = [
"https://kubernetes.io/docs/reference/kubernetes-api/authentication-resources/token-v1/",
"https://attack.mitre.org/techniques/T1552/007/",
]
risk_score = 47
rule_id = "4df91789-7859-4bc4-9c5a-6b56bfa81a8b"
severity = "medium"
tags = [
"Data Source: Kubernetes",
"Domain: Kubernetes",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:"kubernetes.audit_logs" and
kubernetes.audit.verb:"create" and
kubernetes.audit.objectRef.resource:"serviceaccounts" and
kubernetes.audit.objectRef.subresource:"token" and
user.name:(* and not
(system\:kube-controller-manager or
system\:kube-scheduler or
system\:node\:* or
system\:serviceaccount\:kube-system\:* or
eks\:* or
aksService or
aks-service or
masterclient or
nodeclient or
system\:serviceaccount\:gke-managed-system\:* or
system\:serviceaccount\:gke-connect\:* or
system\:serviceaccount\:anthos-identity-service\:* or
system\:gke-controller-manager or
system\:serviceaccount\:tigera-operator\:* or
system\:serviceaccount\:calico-system\:*))
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[rule.threat.technique.subtechnique]]
id = "T1552.007"
name = "Container API"
reference = "https://attack.mitre.org/techniques/T1552/007/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: query
data_stream.dataset:"kubernetes.audit_logs" and
kubernetes.audit.verb:"create" and
kubernetes.audit.objectRef.resource:"serviceaccounts" and
kubernetes.audit.objectRef.subresource:"token" and
user.name:(* and not
(system\:kube-controller-manager or
system\:kube-scheduler or
system\:node\:* or
system\:serviceaccount\:kube-system\:* or
eks\:* or
aksService or
aks-service or
masterclient or
nodeclient or
system\:serviceaccount\:gke-managed-system\:* or
system\:serviceaccount\:gke-connect\:* or
system\:serviceaccount\:anthos-identity-service\:* or
system\:gke-controller-manager or
system\:serviceaccount\:tigera-operator\:* or
system\:serviceaccount\:calico-system\:*))
Exclusions
The rule actively suppresses these predicates.
Indicators
These rows show field, operator, and value matches.