Microsoft Defender for Cloud · Azure Kubernetes Service
Diagnostic logs in Kubernetes services should be enabled
Written and reviewed by Emnode · Last reviewed
What does the recommendation "Diagnostic logs in Kubernetes services should be enabled" check?
Flags any AKS cluster that has no diagnostic setting routing its control-plane resource logs to a destination. AKS does not store these logs until you create a diagnostic setting, so the check confirms one exists and is forwarding categories such as kube-audit, kube-audit-admin, kube-apiserver and guard to a Log Analytics workspace, storage account or event hub. It looks only at whether a setting is present, not at which categories you enabled or whether anyone reviews the data. It also does not cover data-plane container logs (pod stdout and stderr): those flow through Container insights into ContainerLogV2 and are governed separately, so a cluster with Container insights on but no diagnostic setting still flags.
Why does "Diagnostic logs in Kubernetes services should be enabled" matter?
The AKS control plane is managed by Azure, so the API server audit trail is the only record of who called the Kubernetes API, what they changed and from where. Without a diagnostic setting that history is never captured: when an attacker creates a privileged pod, reads a secret or escalates via the API, you have no kube-audit record to reconstruct the incident, scope the blast radius or prove what was and was not touched. For regulated workloads that missing audit trail also fails the logging requirements in most frameworks, which can hold up an attestation or breach notification. Capturing the logs before an incident is the only option, because control-plane activity cannot be recovered after the fact.
How do I fix "Diagnostic logs in Kubernetes services should be enabled"?
- Create a Log Analytics workspace in the same subscription as the cluster, then add a diagnostic setting on the cluster routing the security-relevant categories to it: az monitor diagnostic-settings create --name AKS-Diagnostics --resource <aks-resource-id> --workspace <workspace-resource-id> --export-to-resource-specific true --logs '[{"category":"kube-audit-admin","enabled":true},{"category":"kube-apiserver","enabled":true},{"category":"guard","enabled":true}]'.
- Prefer kube-audit-admin over kube-audit and set --export-to-resource-specific true so audit data lands in the AKSAuditAdmin table; kube-audit-admin excludes high-volume get and list events and the resource-specific table can be set to the Basic logs tier, which keeps the security signal while minimising ingestion cost.
- To enforce this at scale, assign the built-in policy by exact display name rather than a hardcoded GUID, then attach a deployIfNotExists policy so new clusters self-remediate: pid=$(az policy definition list --query "[?displayName=='Resource logs in Azure Kubernetes Service should be enabled'].name" -o tsv); az policy assignment create --name aks-diag-logs --policy "$pid" --scope <subscription-or-management-group-scope>.
Remediation script · bash
# Turn on the security-relevant App Service logs and send them to a workspace.
WS=$(az monitor log-analytics workspace show \
-g central-logging -n estate-logs --query id -o tsv)
for id in $(az webapp list --query "[].id" -o tsv); do
has=$(az monitor diagnostic-settings list --resource "$id" \
--query "length(value)" -o tsv)
if [ "$has" = "0" ]; then
az monitor diagnostic-settings create \
--name to-log-analytics \
--resource "$id" \
--workspace "$WS" \
--logs '[{"category":"AppServiceHTTPLogs","enabled":true},
{"category":"AppServiceAuditLogs","enabled":true},
{"category":"AppServiceConsoleLogs","enabled":true}]'
echo "$(basename "$id"): diagnostic logging enabled to estate-logs"
fi
done
# Ratchet it shut: built-in policy adds the setting to any new App Service.
az policy assignment create \
--name deploy-appservice-diag \
--policy 0c6cd767-1a1d-484b-a897-68e398c03aeb \
--location uksouth \
--mi-system-assigned \
--scope "/subscriptions/00000000-0000-0000-0000-000000000000" Full walkthrough (console steps, edge cases and verification) in the lesson Turn on diagnostic logging for Azure resources.
Is "Diagnostic logs in Kubernetes services should be enabled" a false positive?
A short-lived cluster used purely for batch or CI work, with no internet-facing API server and torn down on a schedule, may not warrant control-plane log retention if its activity is already captured upstream (for example in the pipeline that creates and destroys it). In that case the flag is a deliberate, documented exception rather than a finding to remediate; exempt it through an Azure Policy exemption scoped to that resource group so the decision is auditable and does not silently apply to long-lived production clusters.
More Azure Kubernetes Service controls
- Azure Kubernetes Service clusters should have Defender profile enabled
- Azure Kubernetes Service clusters should have the Azure Policy add-on for Kubernetes installed
- Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)
- Container CPU and memory limits should be enforced
- Container images should be deployed from trusted registries only
- Container with privilege escalation should be avoided
- Containers sharing sensitive host namespaces should be avoided
- Immutable (read-only) root filesystem should be enforced for containers
- Kubernetes API server should be configured with restricted access
- Kubernetes clusters should be accessible only over HTTPS
- Kubernetes clusters should disable automounting API credentials
- Kubernetes clusters should not use the default namespace