Skip to main content

Ensure All Namespaces Have NetworkPolicies Defined

More Info:

Namespaces without NetworkPolicies allow unrestricted pod-to-pod traffic. Define policies to segment and restrict network flows.

Risk Level

High

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

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

    • Run on: any machine with kubectl access
    kubectl get ns
    kubectl get networkpolicies.networking.k8s.io --all-namespaces
    • Compare the two lists and note any namespaces that do not appear in the NetworkPolicy list.
  2. Confirm traffic requirements for each uncovered namespace

    • For each namespace without a NetworkPolicy, gather workload and usage info:
    kubectl get deploy,sts,ds,svc,po -n <namespace>
    • With application owners, determine:
      • Which pods/services must be reachable from outside the namespace (and from where).
      • Which pods can talk to which other pods within the namespace.
      • Any external (egress) destinations that are required.
  3. Decide enforcement strategy per namespace

    • For each namespace, choose an approach:
      • Strict isolation: deny all ingress/egress by default and explicitly allow required flows.
      • Ingress-only control: restrict which sources can reach pods, leave egress open.
      • Baseline: start with a “deny-all” + explicit allow for known critical paths, plan to refine later.
    • Confirm with stakeholders that introducing NetworkPolicies will not unexpectedly break known traffic paths.
  4. Draft and apply appropriate NetworkPolicy manifests

    • Create one or more YAML files per namespace (examples to adapt, do not apply blindly):
    • Baseline deny-all ingress/egress for the namespace:
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
      name: default-deny-all
      namespace: <namespace>
      spec:
      podSelector: {}
      policyTypes:
      - Ingress
      - Egress
    • Example: allow ingress only from same namespace:
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
      name: allow-namespace-internal
      namespace: <namespace>
      spec:
      podSelector: {}
      ingress:
      - from:
      - podSelector: {}
      policyTypes:
      - Ingress
    • Apply after review:
      kubectl apply -f <policy-file>.yaml
  5. Validate connectivity and adjust policies

    • After applying policies, verify application behavior (health checks, functional tests).
    • If needed, iteratively relax or tighten rules (edit YAML, then re-apply):
      kubectl apply -f <updated-policy-file>.yaml
  6. Re-run evidence collection to confirm coverage

    • Verify that all namespaces now have at least one NetworkPolicy and that policies match your intent:
    kubectl get networkpolicies.networking.k8s.io --all-namespaces
    kubectl describe networkpolicies.networking.k8s.io -n <namespace>
    • Document which namespaces intentionally have specific NetworkPolicies and any namespaces (if any) that are intentionally left without them, including the risk rationale.
Using kubectl
# 1) List all namespaces
# Run on: any machine with kubectl access
kubectl get namespaces -o name

Review the list to understand the full scope of namespaces you must consider (including system namespaces like kube-system, kube-public, and any application namespaces).

# 2) For each namespace, list its NetworkPolicies
# Run on: any machine with kubectl access

# Shows a concise overview of how many NetworkPolicies exist per namespace
kubectl get networkpolicy --all-namespaces

# To see which namespaces have zero NetworkPolicies:
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{end}' | tr '\t' '\n' | while read ns; do
count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
echo "$ns $count"
done

Output interpretation:

  • Namespaces that show 0 in the count column have no NetworkPolicy objects defined.
  • Lack of any NetworkPolicy usually indicates unrestricted pod-to-pod traffic within that namespace (and from other namespaces, depending on the CNI behavior), which is what this control wants you to review and likely tighten.
# 3) Inspect NetworkPolicies in a specific namespace
# Run on: any machine with kubectl access
kubectl get networkpolicy -n <namespace> -o wide
kubectl describe networkpolicy -n <namespace> <policy-name>
kubectl get networkpolicy -n <namespace> -o yaml

Output interpretation:

  • Even if a namespace has one or more NetworkPolicies, they may not actually restrict traffic (for example, a policy that selects no pods, or allows all ingress/egress).
  • Use describe/-o yaml to review:
    • podSelector: which pods are affected.
    • policyTypes: Ingress, Egress, or both.
    • ingress / egress rules: whether they meaningfully restrict traffic or effectively allow everything.
# 4) Identify namespaces with workloads but no NetworkPolicies
# Run on: any machine with kubectl access

# List namespaces that currently have pods
kubectl get pods --all-namespaces -o custom-columns='NAMESPACE:.metadata.namespace' --no-headers | sort | uniq

# Cross-reference with the earlier NetworkPolicy count output

Output interpretation:

  • Namespaces that have running pods but zero NetworkPolicies are typically the highest priority for review, since they are actively used and currently not segmented by policy.

These commands only surface the current state. A human must decide:

  • Which namespaces require isolation.
  • How strict ingress/egress should be for each namespace.
  • Whether some namespaces (e.g., certain system namespaces) should intentionally remain more permissive.
Automation
#!/usr/bin/env bash
# Report namespaces without any NetworkPolicy and show existing policies per namespace.
# Run on: any machine with kubectl access to the cluster

set -euo pipefail

echo "=== Summary: NetworkPolicy presence per namespace ==="
echo

# List all namespaces, annotate whether they have at least one NetworkPolicy
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" -gt 0 ]; then
echo "[OK] Namespace: $ns - NetworkPolicies: $count"
else
echo "[WARN] Namespace: $ns - NetworkPolicies: 0 (unrestricted pod-to-pod by default)"
fi
done

echo
echo "=== Detailed listing of existing NetworkPolicies ==="
echo "# Format: <namespace> <networkpolicy-name>"
kubectl get networkpolicy --all-namespaces

echo
echo "=== Namespaces with NO NetworkPolicies (focus review here) ==="
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
echo "$ns"
fi
done

How to interpret the output

  • Lines starting with [WARN] in the summary and the list under Namespaces with NO NetworkPolicies indicate a problem: those namespaces currently have zero NetworkPolicy objects and therefore allow unrestricted pod-to-pod traffic by default.
  • These namespaces require manual review and design of appropriate NetworkPolicy objects based on application communication requirements. The script does not and cannot create policies automatically.