> ## 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 That All Namespaces Have Network Policies Defined

### More Info:

Namespaces without NetworkPolicies allow unrestricted pod-to-pod traffic. Define at least one NetworkPolicy in each namespace to control and restrict traffic.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS EKS

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. List namespaces that currently have no NetworkPolicies (run on any machine with kubectl access):
           ```bash theme={null}
           ns_without_np=$(kubectl get namespaces -o json | jq -r '.items[].metadata.name' | while read ns; do
             count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l)
             if [ "$count" -eq 0 ]; then echo "$ns"; fi
           done)
           echo "$ns_without_np"
           ```

        2. For each namespace without a NetworkPolicy, review what should be allowed:
           * Ingress: which pods/services (by label, namespace, IPs) may talk to pods in this namespace?
           * Egress: which external destinations (namespaces, services, CIDRs, ports) are required?
             Use these answers to decide labels, ports, and CIDR ranges for your policies.

        3. (Optional but recommended) Label workloads in a target namespace so policies can select them. For example, in namespace `example-namespace` (run on any machine with kubectl access):
           ```bash theme={null}
           kubectl -n example-namespace get pods --no-headers -o custom-columns='NAME:.metadata.name' | while read pod; do
             kubectl -n example-namespace label pod "$pod" role=app --overwrite
           done
           ```

        4. Create a default deny-all ingress and egress NetworkPolicy for each selected namespace, adjusting `namespace` and labels as appropriate (run on any machine with kubectl access). Example for `example-namespace`:
           ```bash theme={null}
           cat << 'EOF' | kubectl apply -f -
           apiVersion: networking.k8s.io/v1
           kind: NetworkPolicy
           metadata:
             name: default-deny-all
             namespace: example-namespace
           spec:
             podSelector: {}        # selects all pods in this namespace
             policyTypes:
               - Ingress
               - Egress
           EOF
           ```

        5. Add specific allow NetworkPolicies where needed so applications continue to function. For example, allow ingress HTTP traffic from same namespace to pods labeled `role=app` in `example-namespace` (run on any machine with kubectl access):
           ```bash theme={null}
           cat << 'EOF' | kubectl apply -f -
           apiVersion: networking.k8s.io/v1
           kind: NetworkPolicy
           metadata:
             name: allow-http-same-namespace
             namespace: example-namespace
           spec:
             podSelector:
               matchLabels:
                 role: app
             policyTypes:
               - Ingress
             ingress:
               - from:
                   - podSelector: {}      # any pod in this namespace
                 ports:
                   - protocol: TCP
                     port: 80
           EOF
           ```
           Repeat with additional policies for other required ports, sources, or egress as identified in step 2.

        6. Verify that every namespace has at least one NetworkPolicy (run on any machine with kubectl access):
           ```bash theme={null}
           ns_without_np=$(kubectl get namespaces -o json | jq -r '.items[].metadata.name' | while read ns; do
             count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l)
             if [ "$count" -eq 0 ]; then echo "$ns"; fi
           done)
           if [ -z "$ns_without_np" ]; then
             echo "ALL_NAMESPACES_HAVE_NETWORK_POLICIES"
           else
             echo "NAMESPACES_WITHOUT_NETWORK_POLICIES: $ns_without_np"
           fi
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) Identify namespaces without any NetworkPolicy
        # Run on: any machine with kubectl access
        ns_without_np=$(kubectl get namespaces -o json | jq -r '.items[].metadata.name' | while read ns; do
          count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l)
          if [ "$count" -eq 0 ]; then echo "$ns"; fi
        done)
        echo "$ns_without_np"
        ```

        ```bash theme={null}
        # 2) Create a baseline default-deny-all-ingress policy in each namespace that lacks NetworkPolicies
        #    Adjust/add more specific policies later as needed for your applications.
        # Run on: any machine with kubectl access

        for ns in $ns_without_np; do
          cat <<EOF | kubectl apply -n "$ns" -f -
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: default-deny-ingress
          namespace: $ns
        spec:
          podSelector: {}
          policyTypes:
            - Ingress
        EOF
        done
        ```

        ```bash theme={null}
        # 3) Optional: create a stricter baseline (deny all ingress and egress)
        # WARNING: This can break cross-namespace or external connectivity for pods in these namespaces.
        # Run on: any machine with kubectl access

        for ns in $ns_without_np; do
          cat <<EOF | kubectl apply -n "$ns" -f -
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: default-deny-all
          namespace: $ns
        spec:
          podSelector: {}
          policyTypes:
            - Ingress
            - Egress
        EOF
        done
        ```

        ```bash theme={null}
        # 4) Verification: confirm every namespace now has at least one NetworkPolicy
        # Run on: any machine with kubectl access

        ns_without_np=$(kubectl get namespaces -o json | jq -r '.items[].metadata.name' | while read ns; do
          count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l)
          if [ "$count" -eq 0 ]; then echo "$ns"; fi
        done)

        if [ -z "$ns_without_np" ]; then
          echo "ALL_NAMESPACES_HAVE_NETWORK_POLICIES"
        else
          echo "NAMESPACES_WITHOUT_NETWORK_POLICIES: $ns_without_np"
        fi
        ```
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        set -euo pipefail

        # This script:
        # - Ensures every namespace has at least one NetworkPolicy
        # - Creates a default-deny-all NetworkPolicy in any namespace missing policies
        # - Skips kube-system and other core namespaces where you may not want default-deny
        # - Is safe to re-run (idempotent)
        #
        # Run from any machine with kubectl access and a current context pointing at the cluster.

        # -------- Configuration --------
        # Comma-separated namespaces to SKIP from automatic default-deny policies.
        # Adjust as appropriate for your cluster.
        SKIP_NAMESPACES="kube-system,kube-public,default,local-path-storage,ingress-nginx"

        # Name of the default policy to create (if none exist in a namespace)
        DEFAULT_POLICY_NAME="default-deny-all"

        # --------------------------------

        IFS=',' read -r -a SKIP_ARRAY <<< "$SKIP_NAMESPACES"

        ns_in_skip_list() {
          local ns="$1"
          for s in "${SKIP_ARRAY[@]}"; do
            if [[ "$ns" == "$s" ]]; then
              return 0
            fi
          done
          return 1
        }

        echo "Discovering namespaces without any NetworkPolicy..."
        ns_without_np=()

        # Collect namespaces with zero NetworkPolicies
        while read -r ns; do
          # Skip terminating namespaces
          phase=$(kubectl get ns "$ns" -o jsonpath='{.status.phase}')
          if [[ "$phase" != "Active" ]]; then
            continue
          fi

          count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
          if [[ "$count" -eq 0 ]]; then
            ns_without_np+=("$ns")
          fi
        done < <(kubectl get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')

        if [[ ${#ns_without_np[@]} -eq 0 ]]; then
          echo "All namespaces already have at least one NetworkPolicy."
        else
          echo "Namespaces with no NetworkPolicy: ${ns_without_np[*]}"
        fi

        for ns in "${ns_without_np[@]}"; do
          if ns_in_skip_list "$ns"; then
            echo "Skipping namespace '$ns' (in skip list); please define NetworkPolicies manually if desired."
            continue
          fi

          echo "Creating default-deny-all NetworkPolicy in namespace '$ns'..."

          # Apply an idempotent default deny-all policy (ingress and egress)
          # Safe to re-run: same name, full manifest.
          cat <<EOF | kubectl apply -f -
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: ${DEFAULT_POLICY_NAME}
          namespace: ${ns}
        spec:
          podSelector: {}           # applies to all pods in this namespace
          policyTypes:
            - Ingress
            - Egress
          ingress: []               # deny all ingress
          egress: []                # deny all egress
        EOF

        done

        echo
        echo "Verifying that all namespaces now have at least one NetworkPolicy..."

        verify_ns_without_np=$(kubectl get namespaces -o json | jq -r '.items[].metadata.name' | 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)

        if [ -z "$verify_ns_without_np" ]; then
          echo "ALL_NAMESPACES_HAVE_NETWORK_POLICIES"
        else
          echo "NAMESPACES_WITHOUT_NETWORK_POLICIES (manual review required or skipped by config): $verify_ns_without_np"
          echo "Review these namespaces and create appropriate NetworkPolicies as needed."
        fi
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
