> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ensure Network Policy Is Enabled And Set Appropriate

### More Info:

Amazon EKS provides two ways to implement network policy. You choose a network policy option when you create an EKS cluster. The policy option cant be changed after the cluster is created: Calico Network Policies, an open-source network and network security solution founded by Tigera. Both implementations use Linux IPTables to enforce the specified policies. Policies are translated into sets of allowed and disallowed IP pairs. These pairs are then programmed as IPTable filter rules.

### 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 EKS
* 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify the cluster’s network plugin / policy engine**
           * From any machine with AWS CLI access:
             ```bash theme={null}
             aws eks describe-cluster --name YOUR_CLUSTER_NAME --region YOUR_AWS_REGION \
               --query 'cluster.resourcesVpcConfig' --output json
             ```
           * In the AWS console, open EKS → your cluster → Networking → confirm which CNI add-ons are installed (e.g., Amazon VPC CNI only, or Calico, etc.).
           * If your cluster does not have a network policy–capable CNI (e.g., Calico), note that this cluster cannot enforce Kubernetes NetworkPolicies and you must either deploy a supported policy engine or plan a new cluster with it enabled.

        2. **Check whether any Kubernetes NetworkPolicy objects exist**
           * From any machine with kubectl access:
             ```bash theme={null}
             kubectl get networkpolicy --all-namespaces
             ```
           * If the list is empty but you require intra-cluster segmentation, you currently have no enforced NetworkPolicies even if a policy engine is present.

        3. **Review current network segmentation requirements with stakeholders**
           * Document workloads that:
             * Must only talk to specific namespaces/services (e.g., frontend → backend only).
             * Must be internet-isolated or restricted to specific egress.
           * Decide on a default stance per namespace: default-deny (preferred) vs allow-all.
           * This is a business/architecture decision, not something a command can answer.

        4. **If the cluster lacks a policy engine, plan provider-level remediation**
           * For existing EKS clusters created without a network policy–capable CNI, the network policy option cannot be switched in-place. Typical options are:
             * Create a new EKS cluster with Calico or another supported network policy engine configured via your IaC (e.g., eksctl, Terraform, AWS CDK) or by following the provider’s “Install Calico on EKS” guidance.
             * Migrate workloads to the new cluster, then decommission the old cluster.
           * Capture this as a change plan (with maintenance windows, testing, and rollback).

        5. **If a policy engine is present, implement / refine NetworkPolicies**
           * From any machine with kubectl access, inspect existing policies for a sample namespace:
             ```bash theme={null}
             kubectl get networkpolicy -n YOUR_NAMESPACE -o yaml
             ```
           * Create or adjust NetworkPolicies (using your chosen GitOps/manifest process) to:
             * Enforce namespace isolation (e.g., default-deny + explicit allows).
             * Restrict ingress/egress based on the requirements from step 3.
           * Apply and test connectivity carefully in a non‑production environment first.

        6. **Verify effective enforcement after changes**
           * From any machine with kubectl access, confirm policies are present and accepted:
             ```bash theme={null}
             kubectl get networkpolicy --all-namespaces
             ```
           * Use provider/CNI-specific tools or logs (for Calico, e.g., calicoctl if in use, or pod connectivity tests using `kubectl exec` and `curl/nc`) to validate that blocked connections actually fail and allowed connections succeed, documenting the results as evidence for this control.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot be used to enable or change the EKS cluster’s network policy provider; this is configured only at the cloud provider control-plane level (EKS console/CLI/IaC) when the cluster is created. Refer to the Manual Steps section for guidance on reviewing the current configuration and planning any required changes.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Purpose: Report Kubernetes network policy coverage across all namespaces.
        # Scope:   Run on any machine with kubectl context to the target cluster.
        # Requires: kubectl, jq
        #
        # This does NOT verify whether EKS was created with Calico or another
        # network policy engine; that must be checked in your IaC or EKS cluster
        # creation configuration.

        set -euo pipefail

        if ! command -v kubectl >/dev/null 2>&1; then
          echo "ERROR: kubectl not found in PATH" >&2
          exit 1
        fi

        if ! command -v jq >/dev/null 2>&1; then
          echo "ERROR: jq not found in PATH" >&2
          exit 1
        fi

        echo "== Cluster info =="
        kubectl version --short || true
        echo

        echo "== Namespaces and NetworkPolicy objects =="
        # List all namespaces with count of NetworkPolicy objects and their types
        kubectl get ns -o json | jq -r '
          .items[] |
          .metadata.name as $ns |
          (
            $ns,
            (
              ( .metadata.labels // {} ) as $labels
              | "  labels: " + ( $labels | tojson )
            ),
            (
              "  networkPolicies:",
              (
                [
                  ( .metadata.name ) as $dummy
                ] |
                . # just to make structure consistent
              )
            )
          | @text
          ' >/dev/null 2>&1 || true

        # More structured summary using multiple calls
        echo "NAMESPACE,NUM_POLICIES,ISOLATED_PODS_DESCRIPTION"
        for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
          num_policies=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
          # Detect if any policy selects all pods (empty podSelector) which is typical for default deny
          has_default_policy=$(kubectl get networkpolicy -n "$ns" -o json 2>/dev/null \
            | jq '[.items[]
                   | select(.spec.podSelector == {} )
                  ] | length > 0' 2>/dev/null || echo "false")

          if [ "$num_policies" -eq 0 ]; then
            iso_desc="NO NetworkPolicy objects; namespace likely fully non-isolated"
          else
            if [ "$has_default_policy" = "true" ]; then
              iso_desc="Has at least one policy with empty podSelector (possible namespace-wide default policy)"
            else
              iso_desc="Has policies, but none with empty podSelector (isolation may be partial)"
            fi
          fi

          echo "$ns,$num_policies,$iso_desc"
        done
        echo

        echo "== Detailed per-namespace report =="
        for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
          echo "----- Namespace: $ns -----"
          kubectl get networkpolicy -n "$ns" || echo "  (no NetworkPolicy objects)"
          echo
        done

        echo "== Pod-level coverage check (sample) =="
        # For each namespace, show how many pods are selected by at least one NetworkPolicy
        for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
          total_pods=$(kubectl get pods -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
          if [ "$total_pods" -eq 0 ]; then
            echo "Namespace $ns: no pods"
            continue
          fi

          # Build a label selector for pods matched by any policy in this namespace
          policies_json=$(kubectl get networkpolicy -n "$ns" -o json 2>/dev/null || echo '{"items":[]}')
          covered_pods=0

          # If there are no policies, then 0 covered pods
          num_policies=$(echo "$policies_json" | jq '.items | length')
          if [ "$num_policies" -gt 0 ]; then
            # For each pod, check if any policy's podSelector matches it
            for pod in $(kubectl get pod -n "$ns" -o jsonpath='{.items[*].metadata.name}'); do
              pod_labels=$(kubectl get pod "$pod" -n "$ns" -o json | jq '.metadata.labels // {}')
              matched=$(echo "$policies_json" | jq --argjson podLabels "$pod_labels" '
                [ .items[]
                  | .spec.podSelector.matchLabels // {}
                  | to_entries as $sel
                  | all($sel[]; $podLabels[.key] == .value)
                ] | any
              ')
              if [ "$matched" = "true" ]; then
                covered_pods=$((covered_pods + 1))
              fi
            done
          fi

          echo "Namespace $ns: pods covered by at least one NetworkPolicy = $covered_pods / $total_pods"
        done

        cat <<'EOF'

        INTERPRETING OUTPUT:

        1) "NAMESPACE,NUM_POLICIES,ISOLATED_PODS_DESCRIPTION"
           - Namespaces with "NO NetworkPolicy objects" are likely fully non-isolated.
           - Namespaces that "Has policies, but none with empty podSelector" may only
             isolate specific pods; traffic for other pods remains unrestricted.
           - Namespaces with "Has at least one policy with empty podSelector" often
             have some form of namespace-wide baseline policy (e.g., default deny),
             but you must review the actual spec to confirm.

        2) "Detailed per-namespace report"
           - If critical namespaces (for example, workloads handling sensitive data)
             show "(no NetworkPolicy objects)", they likely do not have traffic
             segmentation/enforcement in place.

        3) "Pod-level coverage check (sample)"
           - Shows how many pods in each namespace are selected by at least one
             NetworkPolicy. A low ratio (near 0) in production namespaces is a
             red flag that most pods are not governed by any policy.

        LIMITATIONS:

        - This script checks Kubernetes NetworkPolicy objects and which pods
          they target. It does NOT:
          * Confirm that the EKS cluster was created with Calico or any particular
            network policy engine.
          * Validate that policies enforce the "right" security posture.

        If you see many namespaces with zero NetworkPolicy objects or critical
        workload pods not covered by any policy, that indicates a potential
        problem relative to the benchmark requirement to "segment and isolate
        your traffic" using a network policy engine.

        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
