Detection rules › Elastic
Azure AKS Service Account Token Created via TokenRequest API
Detects an identity minting a service account token via the AKS (Azure Kubernetes Service) TokenRequest API (serviceaccounts/token), excluding known AKS control-plane and platform identities. Adversaries request service account tokens from a compromised identity to impersonate a workload, move laterally, or escalate privileges within the cluster. Coverage includes workload service accounts (system:serviceaccount:*), so a compromised in-cluster token minting a token for another service account is not excluded.
Known false positives
- Controllers, CI/CD systems, and platform components legitimately request service account tokens. Baseline the requesting identities and exclude verified automation after review.
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.
- 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)
- Kubernetes Service Account Token Created via TokenRequest API (Elastic)
- New Kubernetes Service Account Created (Sigma)
- Service Account Created in Kube Namespace (Falco)
Rule body
[metadata]
creation_date = "2026/07/23"
integration = ["azure"]
maturity = "production"
updated_date = "2026/07/23"
[rule]
author = ["Elastic"]
description = """
Detects an identity minting a service account token via the AKS (Azure Kubernetes Service) TokenRequest API
(serviceaccounts/token), excluding known AKS control-plane and platform identities. Adversaries request service account
tokens from a compromised identity to impersonate a workload, move laterally, or escalate privileges within the cluster.
Coverage includes workload service accounts (system:serviceaccount:*), so a compromised in-cluster token minting a token
for another service account is not excluded.
"""
false_positives = [
"""
Controllers, CI/CD systems, and platform components legitimately request service account tokens. Baseline the
requesting identities and exclude verified automation after review.
""",
]
from = "now-9m"
index = ["logs-azure.platformlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure AKS Service Account Token Created via TokenRequest API"
note = """## Triage and analysis
### Investigating Azure AKS Service Account Token Created via TokenRequest API
AKS kube-audit events are carried under the flattened `azure.platformlogs.properties.log.*` subtree and share the ARM
operation `event.action: Microsoft.ContainerService/managedClusters/diagnosticLogs/Read`. The TokenRequest API
(`serviceaccounts/token`) mints a bound service account token. The kubelet (`system:node:*`) and the
kube-controller-manager (`aksService`) mint these tokens continuously for normal pod operation and are excluded; the
signal is a non-platform identity minting one. An attacker with rights over a service account can request a token to act
as that workload identity, reaching resources the compromised principal cannot.
### Possible investigation steps
- Identify the requesting identity in `azure.platformlogs.properties.log.user.username` (and its groups in
`azure.platformlogs.properties.log.user.groups`) and whether it should mint tokens. A workload service account
(`system:serviceaccount:<ns>:<sa>`) minting a token, or `masterclient` (the local cluster-admin cert), is the
higher-concern case.
- Inspect `azure.platformlogs.properties.log.userAgent` to distinguish interactive/expected tooling (`kubectl create
token`) from custom clients (for example `curl`), which is a stronger indicator of scripted abuse.
- Identify the target service account in `azure.platformlogs.properties.log.objectRef.name` /
`azure.platformlogs.properties.log.objectRef.namespace` and what RBAC that account holds; minting a token for a
higher-privileged service account is privilege escalation.
- Evaluate the source in `azure.platformlogs.properties.log.sourceIPs` and pivot on it for follow-on API calls made with
the minted token, and correlate with recent RBAC changes, secret reads, or exec sessions from the same identity.
### False positive analysis
- Controllers, CI/CD systems, and platform components legitimately request service account tokens (for example the
kube-controller-manager as `aksService`, which is excluded). Additional automation such as GitOps operators or CI
running `kubectl create token` may surface; baseline those identities and exclude the specific validated account
rather than re-broadening to all `system:*`, which would blind the rule to compromised workload service accounts.
### Response and remediation
- If unauthorized, revoke the minted token and the requesting identity's credentials, and review the RBAC that permitted
token creation.
- Audit actions performed with the target service account's identity after the request.
- Collect kube-audit and identity artifacts per incident response procedures.
"""
references = [
"https://kubernetes.io/docs/reference/kubernetes-api/authentication-resources/token-request-v1/",
"https://microsoft.github.io/Threat-Matrix-for-Kubernetes/",
"https://github.com/inguardians/peirates",
]
risk_score = 47
rule_id = "95db6791-8e88-47d0-81c9-531ff79c0e60"
setup = """
The Azure Fleet integration collecting AKS diagnostic logs forwarded through Event Hub into the `azure.platformlogs`
data stream is required for this rule. Enable either the `kube-audit` or the `kube-audit-admin` log category (Microsoft
recommends `kube-audit-admin` alone to reduce volume, as it only drops read-only get/list events). TokenRequest is a
mutating create recorded in both categories with the same `auditID`, so clusters that enable both categories may
generate two alerts per request.
"""
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Kubernetes",
"Data Source: Azure",
"Data Source: Azure Platform Logs",
"Data Source: Kubernetes",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:azure.platformlogs and
event.action:"Microsoft.ContainerService/managedClusters/diagnosticLogs/Read" and
azure.platformlogs.category:("kube-audit" or "kube-audit-admin") and
azure.platformlogs.properties.log.stage:"ResponseComplete" and
azure.platformlogs.properties.log.objectRef.resource:"serviceaccounts" and
azure.platformlogs.properties.log.objectRef.subresource:"token" and
azure.platformlogs.properties.log.verb:"create" and
azure.platformlogs.properties.log.responseStatus.code:("200" or "201") and
not azure.platformlogs.properties.log.user.username:(
system\:node\:* or "aksService" or "hcpService" or "readinessChecker" or
system\:serviceaccount\:kube-system\:*
)
'''
[rule.investigation_fields]
field_names = [
"@timestamp",
"event.action",
"azure.platformlogs.category",
"azure.platformlogs.properties.log.verb",
"azure.platformlogs.properties.log.user.username",
"azure.platformlogs.properties.log.user.groups",
"azure.platformlogs.properties.log.userAgent",
"azure.platformlogs.properties.log.sourceIPs",
"azure.platformlogs.properties.log.objectRef.namespace",
"azure.platformlogs.properties.log.objectRef.name",
"azure.platformlogs.properties.log.objectRef.subresource",
"azure.platformlogs.properties.log.requestURI",
"azure.platformlogs.properties.log.responseStatus.code",
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1528"
name = "Steal Application Access Token"
reference = "https://attack.mitre.org/techniques/T1528/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: query
data_stream.dataset:azure.platformlogs and
event.action:"Microsoft.ContainerService/managedClusters/diagnosticLogs/Read" and
azure.platformlogs.category:("kube-audit" or "kube-audit-admin") and
azure.platformlogs.properties.log.stage:"ResponseComplete" and
azure.platformlogs.properties.log.objectRef.resource:"serviceaccounts" and
azure.platformlogs.properties.log.objectRef.subresource:"token" and
azure.platformlogs.properties.log.verb:"create" and
azure.platformlogs.properties.log.responseStatus.code:("200" or "201") and
not azure.platformlogs.properties.log.user.username:(
system\:node\:* or "aksService" or "hcpService" or "readinessChecker" or
system\:serviceaccount\:kube-system\:*
)
Exclusions
The rule actively suppresses these predicates.
Indicators
These rows show field, operator, and value matches.