Ensure All Namespaces Have Network Policies Defined
More Info:
Without NetworkPolicy objects, all pods can communicate freely, enabling lateral movement. Install a NetworkPolicy-capable provider such as Calico and define policies for every namespace.
Risk Level
High
Address
Security
Compliance Standards
- CIS OKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Confirm current CNI and NetworkPolicy support
- On any machine with kubectl access:
kubectl -n kube-system get pods -o widekubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}' ; echo
- Review CNI pods (e.g.,
flannel,calico-node,cilium-...). If only flannel (or another non–NetworkPolicy-capable CNI) is present, plan to deploy a NetworkPolicy-capable provider (for example, Calico in “Calico + flannel” mode) following its official documentation before proceeding with policy design.
- On any machine with kubectl access:
-
Inventory namespaces and existing NetworkPolicies
- On any machine with kubectl access:
kubectl get nskubectl get networkpolicy --all-namespaces
- Identify namespaces without any NetworkPolicy:
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{" "}{end}' | tr ' ' '\n' | while read ns; do[ -z "$ns" ] && continuecount=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')echo "$ns: $count"done
- List all namespaces where the count is
0; these are in scope for remediation.
- On any machine with kubectl access:
-
Classify each namespace’s intended traffic model
- For each namespace (especially those with
0policies), gather workload info:kubectl get deploy,sts,ds,svc,po -n <namespace> - With the application owners, decide for each namespace:
- Which external CIDRs or namespaces may reach its pods (ingress).
- Which destinations (namespaces, services, or CIDRs) its pods must contact (egress).
- Whether intra-namespace pod-to-pod traffic should be allowed by default or restricted.
- For each namespace (especially those with
-
Design and apply baseline NetworkPolicies per namespace
- For each namespace lacking policies, create at least a minimal, reviewed policy manifest. Examples to adapt (save and edit before applying):
- Default deny all ingress/egress (tightest posture):
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: default-deny-allnamespace: <namespace>spec:podSelector: {}policyTypes:- Ingress- Egress
- Allow intra-namespace traffic but deny cross-namespace by default:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: allow-same-namespacenamespace: <namespace>spec:podSelector: {}policyTypes:- Ingress- Egressingress:- from:- podSelector: {}egress:- to:- podSelector: {}
- Default deny all ingress/egress (tightest posture):
- Apply with kubectl from any machine with kubectl access:
kubectl apply -f <policy-file>.yaml
- Add additional, narrower policies (per app labels) as needed to explicitly permit required ingress/egress.
- For each namespace lacking policies, create at least a minimal, reviewed policy manifest. Examples to adapt (save and edit before applying):
-
Functionally validate impact with test pods
- In at least one hardened namespace, run a temporary debug pod:
kubectl run netpol-test -n <namespace> --image=busybox:1.36 --restart=Never --command -- sleep 3600
- From that pod, test expected/blocked connectivity (adjust hostnames/IPs):
kubectl exec -n <namespace> netpol-test -- wget -qO- http://<service-or-ip> || echo "blocked or error"
- Confirm results align with the designed policy (required paths work, disallowed paths fail). Adjust NetworkPolicies iteratively if necessary.
- In at least one hardened namespace, run a temporary debug pod:
-
Re-verify cluster-wide compliance
- After policies are in place and validated, re-run evidence collection from any kubectl-capable machine:
kubectl get networkpolicy --all-namespaceskubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{" "}{end}' | tr ' ' '\n' | while read ns; do[ -z "$ns" ] && continuecount=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')echo "$ns: $count"done
- Confirm every non-system namespace has at least one intentional, documented NetworkPolicy and that a NetworkPolicy-capable CNI is deployed and healthy.
- After policies are in place and validated, re-run evidence collection from any kubectl-capable machine:
Using kubectl
Using kubectl
Run these commands from any machine with kubectl access.
- List all namespaces and see which have zero NetworkPolicies:
kubectl get ns --no-headers | awk '{print $1}' | while read ns; do
count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
echo "$ns $count"
done
What indicates a problem: Any namespace that shows 0 means there is no NetworkPolicy at all in that namespace, so pod-to-pod traffic there is completely unrestricted at the Kubernetes layer.
- View namespaces with and without NetworkPolicies in a more visual way:
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
echo "Namespace: $ns"
kubectl get networkpolicy -n "$ns"
echo "----"
done
What indicates a problem:
No resources found in <namespace> namespace.→ that namespace has no NetworkPolicies.- Namespaces that only have very permissive policies (for example, a policy that selects all pods and allows all ingress and egress from/to all namespaces/CIDRs) may be effectively equivalent to having no policy and should be reviewed by a human.
- Check which CNI plugin is running on the nodes (to confirm NetworkPolicy support):
kubectl get pods -n kube-system -o wide | egrep -i 'calico|flannel|cilium|weave|ovn|antrea'
What indicates a problem:
- If you only see
flannel-related pods (for example,kube-flannel-ds-*) and no NetworkPolicy-capable CNI such ascalico,cilium,antrea,weave-net, etc., then NetworkPolicy objects will not be enforced even if they exist.
- Inspect the details of existing NetworkPolicies in a specific namespace (replace
NAMESPACEas needed):
kubectl get networkpolicy -n NAMESPACE -o yaml
What indicates a problem:
- Policies that have
podSelector: {}and allow all ingress/egress from everywhere (e.g.,from: []orto: []or broadipBlockranges) can indicate a configuration that does not meaningfully restrict traffic and should be assessed manually.
Automation
#!/usr/bin/env bash
# Report namespaces without any NetworkPolicy objects
# Run on: any machine with kubectl access and KUBECONFIG set
set -euo pipefail
echo "== Cluster NetworkPolicy capability check =="
# 1) Check if NetworkPolicy CRD is usable (some CNIs ignore it even if API exists)
echo
echo "-> Verifying that the NetworkPolicy API is available..."
if ! kubectl api-resources --api-group=networking.k8s.io | grep -q "^networkpolicies"; then
echo "WARNING: networking.k8s.io/v1 NetworkPolicy API not available."
echo "This usually means no NetworkPolicy-capable CNI is installed."
echo "Namespaces cannot be protected with NetworkPolicy until this is addressed."
else
echo "OK: networking.k8s.io/v1 NetworkPolicy API is available."
fi
# 2) List all namespaces and count NetworkPolicy objects in each
echo
echo "== Per-namespace NetworkPolicy counts =="
echo "NAMESPACE,NETWORKPOLICY_COUNT"
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
| while read -r ns; do
count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
echo "${ns},${count}"
done
# 3) Highlight namespaces with zero NetworkPolicies
echo
echo "== Namespaces with ZERO NetworkPolicies (attention required) =="
zero_ns_found=false
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
| while read -r ns; do
count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
if [ "$count" -eq 0 ]; then
zero_ns_found=true
echo "$ns"
fi
done
echo
echo "== Detail: NetworkPolicies per namespace =="
kubectl get networkpolicy --all-namespaces
cat <<'EOF'
How to interpret this output
----------------------------
1) "NetworkPolicy API not available" warning:
- Indicates the cluster is likely using a CNI (such as plain flannel) that
does NOT enforce NetworkPolicy. In this case, adding NetworkPolicy
objects will NOT provide isolation until a NetworkPolicy-capable CNI
(e.g., Calico with flannel) is installed and configured.
2) Per-namespace counts:
- Any namespace listed with NETWORKPOLICY_COUNT=0 has no NetworkPolicy
objects defined. Those namespaces allow unrestricted pod-to-pod traffic
(subject only to node/network-level controls), which is the condition
this CIS control flags.
3) "Namespaces with ZERO NetworkPolicies":
- This is the primary problem list. Each namespace shown here needs a
design decision:
* either define one or more NetworkPolicy objects to restrict traffic,
* or explicitly accept the risk and document the exception.
4) "NetworkPolicies per namespace" detailed list:
- Use this to review existing policies for correctness and coverage. Having
at least one NetworkPolicy in a namespace does not guarantee that all
traffic is restricted; it only indicates that some policy exists and the
namespace is not fully open by default.
EOF