Ensure Network Policy Is Enabled And Set Appropriate
More Info:
Configure Network Policy for the Cluster.
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)
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- 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
Remediation
Manual Steps
-
Identify current cluster network plugin and policy support
- Run on any machine with cloud CLI access:
- For OKE:
oci ce cluster get --cluster-id <CLUSTER_OCID> \--query 'data."endpoint-config"."is-private-endpoint"' --raw-outputoci ce cluster get --cluster-id <CLUSTER_OCID> \--query 'data.options."kubernetes-network-config"'
- Review the output for which CNI/networking option is in use (Flannel, OCI VCN-Native, Calico, etc.) and whether it supports Kubernetes NetworkPolicy.
- For OKE:
- Run on any machine with cloud CLI access:
-
Check cluster-level Network Policy feature/configuration in provider
- In the OCI Console:
- Go to Developer Services → Kubernetes Clusters (OKE) → select the cluster.
- Review Networking or Cluster Options tabs for:
- Selected network type/plugin.
- Any “Network Policy”, “Calico”, or similar options (varies by OKE version/shape).
- With IaC (if used), inspect Terraform/Resource Manager definitions for the cluster (e.g.,
oci_containerengine_clusterresources) for networking-related attributes to confirm whether a NetworkPolicy‑capable plugin is configured.
- In the OCI Console:
-
Enumerate existing Kubernetes NetworkPolicy objects
- On any machine with
kubectlaccess:kubectl get networkpolicy --all-namespaces - If none are listed or coverage is sparse, plan to introduce or tighten NetworkPolicy rules for critical namespaces (at minimum: system, control, and sensitive application namespaces).
- On any machine with
-
Assess current traffic exposure and required communication patterns
- Gather application/service inventory:
kubectl get nskubectl get svc --all-namespaces -o widekubectl get pods --all-namespaces -o wide
- For each critical namespace, document:
- Which services must be reachable from the internet, from other namespaces, and from internal-only components.
- Required egress destinations (DNS, databases, external APIs).
- Use this to determine the intended ingress/egress model so you can express it via NetworkPolicy.
- Gather application/service inventory:
-
Decide and implement a NetworkPolicy strategy in cloud/IaC configuration
- If the current OKE networking option does not support NetworkPolicy, plan a cluster migration or recreation using a NetworkPolicy‑capable option per OCI/OKE documentation and your IaC (Terraform, etc.).
- If NetworkPolicy is supported but unused or incomplete:
- Define baseline policies in manifests/IaC (even though this check is about provider configuration, NetworkPolicy objects themselves are Kubernetes resources):
- Default‑deny ingress (and optionally egress) per namespace.
- Explicit allow policies for required flows identified in step 4.
- Ensure future namespaces get default‑deny policies via templates or admission controls in your deployment/IaC process.
- Define baseline policies in manifests/IaC (even though this check is about provider configuration, NetworkPolicy objects themselves are Kubernetes resources):
-
Verify effective Network Policy enablement and coverage
- Confirm provider/networking configuration still indicates a NetworkPolicy‑capable CNI:
oci ce cluster get --cluster-id <CLUSTER_OCID> \--query 'data.options."kubernetes-network-config"'
- Confirm NetworkPolicy objects are present and cover intended namespaces:
kubectl get networkpolicy --all-namespaces -o wide
- Optionally validate behavior by attempting disallowed connections between pods/namespaces to ensure they are blocked as expected.
- Confirm provider/networking configuration still indicates a NetworkPolicy‑capable CNI:
Using kubectl
kubectl cannot be used to enable or configure the cluster-level network policy feature for this finding, because it is controlled at the managed control-plane / cloud provider layer (for example, in the provider console, CLI, or IaC). Please refer to the Manual Steps section for guidance on reviewing and updating the provider-side network policy configuration.
Automation
#!/usr/bin/env bash
#
# audit-network-policies.sh
#
# Report Kubernetes NetworkPolicy usage across all namespaces.
# Run from any machine with kubectl access and sufficient RBAC.
# Requires: bash, kubectl
set -euo pipefail
echo "=== NetworkPolicy audit: $(date -Iseconds) ==="
echo
# 1) Cluster-level summary
echo "== Cluster-wide summary =="
echo "- NetworkPolicy resource presence:"
if kubectl api-resources | grep -qE '^networkpolicies[[:space:]]'; then
echo " * NetworkPolicy CRD/API: PRESENT"
else
echo " * NetworkPolicy CRD/API: MISSING"
echo " !! Problem: Your cluster API does not expose the NetworkPolicy resource."
echo " This usually means the network plugin or cluster configuration"
echo " does not support Kubernetes NetworkPolicy."
fi
echo
echo "- Network plugin hint (from kube-system pods):"
kubectl get pods -n kube-system -o wide \
| awk 'NR==1 || /calico|cilium|weave|antrea|azure-cni|aws-node|flannel|cni/ {print}'
echo
echo " NOTE: You must confirm from provider docs whether the CNI/plugin actually"
echo " enforces Kubernetes NetworkPolicy objects in this managed environment."
echo
# 2) Per-namespace NetworkPolicy coverage
echo "== Per-namespace NetworkPolicy coverage =="
# Get list of namespaces
namespaces=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
# Table header
printf "%-32s %-10s %-12s %-12s\n" "NAMESPACE" "NP_COUNT" "HAS_DEFAULT" "HAS_INGRESS_EGRESS"
printf "%-32s %-10s %-12s %-12s\n" "---------" "--------" "----------" "---------------"
for ns in $namespaces; do
# Count all NetworkPolicies in the namespace
np_count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
# Check for any policy that appears to be a "default deny" or restrictive policy:
# - spec.podSelector == {} (selects all pods)
# - and either:
# * no ingress rules (deny-all ingress), or
# * no egress rules (deny-all egress), or
# * both missing (deny-all both directions)
has_default=$(kubectl get networkpolicy -n "$ns" -o json 2>/dev/null \
| jq -r '
.items[]
| select(.spec.podSelector == {} or .spec.podSelector == null)
| ( (has("spec") and (.spec | has("ingress") | not)) as $noIngress
| (has("spec") and (.spec | has("egress") | not)) as $noEgress
| if $noIngress or $noEgress then "yes" else empty end
)
' 2>/dev/null | head -n1)
if [[ -z "${has_default:-}" ]]; then
has_default="no"
fi
# Check if any NetworkPolicy in the namespace has both ingress and egress sections
has_ingress_egress=$(kubectl get networkpolicy -n "$ns" -o json 2>/dev/null \
| jq -r '
.items[]
| select((.spec.ingress | length > 0) and (.spec.egress | length > 0))
| "yes"
' 2>/dev/null | head -n1)
if [[ -z "${has_ingress_egress:-}" ]]; then
has_ingress_egress="no"
fi
printf "%-32s %-10s %-12s %-12s\n" "$ns" "$np_count" "$has_default" "$has_ingress_egress"
done
echo
echo "Interpretation of per-namespace table:"
echo " NP_COUNT : Number of NetworkPolicy objects in the namespace."
echo " HAS_DEFAULT : 'yes' if any policy appears to select all pods with"
echo " no ingress and/or no egress rules (default-deny style)."
echo " HAS_INGRESS_EGRESS: 'yes' if any policy uses both ingress and egress rules,"
echo " which often indicates more complete traffic control."
echo
# 3) Highlight potentially unprotected namespaces
echo "== Namespaces with NO NetworkPolicy defined =="
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
echo
echo "== Namespaces with NetworkPolicy but no apparent default-deny =="
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
| while read -r ns; do
json=$(kubectl get networkpolicy -n "$ns" -o json 2>/dev/null || echo '{}')
count=$(echo "$json" | jq '.items | length')
if [[ "$count" -eq 0 ]]; then
continue
fi
has_default=$(echo "$json" | jq -r '
.items[]
| select(.spec.podSelector == {} or .spec.podSelector == null)
| ( (has("spec") and (.spec | has("ingress") | not)) as $noIngress
| (has("spec") and (.spec | has("egress") | not)) as $noEgress
| if $noIngress or $noEgress then "yes" else empty end
)
' | head -n1)
if [[ -z "$has_default" ]]; then
echo " - $ns"
fi
done
echo
echo "=== How to interpret potential problems ==="
echo
echo "1) If 'NetworkPolicy CRD/API: MISSING':"
echo " - Problem: The cluster CNI / managed control plane likely does not support"
echo " Kubernetes NetworkPolicy, or it is disabled in the provider settings."
echo
echo "2) Namespaces listed under 'NO NetworkPolicy defined':"
echo " - Problem: Pods in these namespaces are generally fully open to network"
echo " traffic (subject to provider/CNI defaults). For security-sensitive workloads,"
echo " this is usually non-compliant with CIS recommendations."
echo
echo "3) Namespaces listed under 'NetworkPolicy but no apparent default-deny':"
echo " - Problem: There are some policies, but they may not provide a clear baseline"
echo " default-deny posture. You should manually review policies in those namespaces"
echo " to confirm they actually restrict traffic as intended."
echo
echo "NOTE: This script does NOT automatically fix issues or guarantee compliance."
echo " Use it as input for a manual review and for updating cloud-provider"
echo " network policy / CNI configuration and per-namespace policies."
To verify after changes, re-run:
bash audit-network-policies.sh
and confirm:
NetworkPolicy CRD/API: PRESENTis shown.- Security-sensitive namespaces no longer appear in:
- “NO NetworkPolicy defined”
- “NetworkPolicy but no apparent default-deny” (unless deliberately open by design).