CIS Google Kubernetes Engine (GKE) Benchmark
Security configuration recommendations for Google Kubernetes Engine clusters
v1.6.0 02-2025Overview
▶This benchmark provides prescriptive guidance for establishing a secure configuration posture for Google Kubernetes Engine (GKE). It covers cluster configuration, node security, networking, logging, pod security policies, binary authorization, and secrets management using gcloud CLI and kubectl commands.
| Section | Area | Focus |
|---|---|---|
| 1 | Cluster Configuration | Workload Identity, RBAC, ABAC, network policy, and master authorized networks |
| 2 | Node Security | COS images, auto-upgrade/repair, shielded nodes, and dedicated service accounts |
| 3 | Networking | Private clusters, VPC-native mode, intranode visibility, and network policies |
| 4 | Logging & Monitoring | Cloud Logging and Cloud Monitoring integration |
| 5 | Pod Security | Pod Security Standards, privileged containers, non-root, and Binary Authorization |
| 6 | Secrets Management | Application-layer encryption and Google Secret Manager integration |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Standard | Essential security for all GKE deployments; minimal performance impact. |
| L2 | Level 2 — Hardened | Advanced hardening for PCI-DSS, HIPAA, or high-security environments. |
1 — Cluster Configuration
▶1.1 Identity & Access
▶This recommendation verifies that Workload Identity is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify Workload Identity is enabled on the cluster: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(workloadIdentityConfig.workloadPool)' # Should return: PROJECT_ID.svc.id.goog
# Enable Workload Identity on existing cluster: gcloud container clusters update CLUSTER_NAME \ --zone ZONE \ --workload-pool=PROJECT_ID.svc.id.goog # Enable on node pool: gcloud container node-pools update POOL_NAME \ --cluster=CLUSTER_NAME --zone ZONE \ --workload-metadata=GKE_METADATA
This recommendation verifies that legacy ABAC authorization is disabled on the GKE managed Kubernetes platform. Disabling or removing unnecessary components reduces the attack surface and limits potential vectors for exploitation.
Running unnecessary components on the GKE managed Kubernetes platform increases the attack surface and the risk of exploitation. Disabling or removing them follows the principle of least functionality and reduces exposure to known vulnerabilities.
# Verify legacy ABAC is disabled: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(legacyAbac.enabled)' # Should return empty or False
# Disable legacy ABAC: gcloud container clusters update CLUSTER_NAME \ --zone ZONE --no-enable-legacy-authorization
This recommendation verifies that RBAC is configured on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify RBAC is enabled (default on GKE 1.6+): kubectl api-versions | grep rbac.authorization.k8s.io # List cluster role bindings: kubectl get clusterrolebindings -o wide | grep -v system:
# Create appropriate RBAC roles: kubectl create clusterrole read-only \ --verb=get,list,watch --resource=pods,services,deployments kubectl create clusterrolebinding read-only-binding \ --clusterrole=read-only --user=user@example.com
This recommendation verifies that Network Policy is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify network policy is enabled: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(networkPolicy.enabled)' # Also check Dataplane V2 (Cilium): gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(networkConfig.datapathProvider)'
# Enable network policy on cluster: gcloud container clusters update CLUSTER_NAME \ --zone ZONE --enable-network-policy # Or enable Dataplane V2 (recommended, at creation): gcloud container clusters create CLUSTER_NAME \ --zone ZONE --enable-dataplane-v2
This recommendation verifies that master authorized networks are configured on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify master authorized networks: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(masterAuthorizedNetworksConfig)' # Should show enabled with CIDR blocks
# Enable master authorized networks: gcloud container clusters update CLUSTER_NAME \ --zone ZONE \ --enable-master-authorized-networks \ --master-authorized-networks 10.0.0.0/8,172.16.0.0/12
2 — Node Security
▶2.1 Node Configuration
▶This recommendation verifies that Container-Optimized OS is used for node images on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify Container-Optimized OS is used: gcloud container node-pools list --cluster CLUSTER_NAME \ --zone ZONE --format='table(name,config.imageType)' # Should show COS_CONTAINERD
# Create node pool with COS: gcloud container node-pools create secure-pool \ --cluster=CLUSTER_NAME --zone ZONE \ --image-type=COS_CONTAINERD # Update existing: gcloud container node-pools update POOL_NAME \ --cluster=CLUSTER_NAME --zone ZONE \ --image-type=COS_CONTAINERD
This recommendation verifies that automatic node upgrades are enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify auto-upgrade is enabled per node pool: gcloud container node-pools describe POOL_NAME \ --cluster CLUSTER_NAME --zone ZONE \ --format='value(management.autoUpgrade)'
# Enable auto-upgrade: gcloud container node-pools update POOL_NAME \ --cluster=CLUSTER_NAME --zone ZONE \ --enable-autoupgrade
This recommendation verifies that automatic node repair is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify auto-repair is enabled: gcloud container node-pools describe POOL_NAME \ --cluster CLUSTER_NAME --zone ZONE \ --format='value(management.autoRepair)'
# Enable auto-repair: gcloud container node-pools update POOL_NAME \ --cluster=CLUSTER_NAME --zone ZONE \ --enable-autorepair
This recommendation verifies that Shielded GKE Nodes are enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify Shielded GKE Nodes: gcloud container node-pools describe POOL_NAME \ --cluster CLUSTER_NAME --zone ZONE \ --format='value(config.shieldedInstanceConfig)' # Check secure boot and vTPM: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(shieldedNodes.enabled)'
# Enable shielded nodes on cluster: gcloud container clusters update CLUSTER_NAME \ --zone ZONE --enable-shielded-nodes # Create node pool with shielded config: gcloud container node-pools create secure-pool \ --cluster=CLUSTER_NAME --zone ZONE \ --shielded-secure-boot --shielded-integrity-monitoring
This recommendation verifies that nodes use a dedicated service account on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify node service account is NOT default compute: gcloud container node-pools describe POOL_NAME \ --cluster CLUSTER_NAME --zone ZONE \ --format='value(config.serviceAccount)' # Should NOT show 'default'
# Create dedicated SA for GKE nodes: gcloud iam service-accounts create gke-node-sa \ --display-name='GKE Node Service Account' # Grant minimal permissions: gcloud projects add-iam-policy-binding PROJECT_ID \ --member='serviceAccount:gke-node-sa@PROJECT_ID.iam.gserviceaccount.com' \ --role='roles/logging.logWriter' gcloud projects add-iam-policy-binding PROJECT_ID \ --member='serviceAccount:gke-node-sa@PROJECT_ID.iam.gserviceaccount.com' \ --role='roles/monitoring.metricWriter' # Create node pool with dedicated SA: gcloud container node-pools create secure-pool \ --cluster=CLUSTER_NAME --zone ZONE \ --service-account=gke-node-sa@PROJECT_ID.iam.gserviceaccount.com
3 — Networking
▶3.1 Cluster Networking
▶This recommendation verifies that private cluster is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify private cluster (private nodes): gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(privateClusterConfig.enablePrivateNodes)' # Check private endpoint: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(privateClusterConfig.enablePrivateEndpoint)'
# Create private cluster: gcloud container clusters create CLUSTER_NAME \ --zone ZONE \ --enable-private-nodes \ --master-ipv4-cidr=172.16.0.0/28 \ --enable-ip-alias
This recommendation verifies that VPC-native clusters are used on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify VPC-native (alias IP) mode: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(ipAllocationPolicy.useIpAliases)' # Should return True
# Create VPC-native cluster: gcloud container clusters create CLUSTER_NAME \ --zone ZONE --enable-ip-alias \ --cluster-ipv4-cidr=/16 --services-ipv4-cidr=/22
This recommendation verifies that intranode visibility is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify intranode visibility: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(networkConfig.enableIntraNodeVisibility)'
# Enable intranode visibility: gcloud container clusters update CLUSTER_NAME \ --zone ZONE --enable-intra-node-visibility
3.2 Network Policies
▶This recommendation verifies that default deny network policies are configured on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check for default deny network policies: kubectl get networkpolicies --all-namespaces # Verify default deny exists: kubectl get networkpolicy default-deny -n default -o yaml 2>/dev/null
# Create default deny all ingress policy:
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
EOF4 — Logging & Monitoring
▶4.1 Observability
▶This recommendation verifies that Cloud Logging is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify Cloud Logging is enabled: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(loggingService)' # Should return: logging.googleapis.com/kubernetes
# Enable Cloud Logging: gcloud container clusters update CLUSTER_NAME \ --zone ZONE --logging=SYSTEM,WORKLOAD
This recommendation verifies that Cloud Monitoring is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify Cloud Monitoring is enabled: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(monitoringService)' # Should return: monitoring.googleapis.com/kubernetes
# Enable Cloud Monitoring: gcloud container clusters update CLUSTER_NAME \ --zone ZONE --monitoring=SYSTEM,WORKLOAD
5 — Pod Security
▶5.1 Pod Configuration
▶This recommendation ensures that Pod Security Standards are enforced on the GKE managed Kubernetes platform. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.
Without this enforcement, the GKE managed Kubernetes platform may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.
# Verify Pod Security Standards (PSS) admission: kubectl get ns --show-labels | grep pod-security # Check for PodSecurityPolicy (deprecated in 1.25+): kubectl get psp 2>/dev/null
# Apply Pod Security Standards to namespaces: kubectl label ns default \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/warn=restricted \ pod-security.kubernetes.io/audit=restricted
This recommendation verifies that privileged containers are not used on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check for privileged containers: kubectl get pods --all-namespaces -o json | \ jq -r '.items[] | select(.spec.containers[].securityContext.privileged==true) | .metadata.namespace + "/" + .metadata.name'
# Remove privileged flag from pod spec:
# In deployment YAML, set:
# spec:
# containers:
# - name: app
# securityContext:
# privileged: false
# allowPrivilegeEscalation: false
# readOnlyRootFilesystem: true
# runAsNonRoot: true
kubectl patch deployment APP_NAME -p '{"spec":{"template":{"spec":{"containers":[{"name":"app","securityContext":{"privileged":false}}]}}}}'This recommendation verifies that containers run as non-root on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check for containers running as root: kubectl get pods --all-namespaces -o json | \ jq -r '.items[] | select(.spec.containers[].securityContext.runAsNonRoot!=true) | .metadata.namespace + "/" + .metadata.name'
# Configure pods to run as non-root: # In deployment YAML: # spec: # containers: # - name: app # securityContext: # runAsNonRoot: true # runAsUser: 1000 # runAsGroup: 1000
5.2 Binary Authorization
▶This recommendation verifies that Binary Authorization is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify Binary Authorization is enabled: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(binaryAuthorization)' # Check the policy: gcloud container binauthz policy export
# Enable Binary Authorization: gcloud container clusters update CLUSTER_NAME \ --zone ZONE --enable-binauthz # Set default deny policy: gcloud container binauthz policy import - <<EOF admissionWhitelistPatterns: - namePattern: gcr.io/google_containers/* - namePattern: gcr.io/google-containers/* defaultAdmissionRule: enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG evaluationMode: ALWAYS_DENY globalPolicyEvaluationMode: ENABLE EOF
6 — Secrets Management
▶6.1 Secrets Encryption
▶This recommendation verifies that application-layer secrets encryption is enabled on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Verify application-layer secrets encryption: gcloud container clusters describe CLUSTER_NAME \ --zone ZONE --format='value(databaseEncryption)' # Should show state: ENCRYPTED with a KMS key
# Enable application-layer secrets encryption: gcloud container clusters update CLUSTER_NAME \ --zone ZONE \ --database-encryption-key=projects/PROJECT_ID/locations/LOCATION/keyRings/RING/cryptoKeys/KEY
This recommendation verifies that secrets are stored in Secret Manager on the GKE managed Kubernetes platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GKE managed Kubernetes platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Audit Kubernetes secrets: kubectl get secrets --all-namespaces -o json | \ jq -r '.items[] | select(.type=="Opaque") | .metadata.namespace + "/" + .metadata.name' # Check if Secret Manager is used instead: gcloud secrets list --format='table(name,createTime)' 2>/dev/null
# Use Google Secret Manager with Workload Identity: # Install secrets-store-csi-driver: kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/secrets-store-csi-driver/main/deploy/rbac-secretproviderclass.yaml # Store secrets in Secret Manager: gcloud secrets create my-secret --data-file=secret.txt