> ## 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 Minimize Admission of Privileged Containers

### More Info:

Privileged containers run with all Linux capabilities and bypass most container isolation. They must be denied at admission time and only allowed via narrow exceptions tied to specific signed workloads.

### Risk Level

Critical

### Address

Compliance, Security

### Compliance Standards

* CIS OKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To minimize admission of privileged containers in an OCI OKE cluster *using the OCI Console*, you do this by enabling and configuring the OPA Gatekeeper add‑on with restrictive policies.

        ### 1. Open your OKE cluster in the OCI Console

        1. Sign in to the OCI Console.
        2. From the left menu: **Developer Services** → **Kubernetes Clusters (OKE)**.
        3. Select the **Compartment** that contains your cluster.
        4. Click the name of the **cluster** you want to secure.

        ### 2. Enable / configure the Gatekeeper add‑on

        1. In the cluster details page, go to the **Add‑ons** (or **Add‑ons & Security**) tab.

        2. Look for **Gatekeeper** or **Policy** / **Security** related add‑on:
           * If **Gatekeeper** is **not enabled**:
             * Click **Enable / Install Add‑on**.
             * Choose **Gatekeeper**.
           * If **Gatekeeper** is **already enabled**:
             * Click **Edit configuration** or the equivalent action for that add‑on.

        3. In the Gatekeeper configuration:
           * Choose the **policy profile** that **blocks privileged containers**. Depending on the UI version, this is typically:
             * **Restricted** (or similar) Pod Security profile, **or**
             * A checkbox / toggle like **Disallow privileged containers**, **Block privileged containers**, or **Disallow privilege escalation**.
           * Make sure the setting that **forbids `securityContext.privileged: true`** (and usually `allowPrivilegeEscalation: true`) is enabled/enforced.

        4. Click **Save**, **Update**, or **Apply** to reconfigure the cluster.
           * The cluster control plane will roll out the updated admission policy.

        ### 3. Confirm enforcement

        1. After the add‑on update completes, try to deploy (or redeploy) a pod that uses:
           ```yaml theme={null}
           securityContext:
             privileged: true
           ```
        2. The deployment should now be **rejected** by admission control with an error from Gatekeeper / policy enforcement.

        ### 4. Clean up existing workloads (if any)

        Admission control only blocks **new** or **updated** workloads:

        1. In the console, under the cluster, go to **Workloads** or **Deployments**.
        2. Identify any pods/deployments/DaemonSets that:
           * Use **HostPath** volumes with root access and
           * Have **Privileged** containers (visible in the workload details).
        3. Edit or redeploy those workloads (via your normal CI/CD or `kubectl`) to **remove**:
           ```yaml theme={null}
           securityContext:
             privileged: true
             allowPrivilegeEscalation: true
           ```

        If you can share what you see under **Add‑ons** or **Security** for the cluster in the console (names of toggles / profiles), I can map it to the exact click-path and profile name for your tenancy’s OKE version.
      </Accordion>

      <Accordion title="Using CLI">
        To minimize admission of privileged containers on OCI OKE, you use the OPA Gatekeeper admission controller and define a policy that denies pods with `securityContext.privileged: true`.

        Below are the steps, with OCI CLI where applicable.

        ***

        ## 1. Prerequisites

        * OCI CLI installed and configured (`oci setup config`)
        * You have permissions to update the OKE cluster
        * `kubectl` configured for the cluster (`oci ce cluster create-kubeconfig`)

        ***

        ## 2. Enable the Admission Controller (OPA Gatekeeper) via OCI CLI

        1. Get the OKE cluster OCID (if you don’t already have it):

        ```bash theme={null}
        oci ce cluster list --compartment-id <compartment_ocid> \
          --query 'data[].{"name":name,"ocid":id}' --output table
        ```

        2. Enable the admission controller:

        ```bash theme={null}
        oci ce cluster update \
          --cluster-id <cluster_ocid> \
          --cluster-options '{
            "admissionControllerOptions": {
              "isAdmissionControllerEnabled": true
            }
          }' \
          --force --wait-for-state ACTIVE
        ```

        Verify it’s enabled:

        ```bash theme={null}
        oci ce cluster get --cluster-id <cluster_ocid> \
          --query 'data.options.admissionControllerOptions'
        ```

        ***

        ## 3. Configure `kubectl` Access (once per admin machine)

        ```bash theme={null}
        oci ce cluster create-kubeconfig \
          --cluster-id <cluster_ocid> \
          --file $HOME/.kube/config-oke \
          --region <region> \
          --token-version 2
        export KUBECONFIG=$HOME/.kube/config-oke
        ```

        ***

        ## 4. Create a Gatekeeper ConstraintTemplate to Deny Privileged Containers

        Save as `ct-deny-privileged-containers.yaml`:

        ```yaml theme={null}
        apiVersion: templates.gatekeeper.sh/v1beta1
        kind: ConstraintTemplate
        metadata:
          name: k8sprivilegedcontainer
        spec:
          crd:
            spec:
              names:
                kind: K8sPrivilegedContainer
          targets:
            - target: admission.k8s.gatekeeper.sh
              rego: |
                package k8sprivilegedcontainer

                violation[{"msg": msg}] {
                  container := input.review.object.spec.containers[_]
                  container.securityContext.privileged == true
                  msg := sprintf("Privileged containers are not allowed: %v", [container.name])
                }

                violation[{"msg": msg}] {
                  container := input.review.object.spec.initContainers[_]
                  container.securityContext.privileged == true
                  msg := sprintf("Privileged initContainers are not allowed: %v", [container.name])
                }
        ```

        Apply:

        ```bash theme={null}
        kubectl apply -f ct-deny-privileged-containers.yaml
        ```

        ***

        ## 5. Create a Constraint to Enforce the Template Cluster-wide

        Save as `c-deny-privileged-containers.yaml`:

        ```yaml theme={null}
        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: K8sPrivilegedContainer
        metadata:
          name: deny-privileged-containers
        spec:
          match:
            kinds:
              - apiGroups: [""]
                kinds: ["Pod"]
            # Optionally restrict to certain namespaces:
            # namespaces: ["prod", "staging"]
        ```

        Apply:

        ```bash theme={null}
        kubectl apply -f c-deny-privileged-containers.yaml
        ```

        ***

        ## 6. Test the Policy

        Try to create a privileged pod:

        ```yaml theme={null}
        # test-privileged-pod.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          name: privileged-test
        spec:
          containers:
            - name: busybox
              image: busybox
              command: ["sleep", "3600"]
              securityContext:
                privileged: true
        ```

        ```bash theme={null}
        kubectl apply -f test-privileged-pod.yaml
        ```

        You should see an admission error from Gatekeeper denying the pod.

        ***

        ## 7. (Optional) Scope / Soften the Policy

        * To allow specific namespaces, add them under `spec.match.namespaces`.
        * To exclude system namespaces:

        ```yaml theme={null}
        spec:
          match:
            kinds:
              - apiGroups: [""]
                kinds: ["Pod"]
            excludedNamespaces:
              - kube-system
              - gatekeeper-system
        ```

        Re-apply the constraint if you modify it:

        ```bash theme={null}
        kubectl apply -f c-deny-privileged-containers.yaml
        ```

        ***

        That configuration (enabled via OCI CLI and enforced via OPA Gatekeeper) ensures OKE minimizes and typically blocks admission of privileged containers.
      </Accordion>

      <Accordion title="Using Python">
        Below is a practical way to **remediate “privileged containers” in OCI OKE using Python**, by:

        1. Auditing for privileged containers.
        2. Patching workloads to remove `privileged: true`.
        3. Optionally enforcing Kubernetes Pod Security “restricted” mode at namespace level.

        This uses the official Kubernetes Python client against your OKE cluster.

        ***

        ## 1. Prerequisites

        1. Ensure you can run `kubectl` against your OKE cluster:
           ```bash theme={null}
           kubectl get nodes
           ```
        2. Install Kubernetes Python client:
           ```bash theme={null}
           pip install kubernetes
           ```
        3. Make sure your kubeconfig is available (typically `~/.kube/config`) and points to the OKE cluster.

        ***

        ## 2. Python: Find All Privileged Containers

        This script inspects Pods, Deployments, StatefulSets, DaemonSets, and Jobs for `securityContext.privileged: true` at:

        * container level
        * pod-level `securityContext` (for whole pod)

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

        def is_privileged_container(container):
            sc = getattr(container, "security_context", None)
            return bool(sc and getattr(sc, "privileged", False))

        def is_privileged_pod_spec(pod_spec):
            # pod-level securityContext (if ever used for privileged escalation)
            psc = getattr(pod_spec, "security_context", None)
            if psc and getattr(psc, "privileged", None):
                return True
            # containers
            for c in getattr(pod_spec, "containers", []):
                if is_privileged_container(c):
                    return True
            # initContainers
            for c in getattr(pod_spec, "init_containers", []):
                if is_privileged_container(c):
                    return True
            return False

        def main():
            config.load_kube_config()  # or config.load_incluster_config()

            core = client.CoreV1Api()
            apps = client.AppsV1Api()
            batch = client.BatchV1Api()

            print("Checking Pods...")
            for ns in [n.metadata.name for n in core.list_namespace().items]:
                pods = core.list_namespaced_pod(ns)
                for p in pods.items:
                    if is_privileged_pod_spec(p.spec):
                        print(f"[POD] {ns}/{p.metadata.name} has privileged containers")

            print("Checking Deployments...")
            for ns in [n.metadata.name for n in core.list_namespace().items]:
                deps = apps.list_namespaced_deployment(ns)
                for d in deps.items:
                    if is_privileged_pod_spec(d.spec.template.spec):
                        print(f"[DEPLOYMENT] {ns}/{d.metadata.name} has privileged containers")

            print("Checking StatefulSets...")
            for ns in [n.metadata.name for n in core.list_namespace().items]:
                ssets = apps.list_namespaced_stateful_set(ns)
                for s in ssets.items:
                    if is_privileged_pod_spec(s.spec.template.spec):
                        print(f"[STATEFULSET] {ns}/{s.metadata.name} has privileged containers")

            print("Checking DaemonSets...")
            for ns in [n.metadata.name for n in core.list_namespace().items]:
                dsets = apps.list_namespaced_daemon_set(ns)
                for d in dsets.items:
                    if is_privileged_pod_spec(d.spec.template.spec):
                        print(f"[DAEMONSET] {ns}/{d.metadata.name} has privileged containers")

            print("Checking Jobs...")
            for ns in [n.metadata.name for n in core.list_namespace().items]:
                jobs = batch.list_namespaced_job(ns)
                for j in jobs.items:
                    if is_privileged_pod_spec(j.spec.template.spec):
                        print(f"[JOB] {ns}/{j.metadata.name} has privileged containers")

        if __name__ == "__main__":
            main()
        ```

        Run it and review output. Confirm which workloads truly need privilege (ideally none).

        ***

        ## 3. Python: Patch Workloads to Remove `privileged: true`

        Below is a **targeted patch** for Deployments; you can adapt the same logic for StatefulSets, DaemonSets, and Jobs.

        This:

        * Loads the Deployment.
        * Iterates containers and initContainers.
        * Deletes or sets `securityContext.privileged` to `false`.
        * Patches the Deployment.

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

        def remove_privileged_from_container_dict(c_dict):
            sc = c_dict.get("securityContext")
            if sc is None:
                return
            # Remove only the privileged flag
            sc.pop("privileged", None)
            # Clean empty securityContext
            if not sc:
                c_dict.pop("securityContext", None)

        def patch_deployment_remove_privileged(namespace, name):
            config.load_kube_config()
            apps = client.AppsV1Api()

            dep = apps.read_namespaced_deployment(name=name, namespace=namespace)
            tmpl_spec = dep.spec.template.spec

            # Build patch by converting to dict and editing
            dep_dict = dep.to_dict()
            tmpl = dep_dict["spec"]["template"]["spec"]

            changed = False

            for c in tmpl.get("containers", []):
                before = deepcopy(c)
                remove_privileged_from_container_dict(c)
                if before != c:
                    changed = True

            for c in tmpl.get("init_containers", []) or []:
                before = deepcopy(c)
                remove_privileged_from_container_dict(c)
                if before != c:
                    changed = True

            # If pod-level securityContext has "privileged", remove it
            psc = tmpl.get("security_context")
            if psc and "privileged" in psc:
                psc.pop("privileged", None)
                if not psc:
                    tmpl.pop("security_context", None)
                changed = True

            if not changed:
                print(f"No privileged containers found in deployment {namespace}/{name}")
                return

            patch_body = {
                "spec": {
                    "template": {
                        "spec": tmpl
                    }
                }
            }

            resp = apps.patch_namespaced_deployment(
                name=name,
                namespace=namespace,
                body=patch_body,
            )
            print(f"Patched deployment {namespace}/{name}, new generation: {resp.metadata.generation}")

        if __name__ == "__main__":
            # Example usage
            patch_deployment_remove_privileged("default", "my-deployment")
        ```

        Extend this pattern for other controller types by using:

        * `apps.read_namespaced_stateful_set` / `patch_namespaced_stateful_set`
        * `apps.read_namespaced_daemon_set` / `patch_namespaced_daemon_set`
        * `batch.read_namespaced_job` / `patch_namespaced_job`

        ***

        ## 4. Enforce “No Privileged” Using Pod Security Admission (Recommended)

        For Kubernetes 1.25+ (where PodSecurityPolicy is removed), use **Pod Security Admission** labels.

        At the namespace level, you can enforce the **restricted** profile (which denies privileged containers) using Python:

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

        def label_namespace_restricted(namespace):
            config.load_kube_config()
            core = client.CoreV1Api()

            body = {
                "metadata": {
                    "labels": {
                        "pod-security.kubernetes.io/enforce": "restricted",
                        "pod-security.kubernetes.io/enforce-version": "latest"
                    }
                }
            }

            resp = core.patch_namespace(name=namespace, body=body)
            print(f"Namespace {namespace} labeled for restricted Pod Security; resourceVersion={resp.metadata.resource_version}")

        if __name__ == "__main__":
            # Example: apply to non-system namespaces
            config.load_kube_config()
            core = client.CoreV1Api()
            for ns in core.list_namespace().items:
                name = ns.metadata.name
                if name in ("kube-system", "kube-public", "oci-system", "oracle-system"):
                    continue
                label_namespace_restricted(name)
        ```

        After applying:

        * Any new Pod/Deployment/Job with `securityContext.privileged: true` will be rejected by the API server.

        ***

        ## 5. Operational Flow

        1. **Audit:** Run the audit script to identify all privileged containers.
        2. **Discuss/validate:** Confirm with app owners which workloads (if any) truly need elevated privileges.
        3. **Patch:** Use the patch script to remove `privileged: true` from those that don’t need it.
        4. **Enforce:** Label namespaces with Pod Security **restricted** using the last script so future privileged pods are blocked in OKE.
        5. **CI/CD integration (optional):** Run the audit-or-fail script in your pipeline to prevent regressions.

        If you share your Kubernetes version and whether you’re already using Gatekeeper/OPA on OKE, I can tailor this to that setup as well.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # There is currently no argument on `oci_containerengine_cluster` (the
        # Terraform resource behind the "oci-containers-oke-cluster" surface)
        # that can deny privileged containers at admission time.
        #
        # OKE enforces this via Kubernetes-level admission controls (e.g. Pod
        # Security Admission labels, Gatekeeper/OPA policies, or equivalent),
        # which must be configured inside the cluster, not on the cluster
        # resource itself.

        # Example: create the OKE cluster (no field here can block privileged pods)
        resource "oci_containerengine_cluster" "oke" {
          name           = "MY_OKE_CLUSTER_NAME"        # substitute your cluster name
          compartment_id = "OCID_OF_COMPARTMENT"        # substitute your compartment OCID
          vcn_id         = "OCID_OF_VCN"                # substitute your VCN OCID

          kubernetes_version = "v1.30.1"                # example version

          options {
            service_lb_subnet_ids = [
              "OCID_OF_SUBNET_1",
              "OCID_OF_SUBNET_2",
            ]
          }
        }

        # To actually minimize admission of privileged containers you must:
        # - Use a Kubernetes provider/Helm in Terraform to install and configure:
        #   - Pod Security Admission (PSA) labels on namespaces, and/or
        #   - Gatekeeper/OPA or another admission controller with policies that
        #     `deny` pods setting `securityContext.privileged: true`, except for
        #     narrowly-scoped, signed workloads.
        #
        # Those controls are expressed as Kubernetes manifests, not as fields on
        # `oci_containerengine_cluster`, so they cannot be implemented on that
        # exact resource type.

        # Verification:
        # - `terraform plan` against the `oci_containerengine_cluster` resource
        #   will show no changes related to privileged-container admission,
        #   because the provider does not expose such a setting on this resource.
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
