Detection rules › Elastic
Azure AKS Suspicious Self-Subject Review by Service Account or Node Identity
Detects AKS (Azure Kubernetes Service) service account or node identities invoking self-subject access or rules review APIs. Non-human identities rarely enumerate their own permissions outside known controllers; this can indicate stolen tokens probing effective RBAC before privilege escalation.
Known false positives
- SelfSubjectAccessReview ("can I do X") is routinely issued by controllers checking their own permissions, so busy clusters generate benign volume from platform and add-on service accounts (for example kube-system managed add-ons such as azure-policy, Microsoft Defender, metrics-server, and konnectivity, plus operators like cert-manager, ingress controllers, and Argo/Flux). The rule ships with only the Azure Arc agent accounts (system:serviceaccount:azure-arc:*) excluded; that namespace exists only on Arc-enabled clusters and is one example, not a complete list. Treat the exclusion set as a per-environment denylist: baseline the calling service accounts and add validated platform/observability controllers after review. SelfSubjectRulesReview ("list everything I can do") is far rarer from non-human identities and higher signal. Admin impersonation workflows can also trigger this via an impersonated service account; validate the impersonating user.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Telemetry coverage
Rules detecting the same action
These rules filter on the same operation.
Rule body
[metadata]
creation_date = "2026/07/09"
integration = ["azure"]
maturity = "production"
updated_date = "2026/07/09"
[rule]
author = ["Elastic"]
description = """
Detects AKS (Azure Kubernetes Service) service account or node identities invoking self-subject access or rules review
APIs. Non-human identities rarely enumerate their own permissions outside known controllers; this can indicate stolen
tokens probing effective RBAC before privilege escalation.
"""
false_positives = [
"""
SelfSubjectAccessReview ("can I do X") is routinely issued by controllers checking their own permissions, so busy
clusters generate benign volume from platform and add-on service accounts (for example kube-system managed add-ons
such as azure-policy, Microsoft Defender, metrics-server, and konnectivity, plus operators like cert-manager,
ingress controllers, and Argo/Flux). The rule ships with only the Azure Arc agent accounts
(system:serviceaccount:azure-arc:*) excluded; that namespace exists only on Arc-enabled clusters and is one example,
not a complete list. Treat the exclusion set as a per-environment denylist: baseline the calling service accounts and
add validated platform/observability controllers after review. SelfSubjectRulesReview ("list everything I can do")
is far rarer from non-human identities and higher signal. Admin impersonation workflows can also trigger this via an
impersonated service account; validate the impersonating user.
""",
]
from = "now-9m"
index = ["logs-azure.platformlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure AKS Suspicious Self-Subject Review by Service Account or Node Identity"
note = """## Triage and analysis
### Investigating Azure AKS Suspicious Self-Subject Review by Service Account or Node Identity
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`. A `selfsubjectaccessreviews`
or `selfsubjectrulesreviews` create lets the caller enumerate its own effective permissions. Service account and node
identities issuing these reviews outside of known controllers can indicate a stolen token mapping out what it can reach.
### Possible investigation steps
- Confirm the acting identity in `azure.platformlogs.properties.log.user.username` and its groups in
`azure.platformlogs.properties.log.user.groups`, and whether that service account or node routinely performs
self-subject reviews. Check `azure.platformlogs.properties.log.impersonatedUser.username`: when populated, the review
was issued via impersonation (e.g. `kubectl auth can-i --as=<service account>`) and the real actor is the
impersonating user, not the service account in `user.username`.
- Review `azure.platformlogs.properties.log.objectRef.resource` (selfsubjectaccessreviews or selfsubjectrulesreviews)
and the `azure.platformlogs.properties.log.requestObject` to see what access was checked, plus the API path in
`azure.platformlogs.properties.log.requestURI`. Inspect `azure.platformlogs.properties.log.userAgent` to distinguish
interactive tooling (`kubectl`) from custom recon tooling or in-cluster SDKs.
- Evaluate the source in `azure.platformlogs.properties.log.sourceIPs`. Control-plane and in-cluster agents use loopback
(`127.0.0.1`/`::1`) or pod-network addresses (e.g. `10.244.0.0/16`); an external caller wielding a service account
token is more suspicious. Pivot on the source for related API activity, denied requests, exec sessions, or RBAC
changes from the same identity.
### False positive analysis
- Known observability or workflow controllers may issue self-subject reviews; extend exclusions for validated
identities. Azure Arc's agent service accounts (`system:serviceaccount:azure-arc:*`) legitimately submit these reviews
and are already excluded; add other validated platform controllers as they are baselined.
- Admin impersonation workflows can trigger this via an impersonated service account; validate the impersonating user in
`azure.platformlogs.properties.log.impersonatedUser.username`.
### Response and remediation
- If unauthorized, revoke the service account token and review the RBAC bindings granted to it.
- Correlate with any successful privileged actions the identity performed after the review.
- Collect kube-audit and identity artifacts per incident response procedures.
"""
references = [
"https://kubernetes.io/docs/reference/access-authn-authz/authorization/#checking-api-access",
"https://microsoft.github.io/Threat-Matrix-for-Kubernetes/",
"https://github.com/inguardians/peirates",
]
risk_score = 21
rule_id = "11afa743-5264-460b-9d0a-b687efd38a71"
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). Self-subject review
creates are recorded in both categories with the same `auditID`, so clusters that enable both categories may generate
two alerts per review.
"""
severity = "low"
tags = [
"Domain: Cloud",
"Domain: Kubernetes",
"Data Source: Azure",
"Data Source: Azure Platform Logs",
"Data Source: Kubernetes",
"Use Case: Threat Detection",
"Tactic: Discovery",
"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.verb:create and
azure.platformlogs.properties.log.objectRef.resource:(selfsubjectaccessreviews or selfsubjectrulesreviews) and
azure.platformlogs.properties.log.user.username:((system\:node\:* or system\:serviceaccount\:*) and
not system\:serviceaccount\:azure-arc\:*)
'''
[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.impersonatedUser.username",
"azure.platformlogs.properties.log.userAgent",
"azure.platformlogs.properties.log.sourceIPs",
"azure.platformlogs.properties.log.objectRef.resource",
"azure.platformlogs.properties.log.objectRef.namespace",
"azure.platformlogs.properties.log.requestURI",
"azure.platformlogs.properties.log.responseStatus.code",
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1069"
name = "Permission Groups Discovery"
reference = "https://attack.mitre.org/techniques/T1069/"
[[rule.threat.technique.subtechnique]]
id = "T1069.003"
name = "Cloud Groups"
reference = "https://attack.mitre.org/techniques/T1069/003/"
[[rule.threat.technique]]
id = "T1613"
name = "Container and Resource Discovery"
reference = "https://attack.mitre.org/techniques/T1613/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
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.verb:create and
azure.platformlogs.properties.log.objectRef.resource:(selfsubjectaccessreviews or selfsubjectrulesreviews) and
azure.platformlogs.properties.log.user.username:((system\:node\:* or system\:serviceaccount\:*) and
not system\:serviceaccount\:azure-arc\:*)
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
azure.platformlogs.properties.log.user.username | starts_with | system:serviceaccount:azure-arc: | excludes:azure.platformlogs.properties.log.user.username field:"azure.platformlogs.properties.log.user.username" value:"system:serviceaccount:azure-arc:" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.platformlogs.category | in |
| field:"azure.platformlogs.category" kind:in |
azure.platformlogs.properties.log.objectRef.resource | in |
| field:"azure.platformlogs.properties.log.objectRef.resource" kind:in |
azure.platformlogs.properties.log.stage | eq |
| field:"azure.platformlogs.properties.log.stage" kind:eq value:"ResponseComplete" |
azure.platformlogs.properties.log.user.username | wildcard |
| field:"azure.platformlogs.properties.log.user.username" kind:wildcard |
azure.platformlogs.properties.log.verb | eq |
| field:"azure.platformlogs.properties.log.verb" kind:eq value:"create" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.platformlogs" |
event.action | eq |
| field:"EventType" kind:eq value:"Microsoft.ContainerService/managedClusters/diagnosticLogs/Read" |