Ensure Shielded GKE Nodes Are Enabled
More Info:
Enable Shielded GKE Nodes to provide verifiable node identity and integrity via secure boot and vTPM protections. This defends against boot-level and kernel-level tampering.
Risk Level
High
Address
Security
Compliance Standards
- CIS GKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On any machine with
gcloudconfigured, list clusters and identify those to review:gcloud container clusters list --project YOUR_PROJECT_ID --format="table(name,location,shieldedNodes)"Note clusters where
shieldedNodesis empty orFalse. -
For each cluster to review, gather detailed shielded nodes status and record the output for change review:
gcloud container clusters describe CLUSTER_NAME \--location LOCATION \--project YOUR_PROJECT_ID \--format="json(shieldedNodes)"Confirm whether
"enabled": trueis present. -
With your security/operations stakeholders, decide whether Shielded GKE Nodes should be enforced for this cluster, considering: required node images, any dependency on custom bootloaders or kernel modules, and compatibility with secure boot/vTPM.
-
If you decide to enable Shielded GKE Nodes, schedule a maintenance window and update the cluster:
gcloud container clusters update CLUSTER_NAME \--location LOCATION \--project YOUR_PROJECT_ID \--enable-shielded-nodesBe aware that this changes how new and re-created nodes are provisioned and may trigger node recreations depending on your cluster configuration and subsequent operations (e.g., upgrades or node pool recreations).
-
After the update completes, verify the setting is now enabled:
gcloud container clusters describe CLUSTER_NAME \--location LOCATION \--project YOUR_PROJECT_ID \--format="json(shieldedNodes)"Confirm the result shows:
{"enabled": true} -
Optionally, for each node pool, confirm that new nodes are being created as shielded nodes by inspecting instance details in the Google Cloud Console (Compute Engine → VM instances) and validating Shielded VM settings, or via CLI:
gcloud compute instances describe INSTANCE_NAME \--zone ZONE \--project YOUR_PROJECT_ID \--format="json(shieldedInstanceConfig)"
Using kubectl
kubectl cannot enable Shielded GKE Nodes because this setting is part of the managed GKE control-plane/cluster configuration, changed only via the Google Cloud console, gcloud CLI, or IaC. Refer to the Manual Steps section for the exact gcloud command and configuration changes required.
Automation
#!/usr/bin/env bash
#
# Report Shielded GKE Nodes status for all clusters in one or more projects.
# Requirements:
# - gcloud
# - jq
#
# Usage examples:
# ./check_shielded_gke_nodes.sh # use current gcloud project
# GCP_PROJECTS="proj-a proj-b" ./check_shielded_gke_nodes.sh
set -euo pipefail
# Projects to check: space‑separated list in GCP_PROJECTS, or current gcloud project if unset
if [[ -n "${GCP_PROJECTS:-}" ]]; then
PROJECTS=${GCP_PROJECTS}
else
PROJECTS=$(gcloud config get-value project 2>/dev/null || true)
fi
if [[ -z "${PROJECTS}" ]]; then
echo "ERROR: No GCP project configured. Set GCP_PROJECTS or 'gcloud config set project ...'." >&2
exit 1
fi
echo "Checking Shielded GKE Nodes status..."
echo
for PROJECT in ${PROJECTS}; do
echo "=== Project: ${PROJECT} ==="
# List all clusters in all locations for the project
CLUSTERS_JSON=$(gcloud container clusters list \
--project "${PROJECT}" \
--format json 2>/dev/null || true)
if [[ "${CLUSTERS_JSON}" == "[]" || -z "${CLUSTERS_JSON}" ]]; then
echo " No clusters found."
echo
continue
fi
echo "${CLUSTERS_JSON}" | jq -r '.[] | [.name, .location] | @tsv' | while IFS=$'\t' read -r CLUSTER LOCATION; do
# Describe each cluster to get shieldedNodes status
DESC=$(gcloud container clusters describe "${CLUSTER}" \
--location "${LOCATION}" \
--project "${PROJECT}" \
--format json 2>/dev/null || true)
if [[ -z "${DESC}" ]]; then
echo " [ERROR] Failed to describe cluster ${CLUSTER} (${LOCATION})"
continue
fi
SHIELDED_ENABLED=$(echo "${DESC}" | jq -r '.shieldedNodes.enabled // "false"')
RELEASE_CHANNEL=$(echo "${DESC}" | jq -r '.releaseChannel.channel // "UNSPECIFIED"')
if [[ "${SHIELDED_ENABLED}" == "true" ]]; then
STATUS="OK"
else
STATUS="NON-COMPLIANT"
fi
printf " Cluster: %-30s Location: %-12s ShieldedNodes: %-5s ReleaseChannel: %s\n" \
"${CLUSTER}" "${LOCATION}" "${SHIELDED_ENABLED}" "${RELEASE_CHANNEL}"
if [[ "${STATUS}" == "NON-COMPLIANT" ]]; then
echo " -> REVIEW: Shielded GKE Nodes are DISABLED for this cluster."
fi
done
echo
done
Explanation of output indicating a problem:
-
For each cluster, look at the
ShieldedNodesfield in the printed line. -
ShieldedNodes: true→ compliant with the control. -
ShieldedNodes: false→ problem; line is annotated with:-> REVIEW: Shielded GKE Nodes are DISABLED for this cluster.
Those clusters with ShieldedNodes: false are candidates for manual review and possible remediation using:
gcloud container clusters update <cluster_name> --location <location> --enable-shielded-nodes