> ## 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 Integrity Monitoring For Shielded GKE Nodes Is Enabled

### More Info:

Enable integrity monitoring on Shielded GKE nodes so their boot integrity is continuously verified against a trusted baseline. This detects rootkits and boot-level tampering.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS GKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify node pools and current integrity monitoring settings**\
           Run on: any machine with `gcloud` access
           ```bash theme={null}
           PROJECT_ID="<PROJECT_ID>"
           CLUSTER_NAME="<CLUSTER_NAME>"
           LOCATION="<REGION_OR_ZONE>"

           gcloud container node-pools list \
             --cluster "$CLUSTER_NAME" \
             --location "$LOCATION" \
             --project "$PROJECT_ID"
           ```
           For each node pool name returned:
           ```bash theme={null}
           POOL_NAME="<POOL_NAME>"

           gcloud container node-pools describe "$POOL_NAME" \
             --cluster "$CLUSTER_NAME" \
             --location "$LOCATION" \
             --project "$PROJECT_ID" \
             --format json | jq .config.shieldedInstanceConfig
           ```

        2. **Determine compliance for each node pool**
           * Mark a node pool as **compliant** if:
             * `enabled` is `true` and `integrityMonitoring` (or equivalent flag) is `true`, or
             * The `shieldedInstanceConfig` block clearly shows integrity monitoring enabled.
           * Mark a node pool as **non-compliant** if integrity monitoring is not enabled or the field is absent.

        3. **Plan new compliant node pools for non-compliant workloads**\
           For each non-compliant node pool, decide:
           * Desired machine type, disk size/type, labels, taints, autoscaling, and node count.
           * A new node pool name that indicates shielded + integrity monitoring (for traceability).\
             Then create the new node pool with integrity monitoring enabled:
           ```bash theme={null}
           NEW_POOL_NAME="<NEW_SHIELDED_POOL_NAME>"

           gcloud container node-pools create "$NEW_POOL_NAME" \
             --cluster "$CLUSTER_NAME" \
             --location "$LOCATION" \
             --project "$PROJECT_ID" \
             --shielded-integrity-monitoring
           ```
           Add any other flags (e.g. `--machine-type`, `--num-nodes`, `--enable-autoscaling`, `--node-taints`, `--node-labels`) to match your current non-compliant pool.

        4. **Migrate workloads from non-compliant to compliant node pools**\
           Run on: any machine with `kubectl` access
           * If node pools are distinguished by labels/taints, adjust pod `nodeSelector`, `affinity`, or tolerations so workloads can schedule on the new pool.
           * Cordon and drain each non-compliant node pool’s nodes one at a time:
             ```bash theme={null}
             kubectl get nodes -o wide
             # For each node belonging to a non-compliant pool:
             NODE_NAME="<NODE_NAME>"

             kubectl cordon "$NODE_NAME"
             kubectl drain "$NODE_NAME" --ignore-daemonsets --delete-emptydir-data
             ```
           * Verify pods reschedule onto the new, compliant node pool:
             ```bash theme={null}
             kubectl get pods -A -o wide
             ```

        5. **Delete non-compliant node pools after successful migration**\
           Once you confirm workloads are healthy on the new node pool(s):
           ```bash theme={null}
           POOL_NAME="<NON_COMPLIANT_POOL_NAME>"

           gcloud container node-pools delete "$POOL_NAME" \
             --cluster "$CLUSTER_NAME" \
             --location "$LOCATION" \
             --project "$PROJECT_ID"
           ```

        6. **Verify remediation**\
           Re-run the audit for each remaining node pool:
           ```bash theme={null}
           gcloud container node-pools list \
             --cluster "$CLUSTER_NAME" \
             --location "$LOCATION" \
             --project "$PROJECT_ID"

           # For each listed pool:
           POOL_NAME="<POOL_NAME>"

           gcloud container node-pools describe "$POOL_NAME" \
             --cluster "$CLUSTER_NAME" \
             --location "$LOCATION" \
             --project "$PROJECT_ID" \
             --format json | jq .config.shieldedInstanceConfig
           ```
           Confirm all node pools in use show integrity monitoring enabled.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot enable Shielded GKE node integrity monitoring because this setting is defined on the managed node pool in GKE (cloud provider control plane / IaC), not on Kubernetes API objects. Use the cloud console, `gcloud`, or your IaC pipeline to configure integrity monitoring as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Report Shielded GKE node pool integrity monitoring status for all clusters
        # in a given project. Requires:
        #   - gcloud CLI authenticated and configured
        #   - jq installed
        #
        # Usage:
        #   PROJECT_ID="my-project" LOCATION="us-central1" ./check_shielded_integrity.sh
        #
        # LOCATION can be:
        #   - a specific region/zone (e.g. "us-central1", "us-central1-a"), or
        #   - "-" to search all locations in the project.

        set -euo pipefail

        PROJECT_ID="${PROJECT_ID:-}"
        LOCATION="${LOCATION:-"-"}"

        if [[ -z "$PROJECT_ID" ]]; then
          echo "ERROR: Set PROJECT_ID environment variable." >&2
          exit 1
        fi

        echo "Checking Shielded GKE node pool integrity monitoring in project: $PROJECT_ID (location: $LOCATION)"
        echo

        # List all clusters in the project/location
        clusters_json="$(gcloud container clusters list \
          --project "$PROJECT_ID" \
          --location "$LOCATION" \
          --format json)"

        if [[ "$(echo "$clusters_json" | jq 'length')" -eq 0 ]]; then
          echo "No GKE clusters found."
          exit 0
        fi

        echo "$clusters_json" | jq -r '.[] | @tsv "\(.name)\t\(.location)"' | \
        while IFS=$'\t' read -r CLUSTER_NAME CLUSTER_LOCATION; do
          echo "Cluster: $CLUSTER_NAME  (location: $CLUSTER_LOCATION)"
          
          node_pools_json="$(gcloud container node-pools list \
            --cluster "$CLUSTER_NAME" \
            --location "$CLUSTER_LOCATION" \
            --project "$PROJECT_ID" \
            --format json)"

          if [[ "$(echo "$node_pools_json" | jq 'length')" -eq 0 ]]; then
            echo "  (no node pools)"
            echo
            continue
          fi

          echo "$node_pools_json" | jq -r '.[] | @tsv "\(.name)\t\(.config.shieldedInstanceConfig.enableIntegrityMonitoring)"' | \
          while IFS=$'\t' read -r POOL_NAME INTEGRITY; do
            # INTEGRITY may be "true", "false", or "null" (if not set)
            case "$INTEGRITY" in
              true)
                echo "  Node pool: $POOL_NAME  -> integrity monitoring: ENABLED"
                ;;
              false|null|"")
                echo "  Node pool: $POOL_NAME  -> integrity monitoring: DISABLED  <-- REVIEW / NON-COMPLIANT"
                ;;
              *)
                echo "  Node pool: $POOL_NAME  -> integrity monitoring: UNKNOWN ($INTEGRITY)  <-- REVIEW"
                ;;
            esac
          done

          echo
        done
        ```

        **How to run (any machine with gcloud and kubectl access):**

        1. Authenticate and set project:
           ```bash theme={null}
           gcloud auth login
           gcloud config set project YOUR_PROJECT_ID
           ```
        2. Run the script:
           ```bash theme={null}
           PROJECT_ID="YOUR_PROJECT_ID" LOCATION="-" ./check_shielded_integrity.sh
           ```

        **What output indicates a problem**

        Any node pool line showing:

        * `integrity monitoring: DISABLED  <-- REVIEW / NON-COMPLIANT`, or
        * `integrity monitoring: UNKNOWN (...)  <-- REVIEW`

        indicates a node pool where Shielded GKE node integrity monitoring is not confirmed as enabled and must be reviewed and, if appropriate, remediated manually by creating a compliant node pool and migrating workloads.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
