Ensure That All Namespaces Have Network Policies Defined
More Info:
Without NetworkPolicies, pods accept traffic from any source by default. Every namespace should define at least one NetworkPolicy to control pod-level traffic.
Risk Level
High
Address
Security
Compliance Standards
- CIS AKS
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify namespaces missing NetworkPolicies (run on any machine with kubectl access):
ns_without_np=$(comm -23 \<(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort) \<(kubectl get networkpolicy --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\n' | sort))printf '%s\n' "$ns_without_np" -
For each namespace that needs a strict default, create a default-deny-all policy (run on any machine with kubectl access; replace NAMESPACE with one from the list above):
kubectl apply -n NAMESPACE -f - <<'EOF'apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: default-deny-allspec:podSelector: {}policyTypes:- Ingress- EgressEOF -
For namespaces where you cannot fully deny all traffic, create an initial restrictive policy and adjust later (example allowing only intra-namespace traffic; run on any machine with kubectl access and replace NAMESPACE):
kubectl apply -n NAMESPACE -f - <<'EOF'apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: restrict-to-namespacespec:podSelector: {}policyTypes:- Ingressingress:- from:- podSelector: {}EOF -
Review and customize policies in critical namespaces (e.g., kube-system, monitoring, ingress) to avoid breaking traffic (run on any machine with kubectl access):
# List policies in a namespacekubectl get networkpolicy -n NAMESPACE# Show details of a policykubectl describe networkpolicy -n NAMESPACE POLICY_NAME# Edit a policy in-placekubectl edit networkpolicy -n NAMESPACE POLICY_NAME -
Optionally export policies to manifests for version control (run on any machine with kubectl access):
kubectl get networkpolicy -A -o yaml > all-networkpolicies-backup.yaml -
Verification (run on any machine with kubectl access):
ns_without_np=$(comm -23 \<(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort) \<(kubectl get networkpolicy --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\n' | sort))if [ -z "$ns_without_np" ]; thenecho "ALL_NAMESPACES_HAVE_NETWORKPOLICIES"elseecho "MISSING_NETWORKPOLICIES"printf '%s\n' "$ns_without_np"fi
Using kubectl
On any machine with kubectl access to the cluster:
- List namespaces currently missing NetworkPolicies (for your awareness):
ns_without_np=$(comm -23 \
<(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort) \
<(kubectl get networkpolicy --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\n' | sort))
printf '%s\n' "$ns_without_np"
- Create a default-deny NetworkPolicy in each namespace that lacks one (replace the namespace list as needed, or paste from the previous command’s output):
for ns in kube-system default; do
kubectl apply -n "$ns" -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
done
Adjust the for ns in ... list to include every namespace that should receive a default-deny policy, based on your environment and application needs.
- Verification (same command used by the audit):
ns_without_np=$(comm -23 \
<(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort) \
<(kubectl get networkpolicy --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\n' | sort))
if [ -z "$ns_without_np" ]; then echo "ALL_NAMESPACES_HAVE_NETWORKPOLICIES"; else echo "MISSING_NETWORKPOLICIES: $ns_without_np"; fi
Automation
#!/usr/bin/env bash
# Applies a default-deny NetworkPolicy to every namespace that has none.
# Run on: any machine with kubectl access and current context set to target cluster.
set -euo pipefail
echo "[INFO] Discovering namespaces without any NetworkPolicy..."
ns_without_np=$(comm -23 \
<(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort) \
<(kubectl get networkpolicy --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\n' | sort) \
|| true)
if [ -z "${ns_without_np}" ]; then
echo "[INFO] All namespaces already have at least one NetworkPolicy."
else
echo "[INFO] Namespaces missing NetworkPolicies:"
echo "${ns_without_np}" | sed 's/^/ - /'
# Apply a default-deny-all NetworkPolicy in each namespace that lacks any policy.
# This is idempotent: apply will create or update the same object safely.
while read -r ns; do
[ -z "${ns}" ] && continue
echo "[INFO] Applying default-deny-all NetworkPolicy in namespace: ${ns}"
kubectl apply -n "${ns}" -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
done <<< "${ns_without_np}"
fi
echo "[INFO] Verifying that all namespaces now have at least one NetworkPolicy..."
verify_ns_without_np=$(comm -23 \
<(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort) \
<(kubectl get networkpolicy --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\n' | sort) \
|| true)
if [ -z "${verify_ns_without_np}" ]; then
echo "ALL_NAMESPACES_HAVE_NETWORKPOLICIES"
exit 0
else
echo "MISSING_NETWORKPOLICIES"
echo "[WARN] The following namespaces still lack NetworkPolicies (investigate manually):"
echo "${verify_ns_without_np}" | sed 's/^/ - /'
exit 1
fi