Skip to main content
emnode
Compliance Medium severity MCSB PV-2

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"?

  1. 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.
  2. 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.
  3. 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.