Azure Enable Audit Logs - Security Rule
More Info:
Enable auditing on the Kubernetes API Server and set the desired audit log path.
Risk Level
Medium
Address
Security
Compliance Standards
- APRA CPS 234 (Australia)
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS AKS
- CIS Critical Security Controls v8
- CMMC 2.0
- CSA Cloud Controls Matrix v4
- DPDPA
- Digital Operational Resilience Act (EU)
- Essential 8
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- MITRE ATT&CK (Cloud)
- NIS2 Directive
- NIST SP 800-171
- NYDFS 23 NYCRR 500
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify the AKS cluster and resource group
- On any machine with Azure CLI access:
az aks list -o table
- Note the
name(e.g.,myAKSCluster) andresourceGroup(e.g.,myResourceGroup) for the target cluster. - Confirm you are using the AKS resource group (not the
MC_...node resource group).
- On any machine with Azure CLI access:
-
List existing diagnostic settings on the AKS resource
- On any machine with Azure CLI access:
az monitor diagnostic-settings list \--resource $(az aks show -g myResourceGroup -n myAKSCluster --query id -o tsv)
- Review output for any diagnostic setting that includes
kube-auditandkube-audit-adminunderlogs[].category.
- On any machine with Azure CLI access:
-
Verify that kube-audit and kube-audit-admin logs are enabled and flowing to a Log Analytics workspace
- Still on a machine with Azure CLI:
az monitor diagnostic-settings show \--name myAKSClusterLogs \--resource $(az aks show -g myResourceGroup -n myAKSCluster --query id -o tsv)
- Confirm:
logs[].categorycontainskube-auditandkube-audit-admin.- Their
enabledfield istrue. workspaceId(orworkspaceId-equivalent property) is present underworkspaceIdorworkspace/logAnalyticsDestinationType, indicating “Send to Log Analytics” is configured.
- Still on a machine with Azure CLI:
-
If audit logs are missing or disabled, configure diagnostic settings in the Azure portal
- In the Azure portal:
- Open the AKS cluster’s resource group (e.g.,
myResourceGroup), not theMC_...group. - Select your AKS cluster resource (e.g.,
myAKSCluster). - In the left pane, choose Diagnostic settings.
- Click + Add diagnostic setting (or edit an existing setting).
- Name it (e.g.,
myAKSClusterLogs), select Send to Log Analytics workspace, and choose/create a workspace. - Under Logs, enable at minimum
kube-auditandkube-audit-admin(optionally alsokube-apiserver,kube-controller-manager,kube-scheduler), then Save.
- Open the AKS cluster’s resource group (e.g.,
- In the Azure portal:
-
Validate that new diagnostic settings are active
- After saving in the portal, confirm via CLI:
az monitor diagnostic-settings show \--name myAKSClusterLogs \--resource $(az aks show -g myResourceGroup -n myAKSCluster --query id -o tsv)
- Ensure
enabled: trueforkube-auditandkube-audit-adminand that the Log Analytics workspace reference is present.
- After saving in the portal, confirm via CLI:
-
Optionally confirm logs are being ingested in Log Analytics
- In the Azure portal, open the selected Log Analytics workspace → Logs and run a simple query such as:
AzureDiagnostics| where Category in ("kube-audit", "kube-audit-admin")| take 10
- Verify that recent records are present, indicating that API server audit logs are enabled and collected.
- In the Azure portal, open the selected Log Analytics workspace → Logs and run a simple query such as:
Using kubectl
kubectl cannot be used to enable or configure API server audit logging for this finding, because it is managed as an AKS diagnostic setting in the Azure portal, not via Kubernetes API objects. To remediate, follow the Azure Portal configuration steps described in the Manual Steps section.
Automation
#!/usr/bin/env bash
# Purpose: Report AKS audit log diagnostic settings across all managed clusters in a subscription.
# Runs on: any machine with Azure CLI access to the target subscription.
set -euo pipefail
SUBSCRIPTION_ID="<PUT-SUBSCRIPTION-ID-HERE>"
# Set subscription
az account set --subscription "${SUBSCRIPTION_ID}"
echo "Listing AKS clusters and their diagnostic settings (focus: kube-audit, kube-audit-admin)..."
echo
# Get all AKS cluster resource IDs in the subscription
AKS_IDS=$(az aks list --query '[].id' -o tsv)
if [ -z "${AKS_IDS}" ]; then
echo "No AKS clusters found in subscription ${SUBSCRIPTION_ID}"
exit 0
fi
for AKS_ID in ${AKS_IDS}; do
echo "=== Cluster: ${AKS_ID} ==="
# List diagnostic settings on the managed AKS resource
DIAG_JSON=$(az monitor diagnostic-settings list \
--resource "${AKS_ID}" \
-o json)
DIAG_COUNT=$(echo "${DIAG_JSON}" | jq 'length')
if [ "${DIAG_COUNT}" -eq 0 ]; then
echo " STATUS: PROBLEM - No diagnostic settings configured on this AKS cluster."
echo " EXPECTED: At least one diagnostic setting sending kube-audit and kube-audit-admin to Log Analytics."
echo
continue
fi
# For each diagnostic setting, inspect destinations and enabled logs
echo " Found ${DIAG_COUNT} diagnostic setting(s)."
echo
echo "${DIAG_JSON}" | jq -c '.[]' | while read -r ds; do
NAME=$(echo "${ds}" | jq -r '.name')
HAS_LAW=$(echo "${ds}" | jq -r '(.workspaceId != null) or ( .logs[]? | select(.category == "kube-audit" or .category == "kube-audit-admin") | .workspaceId? != null )' 2>/dev/null || echo "false")
echo " Diagnostic setting: ${NAME}"
# Show destinations
LAW_ID=$(echo "${ds}" | jq -r '.workspaceId // empty')
if [ -n "${LAW_ID}" ]; then
echo " Destination: Log Analytics workspace: ${LAW_ID}"
else
echo " Destination: No Log Analytics workspace at root of setting (may still have per-log workspaceId)."
fi
# Show enabled logs and whether kube-audit / kube-audit-admin are on
echo " Enabled log categories:"
echo "${ds}" | jq -r '.logs[] | select(.enabled==true) | " - \(.category)"'
HAS_KUBE_AUDIT=$(echo "${ds}" | jq '[.logs[]? | select(.enabled==true and .category=="kube-audit")] | length > 0')
HAS_KUBE_AUDIT_ADMIN=$(echo "${ds}" | jq '[.logs[]? | select(.enabled==true and .category=="kube-audit-admin")] | length > 0')
if [ "${HAS_KUBE_AUDIT}" != "true" ] || [ "${HAS_KUBE_AUDIT_ADMIN}" != "true" ] || [ "${HAS_LAW}" != "true" ]; then
echo " STATUS: PROBLEM"
echo " - kube-audit enabled: ${HAS_KUBE_AUDIT}"
echo " - kube-audit-admin enabled: ${HAS_KUBE_AUDIT_ADMIN}"
echo " - Sent to Log Analytics: ${HAS_LAW}"
echo " EXPECTED: kube-audit and kube-audit-admin enabled and sent to at least one Log Analytics workspace."
else
echo " STATUS: OK (kube-audit and kube-audit-admin enabled and sent to Log Analytics)."
fi
echo
done
echo
done
How to interpret output
-
Problem / non-compliant:
- Cluster shows:
STATUS: PROBLEM - No diagnostic settings configured on this AKS cluster. - Or any diagnostic setting shows:
kube-audit enabled: falseorkube-audit-admin enabled: falseorSent to Log Analytics: false.
- Cluster shows:
-
Compliant (per benchmark intent):
- At least one diagnostic setting for the AKS cluster reports:
STATUS: OK (kube-audit and kube-audit-admin enabled and sent to Log Analytics).
- At least one diagnostic setting for the AKS cluster reports: