Skip to main content

Ensure That All Namespaces Have Network Policies Defined

More Info:

Use network policies to isolate traffic in your cluster network.

Risk Level

Low

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS OKE
  • 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
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Manual Steps
  1. List all namespaces and identify those without NetworkPolicies

    • Run on: any machine with kubectl access
    kubectl get ns
    kubectl get networkpolicy --all-namespaces
    • Compare outputs to determine which namespaces have zero NetworkPolicy objects defined.
  2. Confirm whether the current CNI supports NetworkPolicy

    • Run on: any machine with kubectl access
    kubectl -n kube-system get pods -o wide
    kubectl -n kube-system get ds,deploy | grep -iE 'flannel|calico|cilium|weave|antrea'
    • If only flannel is present and no NetworkPolicy-capable CNI (such as Calico) is installed, note that NetworkPolicy objects will not be enforced until you deploy a compatible CNI.
  3. Decide the desired isolation posture per namespace

    • For each namespace without NetworkPolicies, classify it (e.g., “production app,” “shared services,” “monitoring,” “system”) and decide:
      • Whether it should default-deny ingress, egress, both, or neither.
      • Which namespaces/pods are allowed to communicate with it.
    • Document these decisions; they drive the NetworkPolicy design.
  4. Create or update baseline NetworkPolicies for target namespaces

    • Run on: any machine with kubectl access
    • For a conservative starting point, apply a default-deny ingress and egress policy in one non-critical namespace, then expand gradually:
    # Example default-deny for a single namespace (replace NAMESPACE with the target)
    kubectl apply -n NAMESPACE -f - <<'EOF'
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
    name: default-deny-all
    spec:
    podSelector: {}
    policyTypes:
    - Ingress
    - Egress
    EOF
    • Add additional, more permissive NetworkPolicies as needed to allow required traffic (between specific apps, from ingress controllers, to DNS, etc.), based on your design in step 3.
  5. If using flannel-only, plan and implement a NetworkPolicy-capable CNI

    • If step 2 showed you are using flannel without a NetworkPolicy-capable plugin, decide whether to:
      • Migrate to a CNI that supports NetworkPolicy (e.g., Calico), or
      • Accept the risk and use other controls (firewalls, service mesh, etc.) while documenting the exception.
    • To gather cluster details for planning:
    kubectl version --short
    kubectl get nodes -o wide
    kubectl -n kube-system get cm -o wide
    • Follow the chosen CNI provider’s official installation/migration guide; do not mix with Calico Enterprise if you intend to keep flannel, per the remediation note.
  6. Verify effective coverage and behavior

    • Run on: any machine with kubectl access
    # Verify every namespace now has at least one NetworkPolicy
    kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{" - "}{.metadata.uid}{"\n"}{end}' > /tmp/namespaces.txt
    kubectl get networkpolicy --all-namespaces -o wide

    # For a quick check of namespaces without policies:
    for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
    count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l || true)
    echo "$ns: $count"
    done
    • Optionally deploy simple test pods in selected namespaces and validate that allowed traffic works and disallowed traffic is blocked, adjusting NetworkPolicies iteratively as needed.
Using kubectl

Using kubectl

Run these commands from any machine with kubectl access.

  1. List all namespaces and which have at least one NetworkPolicy
kubectl get ns
kubectl get networkpolicy --all-namespaces

Problem indication: any namespace from kubectl get ns that does not appear in the NAMESPACE column of kubectl get networkpolicy --all-namespaces has no NetworkPolicy defined.

  1. Get a concise matrix of namespaces vs. NetworkPolicy count
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
echo -n "$ns: "
kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l
done

Problem indication: any namespace that shows 0 has no NetworkPolicy. You must decide whether that is acceptable (e.g., for system or intentionally open namespaces) or a gap that needs policies.

  1. Inspect NetworkPolicies in a specific namespace
# Replace default with the namespace you are reviewing
kubectl get networkpolicy -n default -o wide
kubectl describe networkpolicy -n default
kubectl get networkpolicy -n default -o yaml

Problem indication: policies that are overly permissive (e.g., podSelector: {} with no restrictive ingress/egress rules, or rules that allow 0.0.0.0/0 or namespaceSelector: {} combined with broad pod selectors) may not provide meaningful isolation, even though they exist.

  1. Check whether the cluster CNI supports NetworkPolicy
kubectl get pods -n kube-system -o wide
kubectl get daemonsets -n kube-system

Review the CNI-related pods/daemonsets (e.g., flannel, calico-node, cilium).

Problem indication:

  • Only flannel is present and no CNI known to enforce NetworkPolicy (such as Calico, Cilium, etc.) is installed. In this case, even if NetworkPolicy objects exist, they are not enforced.
  • If Calico Enterprise is present with flannel, note that the benchmark remediation warns Calico Enterprise does not support flannel.
  1. Focus on application namespaces

If you separate user workloads from system namespaces, list non-system namespaces and check them:

for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | grep -vE 'kube-system|kube-public|kube-node-lease'); do
echo "Namespace $ns"
kubectl get networkpolicy -n "$ns"
echo
done

Problem indication: any application/tenant namespace without at least one meaningful NetworkPolicy (ingress/egress) is likely a security gap and should be reviewed with application owners.

Automation
#!/usr/bin/env bash
#
# Report namespaces without any NetworkPolicy and summarize policy coverage.
# Run from any machine with kubectl access and kubeconfig context set.

set -euo pipefail

echo "Checking Kubernetes NetworkPolicy coverage..."
echo "Kubeconfig context: $(kubectl config current-context)"
echo

# 1) List all namespaces and whether they have at least one NetworkPolicy
echo "Per-namespace NetworkPolicy presence:"
echo "namespace,network_policies,count"

# Get all namespaces
namespaces=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')

no_np_namespaces=()

for ns in $namespaces; do
count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
echo "$ns,$([ "$count" -gt 0 ] && echo yes || echo no),$count"
if [ "$count" -eq 0 ]; then
no_np_namespaces+=("$ns")
fi
done

echo
echo "Namespaces with NO NetworkPolicy objects defined:"
if [ "${#no_np_namespaces[@]}" -eq 0 ]; then
echo " (none) - every namespace has at least one NetworkPolicy"
else
for ns in "${no_np_namespaces[@]}"; do
echo " - $ns"
done
fi

echo
echo "Summary:"
total_ns=$(echo "$namespaces" | wc -l | tr -d ' ')
total_no_np=${#no_np_namespaces[@]}
echo " Total namespaces: $total_ns"
echo " Namespaces without NetworkPolicy: $total_no_np"

# 2) Optional: quick view of NetworkPolicy counts by namespace, sorted
echo
echo "NetworkPolicy counts by namespace (sorted descending):"
kubectl get networkpolicy --all-namespaces --no-headers 2>/dev/null \
| awk '{counts[$1]++} END {for (ns in counts) print ns, counts[ns]}' \
| sort -k2 -nr || echo "No NetworkPolicy objects found in the cluster."

echo
echo "NOTE:"
echo "- Any namespace listed above under 'Namespaces with NO NetworkPolicy objects defined'"
echo " is considered a problem for this control and should be reviewed."
echo "- Having at least one NetworkPolicy in a namespace does NOT guarantee adequate"
echo " isolation; the actual rules must be reviewed manually."

How to interpret the output

  • Any namespace shown under:

    Namespaces with NO NetworkPolicy objects defined:

    is non-compliant with this control and needs manual review and a decision on whether to create NetworkPolicy objects there.

  • Namespaces with a network_policies,count of no,0 are the same problem cases, just in CSV form for export/aggregation.

Additional Reading: