What it is
An AKS cluster whose networkProfile.networkPolicy is unset, so no network policy engine (Azure, Cilium, or Calico) is installed. Kubernetes is deny-nothing by default at the network layer: without an engine, every pod can open a connection to every other pod in the cluster, across namespaces, with no filter in between. Any NetworkPolicy manifests you apply are accepted by the API server and enforced by nobody.
Why it happens
Choosing an engine is an opt-in decision at cluster creation, and skipping it is the path of least resistance: the cluster works perfectly without one, nothing warns, and no workload fails. Teams that came from environments where the CNI enforced policy out of the box often assume AKS does too.
The failure mode is unusually quiet. kubectl apply on a NetworkPolicy succeeds, the object shows up in kubectl get networkpolicy, and it does nothing, because there is no engine watching those resources. A team can ship a whole folder of carefully-reviewed policies and pass an eyeball audit while the pod network stays wide open. Historically the choice was also locked in at creation; current AKS can enable Azure or Cilium policy on an existing cluster with az aks update, but older clusters may still need a rebuild, which keeps the setting frozen.
What it costs / blast radius
The blast radius is lateral movement. A flat pod network means one compromised workload, a vulnerable public-facing app, a poisoned image, a hijacked dependency, can directly reach every other pod: internal admin dashboards, in-cluster databases, metrics endpoints, and services that were never hardened because "nothing external can reach them." Namespaces provide zero network isolation on their own, so the boundary you think you have between teams or environments in a shared cluster does not exist at the network layer. Direct cost is nothing; the harm is that a single foothold scopes to the whole cluster instead of one workload. (Blast-radius assessment of Kubernetes and Azure behavior, not a measured statistic.)
See it
resource aks 'Microsoft.ContainerService/managedClusters@2024-05-01' = {
name: 'prod-aks'
location: location
// ...identity and agentPoolProfiles omitted for brevity
properties: {
dnsPrefix: 'prod-aks'
networkProfile: {
networkPlugin: 'azure'
// networkPolicy unset: no engine installed.
// Every pod can reach every other pod.
}
}
}resource aks 'Microsoft.ContainerService/managedClusters@2024-05-01' = {
name: 'prod-aks'
location: location
// ...identity and agentPoolProfiles omitted for brevity
properties: {
dnsPrefix: 'prod-aks'
networkProfile: {
networkPlugin: 'azure'
networkPolicy: 'azure' // or 'calico'; 'cilium' also requires networkDataplane: 'cilium'
// Existing clusters: 'az aks update --network-policy azure'
// works on current AKS; older clusters may require a rebuild.
}
}
}How StratoLens helps
StratoLens flags every AKS cluster running without a network policy engine, automatically and continuously, across all your subscriptions, so you find the flat networks before an incident maps them for you. It also shows when the setting changed, which is useful when a rebuilt cluster quietly dropped the engine the old one had.