Microsoft Defender for Cloud · Azure Kubernetes Service
Least privileged Linux capabilities should be enforced for containers
Written and reviewed by Emnode · Last reviewed
What does the recommendation "Least privileged Linux capabilities should be enforced for containers" check?
Flags AKS workloads whose pods do not drop their Linux capabilities to the least-privileged set. The Azure Policy add-on installs an OPA Gatekeeper constraint that inspects every container's securityContext.capabilities: it expects 'drop' to include ALL and permits only the capabilities listed in the policy's 'Allowed capabilities' parameter. Containers that quietly keep the default capability set, NET_RAW and CHOWN among them, or that add capabilities not on the allow-list, are reported. It governs only Linux capabilities. It does not check privileged mode, host namespace sharing, allowPrivilegeEscalation, read-only root filesystems or the runAsNonRoot setting, each of which is a separate recommendation, and it does not evaluate Windows containers.
Why does "Least privileged Linux capabilities should be enforced for containers" matter?
Linux capabilities are the slices of root power a container keeps even when it is not fully privileged. A container that holds NET_RAW can craft raw packets to spoof ARP or run man-in-the-middle attacks across the pod network; one that holds SYS_ADMIN or SYS_PTRACE gives an attacker who lands code execution a direct lever towards escaping onto the node. Most application containers need none of these. Leaving them in place widens the blast radius of any single compromised image: a foothold in one pod becomes lateral movement across the cluster and, potentially, the host. Enforcing least privilege caps that radius, so a breached workload behaves like an ordinary process rather than a near-root one, and keeps the cluster inside the pod-security baseline auditors expect.
How do I fix "Least privileged Linux capabilities should be enforced for containers"?
- Enable the Azure Policy add-on so Gatekeeper can evaluate the cluster: 'az aks enable-addons --addons azure-policy --resource-group <rg> --name <cluster>'. This deploys the azure-policy pods in kube-system and Gatekeeper in gatekeeper-system.
- Assign the built-in capabilities policy by its display name rather than a hardcoded GUID, setting Required drop capabilities to ALL: pid=$(az policy definition list --query "[?displayName=='Kubernetes cluster containers should only use allowed capabilities'].name" -o tsv); az policy assignment create --name aks-least-priv-caps --policy "$pid" --scope <cluster-resource-id> --params '{"requiredDropCapabilities":{"value":["ALL"]}}'. Start the assignment in audit mode, then move it to deny once workloads are clean.
- Fix the workloads themselves: add 'securityContext.capabilities.drop: ["ALL"]' to each container spec and add back only the capabilities the app genuinely needs (for example NET_BIND_SERVICE for a low port). Bake this into your Helm values or Bicep-deployed manifests so new deployments inherit the safe default.
Remediation script · bash
# 1. Turn on the Azure Policy add-on so Gatekeeper starts auditing the cluster.
az provider register --namespace Microsoft.PolicyInsights
az aks enable-addons --addons azure-policy \
--resource-group rg-prod --name aks-prod
# Confirm the policy and gatekeeper pods are running.
kubectl get pods -n kube-system -l app=azure-policy
kubectl get pods -n gatekeeper-system
# 2. Assign the built-in pod security baseline initiative in AUDIT first.
# Look the initiative up by its exact display name, never paste a GUID.
SCOPE=$(az aks show -g rg-prod -n aks-prod --query id -o tsv)
SETID=$(az policy set-definition list \
--query "[?displayName=='Kubernetes cluster pod security baseline standards for Linux-based workloads'].name" -o tsv)
az policy assignment create \
--name aks-pod-baseline \
--policy-set-definition "$SETID" \
--scope "$SCOPE" \
--params '{"effect":{"value":"audit"},"excludedNamespaces":{"value":["kube-system","gatekeeper-system","azure-arc"]}}'
# 3. Fix the workloads (in each pod spec, securityContext):
# privileged: false | runAsNonRoot: true | runAsUser: 1000
# allowPrivilegeEscalation: false | readOnlyRootFilesystem: true
# capabilities: { drop: ["ALL"] } and add back only what is needed.
# 4. Once audit is clean except for named exceptions, ENFORCE.
az policy assignment update --name aks-pod-baseline \
--set parameters.effect.value=deny Full walkthrough (console steps, edge cases and verification) in the lesson Enforce AKS pod security.
Is "Least privileged Linux capabilities should be enforced for containers" a false positive?
An ingress controller or service mesh sidecar that legitimately needs NET_BIND_SERVICE to bind privileged ports, or NET_ADMIN to programme network rules, will flag if that capability is not on the policy's Allowed capabilities list. This is a correct exception: scope a narrower policy assignment to that namespace and add only the required capability to the allow-list, keeping drop ALL in place, rather than exempting the cluster wholesale.
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
- Diagnostic logs in Kubernetes services should be enabled
- 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