> ## 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.

# OCI OKE Should Use Network Policies to Control Traffic

### More Info:

Define NetworkPolicy resources to allow only required ingress and egress per namespace and workload. Default-deny policies prevent compromised pods from pivoting laterally to other services or the internet.

### Risk Level

High

### Address

Compliance, Security

### Compliance Standards

* CIS OKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To meet “OKE should use Network Policies to control traffic,” you need to:

        1. **Make sure your OKE cluster supports network policies**
           * In OCI Console: go to **Developer Services → Kubernetes Clusters (OKE)**.
           * Open your **cluster**.
           * On the **Cluster Information** page, check:
             * **Cluster Type** must be **VCN-native (pod VNIC)** (network policies are not supported on “Classic” clusters).
           * If your cluster is **“Classic”**, you must:
             * Create a **new VCN-native OKE cluster** and migrate workloads (there’s no in-place conversion).

        2. **Enable Network Policies on the OKE cluster (Console)**
           * In the same cluster page, click **Edit Details** (or **Update Cluster** depending on UI version).
           * Look for **Network Configuration** / **Network Policies** section.
           * Enable or check:
             * **Kubernetes Network Policy Enforcement** (or similar wording).
           * Save the changes.
           * Wait for the **cluster state** to return to **Active**.

        3. **Ensure node pools are updated**
           * Within the cluster page, go to **Node Pools**.
           * For each node pool:
             * Check **Kubernetes version** and **image**; ensure they meet the minimum version required for network policy support (generally any recent OKE version will).
             * If needed, click **Edit** / **Upgrade** to update node pool version and image.
           * Allow node pools to complete upgrade / rolling replacement.

        4. **Verify network plugin / CNI**
           * On the cluster page, confirm that it uses **VCN-native CNI** (Pod VNICs). This is implicit for VCN-native clusters.
           * Classic Flannel-based clusters **do not** support network policies.

        5. **Create Kubernetes NetworkPolicy objects (kubectl)**
           *This part is not done in the OCI Console UI; you use kubectl against your OKE cluster, but it’s required to actually enforce traffic rules.*

           5.1. Get kubeconfig from OCI Console

           * In your cluster page, click **Access Cluster**.
           * Follow the instructions to:
             * Download/update your kubeconfig (e.g., using the **Cloud Shell** or your local machine).
             * Example (Cloud Shell):
               ```bash theme={null}
               oci ce cluster create-kubeconfig \
                 --cluster-id <your-cluster-ocid> \
                 --file $HOME/.kube/config \
                 --region <your-region> \
                 --token-version 2.0.0 \
                 --kube-endpoint PUBLIC_ENDPOINT
               ```
             * Then:
               ```bash theme={null}
               kubectl get nodes
               ```

           5.2. Apply an initial restrictive NetworkPolicy

           * Example: default deny all ingress within a namespace:
             ```yaml theme={null}
             apiVersion: networking.k8s.io/v1
             kind: NetworkPolicy
             metadata:
               name: default-deny-ingress
               namespace: default
             spec:
               podSelector: {}
               policyTypes:
               - Ingress
             ```
           * Save as `default-deny-ingress.yaml` and apply:
             ```bash theme={null}
             kubectl apply -f default-deny-ingress.yaml
             ```

           5.3. Add allow rules as needed

           * Example: allow ingress to pods labeled `app: myapp` only from pods labeled `role: frontend`:
             ```yaml theme={null}
             apiVersion: networking.k8s.io/v1
             kind: NetworkPolicy
             metadata:
               name: allow-frontend-to-myapp
               namespace: default
             spec:
               podSelector:
                 matchLabels:
                   app: myapp
               policyTypes:
               - Ingress
               ingress:
               - from:
                 - podSelector:
                     matchLabels:
                       role: frontend
             ```
           * Apply:
             ```bash theme={null}
             kubectl apply -f allow-frontend-to-myapp.yaml
             ```

        6. **Validate enforcement**
           * From Cloud Shell or a test pod:
             * Confirm that denied traffic is blocked and allowed traffic works:
               ```bash theme={null}
               kubectl run test --rm -it --image=alpine -- sh
               # Inside pod, try to curl or nc target services
               ```

        Summary of remediation in OCI Console:

        * Ensure cluster is **VCN-native**.
        * In **Cluster → Edit Details**, **enable Network Policy enforcement**.
        * Update **node pools** if needed.
        * Then define and apply **Kubernetes NetworkPolicy** resources (kubectl) to actually control pod-to-pod and namespace traffic.
      </Accordion>

      <Accordion title="Using CLI">
        In OCI Container Engine for Kubernetes (OKE), Calico network policies must be enabled at **cluster creation time**. You cannot turn them on for an existing cluster. So “remediation” means:

        1. Verify the current cluster’s setting
        2. Create a new OKE cluster with network policies enabled (via OCI CLI)
        3. Migrate workloads and delete the old cluster

        Below are the key steps and OCI CLI examples.

        ***

        ### 1. Verify if Network Policy is Enabled on Current Cluster

        ```bash theme={null}
        CLUSTER_ID="<your-existing-cluster-ocid>"

        oci ce cluster get \
          --cluster-id "$CLUSTER_ID" \
          --query "data.kubernetes-network-config.network-policy-config" \
          --output json
        ```

        If you see `"isNetworkPolicyEnabled": false` or null, it is not enabled and cannot be changed on this cluster.

        ***

        ### 2. Create a New OKE Cluster with Network Policies Enabled

        You must use the `--options` / `kubernetesNetworkConfig` with `networkPolicyConfig` set to `true`.

        Prepare a JSON file, e.g. `cluster-options.json`:

        ```json theme={null}
        {
          "kubernetesNetworkConfig": {
            "podsCidr": "10.244.0.0/16",
            "servicesCidr": "10.96.0.0/16",
            "networkPolicyConfig": {
              "isNetworkPolicyEnabled": true
            }
          }
        }
        ```

        Then run:

        ```bash theme={null}
        COMPARTMENT_ID="<compartment-ocid>"
        VCN_ID="<vcn-ocid>"
        SUBNET_IDS='["<subnet-ocid-1>","<subnet-ocid-2>"]'    # for LB / control plane, etc.
        CLUSTER_NAME="oke-with-network-policy"
        K8S_VERSION="<desired-k8s-version>"                   # e.g. v1.29.2

        oci ce cluster create \
          --name "$CLUSTER_NAME" \
          --compartment-id "$COMPARTMENT_ID" \
          --vcn-id "$VCN_ID" \
          --kubernetes-version "$K8S_VERSION" \
          --endpoint-config '{"isPublicIpEnabled": false}' \
          --options file://cluster-options.json \
          --kms-key-id "<optional-kms-key-ocid>" \
          --freeform-tags '{"env":"prod"}'
        ```

        Check that network policies are enabled:

        ```bash theme={null}
        NEW_CLUSTER_ID="<new-cluster-ocid>"

        oci ce cluster get \
          --cluster-id "$NEW_CLUSTER_ID" \
          --query "data.kubernetes-network-config.network-policy-config" \
          --output json
        ```

        You should see:

        ```json theme={null}
        {
          "isNetworkPolicyEnabled": true
        }
        ```

        ***

        ### 3. Create Node Pool(s) for the New Cluster

        ```bash theme={null}
        NODEPOOL_NAME="np-with-network-policy"
        NODE_SHAPE="VM.Standard.E4.Flex"
        NODE_IMAGE_ID="<node-image-ocid>"
        NODE_SUBNET_IDS='["<worker-subnet-ocid-1>","<worker-subnet-ocid-2>"]'

        oci ce node-pool create \
          --compartment-id "$COMPARTMENT_ID" \
          --cluster-id "$NEW_CLUSTER_ID" \
          --name "$NODEPOOL_NAME" \
          --kubernetes-version "$K8S_VERSION" \
          --node-shape "$NODE_SHAPE" \
          --node-source-details "{\"sourceType\":\"IMAGE\",\"imageId\":\"$NODE_IMAGE_ID\"}" \
          --subnet-ids "$NODE_SUBNET_IDS" \
          --node-config-details '{"size":3}'
        ```

        Wait until the node pool is `ACTIVE`:

        ```bash theme={null}
        oci ce node-pool get --node-pool-id "<node-pool-ocid>" --query "data.lifecycle-state"
        ```

        ***

        ### 4. Point kubectl to the New Cluster

        ```bash theme={null}
        # Generate kubeconfig for new cluster
        oci ce cluster create-kubeconfig \
          --cluster-id "$NEW_CLUSTER_ID" \
          --file $HOME/.kube/config-new \
          --region "<region>" \
          --token-version 2.0.0 \
          --kube-endpoint PRIVATE

        export KUBECONFIG=$HOME/.kube/config-new
        kubectl get nodes
        ```

        ***

        ### 5. Deploy/Enforce Kubernetes NetworkPolicies

        Network policies themselves are standard Kubernetes resources and are applied with `kubectl`, not OCI CLI. Example:

        ```yaml theme={null}
        # deny-all-default.yaml
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: deny-all
          namespace: default
        spec:
          podSelector: {}
          policyTypes:
          - Ingress
          - Egress
        ```

        ```bash theme={null}
        kubectl apply -f deny-all-default.yaml
        ```

        Then add more granular `NetworkPolicy` manifests to allow needed traffic.

        ***

        ### 6. Migrate Workloads and Delete Old Cluster

        1. Export and reapply manifests (or use Helm/ArgoCD/etc.) into the new cluster.
        2. Verify apps and traffic behavior under network policies.
        3. Delete old resources:

        ```bash theme={null}
        OLD_CLUSTER_ID="<old-cluster-ocid>"

        # Delete old node pools first (if still present)
        oci ce node-pool list \
          --compartment-id "$COMPARTMENT_ID" \
          --cluster-id "$OLD_CLUSTER_ID" \
          --query "data[].id" \
          --output tsv | while read NP; do
            oci ce node-pool delete --node-pool-id "$NP" --force --wait-for-state SUCCEEDED
          done

        # Delete the old cluster
        oci ce cluster delete \
          --cluster-id "$OLD_CLUSTER_ID" \
          --force \
          --wait-for-state SUCCEEDED
        ```

        ***

        If you share your current cluster’s `oci ce cluster get` output (redacted), I can give you an exact `cluster-options.json` and CLI command tailored to your environment.
      </Accordion>

      <Accordion title="Using Python">
        To remediate this, you need to **define and apply Kubernetes NetworkPolicy resources** to your OKE cluster. The Python part is about **programmatically creating/applying those policies** using the Kubernetes Python client.

        Below are the minimal practical steps.

        ***

        ## 1. Prerequisites

        1. An existing OKE cluster with:
           * Worker nodes running
           * `kubectl` access working from your machine
        2. `kubeconfig` for the OKE cluster (usually generated via OCI Console or CLI).
        3. Python packages installed:

        ```bash theme={null}
        pip install kubernetes
        ```

        (You only need the OCI Python SDK if you also want to automate kubeconfig generation or cluster creation.)

        ***

        ## 2. Ensure Network Policies Are Supported/Enabled in the Cluster

        NetworkPolicies are a Kubernetes feature; OKE supports them when using a compatible CNI/network plugin.

        From the Kubernetes side, you can check quickly:

        ```bash theme={null}
        kubectl api-resources | grep networkpolicies
        ```

        You should see:

        ```text theme={null}
        networkpolicies   netpol   networking.k8s.io/v1   true   NetworkPolicy
        ```

        If that’s missing, the cluster/network setup doesn’t support network policies and must be re-created or reconfigured via OCI (do that via console/OCI CLI/SDK according to Oracle docs).

        Assuming the resource exists, continue.

        ***

        ## 3. Python: Connect to OKE via Kubernetes Client

        ```python theme={null}
        from kubernetes import client, config

        # Load local kubeconfig (pointing to your OKE cluster)
        config.load_kube_config()  # or load_incluster_config() if running inside the cluster

        # Create API client for NetworkPolicy
        netpol_api = client.NetworkingV1Api()
        ```

        If your kubeconfig isn’t in the default path, pass it explicitly:

        ```python theme={null}
        config.load_kube_config(config_file="/path/to/oke-kubeconfig")
        ```

        ***

        ## 4. Define a “Default Deny” NetworkPolicy (Ingress + Egress)

        This enforces that **no pod in a namespace can talk to anything unless explicitly allowed** by additional NetworkPolicies.

        Example for namespace `production`:

        ```python theme={null}
        from kubernetes import client

        namespace = "production"

        default_deny_netpol = client.V1NetworkPolicy(
            metadata=client.V1ObjectMeta(
                name="default-deny-all",
                namespace=namespace,
            ),
            spec=client.V1NetworkPolicySpec(
                pod_selector=client.V1LabelSelector(  # selects all pods in namespace
                    match_labels={}
                ),
                policy_types=["Ingress", "Egress"],
                ingress=[],  # deny all ingress
                egress=[],   # deny all egress
            ),
        )
        ```

        Apply it:

        ```python theme={null}
        try:
            netpol_api.create_namespaced_network_policy(
                namespace=namespace,
                body=default_deny_netpol,
            )
            print("Default deny NetworkPolicy created.")
        except client.exceptions.ApiException as e:
            if e.status == 409:
                print("Default deny NetworkPolicy already exists.")
            else:
                raise
        ```

        ***

        ## 5. Define an Allow Policy (Example: Allow HTTP from Frontend to Backend)

        Suppose:

        * All frontend pods have label: `app: frontend`
        * All backend pods have label: `app: backend`
        * You want to **allow frontend → backend on port 8080** only (in namespace `production`).

        ```python theme={null}
        allow_frontend_to_backend = client.V1NetworkPolicy(
            metadata=client.V1ObjectMeta(
                name="allow-frontend-to-backend",
                namespace=namespace,
            ),
            spec=client.V1NetworkPolicySpec(
                pod_selector=client.V1LabelSelector(
                    match_labels={"app": "backend"}  # this policy applies to backend pods
                ),
                policy_types=["Ingress"],
                ingress=[
                    client.V1NetworkPolicyIngressRule(
                        _from=[
                            client.V1NetworkPolicyPeer(
                                pod_selector=client.V1LabelSelector(
                                    match_labels={"app": "frontend"}
                                )
                            )
                        ],
                        ports=[
                            client.V1NetworkPolicyPort(
                                port=8080,
                                protocol="TCP",
                            )
                        ]
                    )
                ]
            )
        )

        try:
            netpol_api.create_namespaced_network_policy(
                namespace=namespace,
                body=allow_frontend_to_backend,
            )
            print("Allow frontend-to-backend NetworkPolicy created.")
        except client.exceptions.ApiException as e:
            if e.status == 409:
                print("Allow NetworkPolicy already exists.")
            else:
                raise
        ```

        ***

        ## 6. (Optional) Apply Policies from YAML Using Python

        If you prefer writing YAML files and applying them via Python:

        `netpol-default-deny.yaml`:

        ```yaml theme={null}
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: default-deny-all
          namespace: production
        spec:
          podSelector: {}
          policyTypes:
            - Ingress
            - Egress
          ingress: []
          egress: []
        ```

        Python to apply:

        ```python theme={null}
        from kubernetes import client, config, utils
        from kubernetes.client import api_client

        config.load_kube_config()
        k8s_client = api_client.ApiClient()

        utils.create_from_yaml(k8s_client, "netpol-default-deny.yaml")
        ```

        ***

        ## 7. Verification

        After applying via Python:

        ```bash theme={null}
        kubectl get networkpolicy -n production
        kubectl describe networkpolicy default-deny-all -n production
        ```

        Test connectivity (e.g., with temporary pods) to verify that only the allowed traffic flows.

        ***

        If you share your specific traffic matrix (which pods/services should be allowed to talk to which), I can provide tailored Python code to generate those NetworkPolicies.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # This cannot be remediated on oci_containerengine_cluster itself;
        # NetworkPolicy is a Kubernetes resource and must be applied via the Kubernetes API.

        # Configure the Kubernetes provider against your OKE cluster
        provider "kubernetes" {
          host                   = var.OKE_CLUSTER_ENDPOINT          # e.g. from oci_containerengine_cluster.endpoint
          cluster_ca_certificate = base64decode(var.OKE_CLUSTER_CA)   # e.g. from oci_containerengine_cluster.certificate_authority
          token                  = var.OKE_CLUSTER_BEARER_TOKEN       # or exec/auth provider
        }

        ############################################################
        # 1. Default-deny all ingress in a namespace
        ############################################################

        resource "kubernetes_network_policy_v1" "ns_default_deny_ingress" {
          metadata {
            name      = "default-deny-ingress"
            namespace = "TARGET_NAMESPACE" # replace with the namespace to protect
          }

          spec {
            pod_selector {} # selects all pods in the namespace

            ingress {}      # empty = deny all ingress

            policy_types = ["Ingress"]
          }
        }

        ############################################################
        # 2. Default-deny all egress in a namespace
        ############################################################

        resource "kubernetes_network_policy_v1" "ns_default_deny_egress" {
          metadata {
            name      = "default-deny-egress"
            namespace = "TARGET_NAMESPACE" # same namespace as above
          }

          spec {
            pod_selector {} # selects all pods in the namespace

            egress {}       # empty = deny all egress

            policy_types = ["Egress"]
          }
        }

        ############################################################
        # 3. Allow only required ingress to a specific app
        ############################################################

        resource "kubernetes_network_policy_v1" "app_allow_ingress" {
          metadata {
            name      = "allow-app-ingress"
            namespace = "TARGET_NAMESPACE" # namespace where the app runs
          }

          spec {
            pod_selector {
              match_labels = {
                app = "APP_LABEL" # replace with label selecting the workload (e.g. "web")
              }
            }

            ingress {
              from {
                namespace_selector {
                  match_labels = {
                    name = "ALLOWED_CALLER_NAMESPACE" # namespace allowed to reach this app
                  }
                }
              }

              ports {
                port     = 80
                protocol = "TCP"
              }
            }

            policy_types = ["Ingress"]
          }
        }

        ############################################################
        # 4. Allow only required egress from a specific app
        ############################################################

        resource "kubernetes_network_policy_v1" "app_allow_egress" {
          metadata {
            name      = "allow-app-egress"
            namespace = "TARGET_NAMESPACE"
          }

          spec {
            pod_selector {
              match_labels = {
                app = "APP_LABEL" # same label as above
              }
            }

            egress {
              to {
                ip_block {
                  cidr = "ALLOWED_DEST_CIDR" # e.g. "10.0.0.0/16" or specific service CIDR
                }
              }

              ports {
                port     = 443
                protocol = "TCP"
              }
            }

            policy_types = ["Egress"]
          }
        }
        ```

        This finding cannot be fixed directly on the `oci_containerengine_cluster` (OKE cluster) resource: Oracle’s Terraform provider does not expose Kubernetes NetworkPolicy there. Network policies must be applied as Kubernetes resources using the `kubernetes_network_policy_v1` resource against the OKE API as shown.

        No resource replacement of the OKE cluster is required; only in-cluster policy objects are added/updated. `terraform plan` should show `+` (create) or `~` (update) for the `kubernetes_network_policy_v1` resources and no changes to `oci_containerengine_cluster`.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
