Skip to main content

More Info:

The CNI plugin must support NetworkPolicy resources for traffic segmentation to be enforceable. Use a CNI plugin that supports network policies and follow least-privilege network design.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS EKS

Triage and Remediation

Remediation

Manual Steps

  1. Confirm the CNI plugin and its NetworkPolicy support
    • Run on: any machine with kubectl access
    • Commands:
    • Review:
      • Identify the CNI in use (e.g., Calico, Cilium, Antrea) from pod/DaemonSet names.
      • Cross-check its documentation to confirm it supports Kubernetes NetworkPolicy (and whether it supports both ingress and egress).
  2. Check whether NetworkPolicy objects are in use at all
    • Run on: any machine with kubectl access
    • Commands:
    • Review:
      • If no NetworkPolicy resources exist, the cluster currently has no enforced traffic segmentation. You must design and deploy policies (starting with least-privilege) once you confirm the CNI supports them.
  3. Identify namespaces lacking a default restrictive policy
    • Run on: any machine with kubectl access
    • Commands:
    • Review for each namespace:
      • Check whether there is at least one “default deny” style policy that selects all pods and denies all ingress and (if supported) egress by default. Typical patterns:
        • PodSelector is empty (podSelector: {}) to match all pods.
        • No ingress section, or policyTypes includes Ingress but no allowed peers.
        • For egress control, policyTypes includes Egress and either no egress rules or only narrowly scoped destinations.
  4. Assess current policies against least-privilege
    • Run on: any machine with kubectl access
    • Commands:
    • Review /tmp/all-networkpolicies.yaml:
      • Look for broad rules such as:
        • podSelector: {} combined with ingress from all sources or egress to 0.0.0.0/0.
        • namespaceSelector: {} without additional constraints.
      • Determine whether each policy exists to explicitly allow necessary traffic given a default-deny stance, or if it unintentionally creates wide-open access.
  5. Design and apply least-privilege “default deny” and scoped allow policies
    • Run on: any machine with kubectl access
    • For a namespace missing default-deny, create a manifest like:
    • Apply:
    • Then, iteratively define additional NetworkPolicy manifests that:
      • Select only the pods that must communicate.
      • Allow only specific ingress sources and/or egress destinations and ports required for application function.
  6. Verify enforcement and adjust as needed
    • Run on: any machine with kubectl access
    • Commands:
    • Optional functional check:
      • Use test pods (e.g., kubectl run -it --rm test --image=busybox --restart=Never -- sh) to attempt connections that should be blocked or allowed, confirming the CNI is enforcing NetworkPolicy as designed. Adjust policies if legitimate traffic is unintentionally denied.
Look for pods with names like calico-*, cilium-*, azure-cni-*, aws-node, weave-net, antrea-*, etc.
Investigate the documented capabilities of the detected CNI. If it does not explicitly support Kubernetes NetworkPolicy (or you see only a basic CNI like flannel without policy add-ons), network policies will not be enforced.
If this returns No resources found (or very few policies in only one namespace), then there is likely no meaningful segmentation. This is a policy gap even if the CNI supports NetworkPolicy.
Things that indicate a problem:
  • No “default deny” style policy (e.g. policies that select many/all pods and deny all ingress/egress by default).
  • Policies only allow traffic but never restrict it (no baseline deny).
  • podSelector: {} with overly broad ingress/egress rules that effectively allow all.
If default or other application namespaces have no NetworkPolicy objects at all, pods there can communicate freely with each other and, often, with the internet. That conflicts with a least-privilege design.
If you have a NetworkPolicy that should deny this traffic but pings / connections still succeed, that suggests:
  • The CNI plugin does not enforce NetworkPolicy, or
  • The policy is misconfigured (e.g. selectors don’t match pods).
If no namespaces have any “deny all” style policy (by label or by manual inspection of specs), then the cluster likely lacks a least-privilege baseline; traffic is broadly allowed until explicitly denied.Use the findings above to decide:
  • Whether your current CNI needs to be replaced/upgraded to one that supports NetworkPolicy.
  • Where to design and apply deny-all (or global) policies as a baseline and then add narrowly scoped allow rules.
Problem indicators in the script output:
  • CNI detection only shows plugins known not to enforce NetworkPolicy (e.g., plain flannel, or a cloud CNI without NP support enabled).
  • No NetworkPolicy resources found in any namespace. for a production cluster.
  • Sensitive namespaces listed under “Namespaces without any NetworkPolicy defined”.
  • No or very few “default deny”-style policies in the heuristic section for critical namespaces.