Detection rules › Elastic

Azure AKS Suspicious Self-Subject Review by Service Account or Node Identity

Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

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

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.

FieldKindExcluded valuesSearch
azure.platformlogs.properties.log.user.usernamestarts_withsystem: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.