CIS Google Kubernetes Engine (GKE) Benchmark

Security configuration recommendations for Google Kubernetes Engine clusters

v1.6.0 02-2025

Overview

▶

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.

23Recommendations
6Sections
2Profile Levels
SectionAreaFocus
1Cluster ConfigurationWorkload Identity, RBAC, ABAC, network policy, and master authorized networks
2Node SecurityCOS images, auto-upgrade/repair, shielded nodes, and dedicated service accounts
3NetworkingPrivate clusters, VPC-native mode, intranode visibility, and network policies
4Logging & MonitoringCloud Logging and Cloud Monitoring integration
5Pod SecurityPod Security Standards, privileged containers, non-root, and Binary Authorization
6Secrets ManagementApplication-layer encryption and Google Secret Manager integration

Profile Definitions

▶
ProfileDescriptionIntended Use
L1Level 1 — StandardEssential security for all GKE deployments; minimal performance impact.
L2Level 2 — HardenedAdvanced hardening for PCI-DSS, HIPAA, or high-security environments.

1 — Cluster Configuration

▶

1.1 Identity & Access

▶
1.1.1 Ensure Workload Identity is enabled (Automated)
L1 Auto
Description

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.

Rationale

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
# 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
Remediation
# 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
1.1.2 Ensure legacy ABAC authorization is disabled (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# Verify legacy ABAC is disabled:
gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE --format='value(legacyAbac.enabled)'

# Should return empty or False
Remediation
# Disable legacy ABAC:
gcloud container clusters update CLUSTER_NAME \
  --zone ZONE --no-enable-legacy-authorization
1.1.3 Ensure RBAC is configured (Automated)
L1 Auto
Description

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.

Rationale

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
# 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:
Remediation
# 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
1.1.4 Ensure Network Policy is enabled (Automated)
L1 Auto
Description

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.

Rationale

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
# 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)'
Remediation
# 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
1.1.5 Ensure master authorized networks are configured (Automated)
L1 Auto
Description

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.

Rationale

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
# Verify master authorized networks:
gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE --format='value(masterAuthorizedNetworksConfig)'

# Should show enabled with CIDR blocks
Remediation
# 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

▶
2.1.1 Ensure Container-Optimized OS is used for node images (Automated)
L1 Auto
Description

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.

Rationale

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
# 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
Remediation
# 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
2.1.2 Ensure automatic node upgrades are enabled (Automated)
L1 Auto
Description

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.

Rationale

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
# Verify auto-upgrade is enabled per node pool:
gcloud container node-pools describe POOL_NAME \
  --cluster CLUSTER_NAME --zone ZONE \
  --format='value(management.autoUpgrade)'
Remediation
# Enable auto-upgrade:
gcloud container node-pools update POOL_NAME \
  --cluster=CLUSTER_NAME --zone ZONE \
  --enable-autoupgrade
2.1.3 Ensure automatic node repair is enabled (Automated)
L1 Auto
Description

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.

Rationale

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
# Verify auto-repair is enabled:
gcloud container node-pools describe POOL_NAME \
  --cluster CLUSTER_NAME --zone ZONE \
  --format='value(management.autoRepair)'
Remediation
# Enable auto-repair:
gcloud container node-pools update POOL_NAME \
  --cluster=CLUSTER_NAME --zone ZONE \
  --enable-autorepair
2.1.4 Ensure Shielded GKE Nodes are enabled (Automated)
L2 Auto
Description

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.

Rationale

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
# 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)'
Remediation
# 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
2.1.5 Ensure nodes use a dedicated service account (Automated)
L1 Auto
Description

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.

Rationale

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
# 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'
Remediation
# 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

▶
3.1.1 Ensure private cluster is enabled (Automated)
L1 Auto
Description

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.

Rationale

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
# 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)'
Remediation
# 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
3.1.2 Ensure VPC-native clusters are used (Automated)
L1 Auto
Description

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.

Rationale

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
# Verify VPC-native (alias IP) mode:
gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE --format='value(ipAllocationPolicy.useIpAliases)'

# Should return True
Remediation
# Create VPC-native cluster:
gcloud container clusters create CLUSTER_NAME \
  --zone ZONE --enable-ip-alias \
  --cluster-ipv4-cidr=/16 --services-ipv4-cidr=/22
3.1.3 Ensure intranode visibility is enabled (Automated)
L2 Auto
Description

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.

Rationale

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
# Verify intranode visibility:
gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE --format='value(networkConfig.enableIntraNodeVisibility)'
Remediation
# Enable intranode visibility:
gcloud container clusters update CLUSTER_NAME \
  --zone ZONE --enable-intra-node-visibility

3.2 Network Policies

▶
3.2.1 Ensure default deny network policies are configured (Manual)
L1 Manual
Description

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.

Rationale

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
# 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
Remediation
# 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
EOF

4 — Logging & Monitoring

▶

4.1 Observability

▶
4.1.1 Ensure Cloud Logging is enabled (Automated)
L1 Auto
Description

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.

Rationale

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
# Verify Cloud Logging is enabled:
gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE --format='value(loggingService)'

# Should return: logging.googleapis.com/kubernetes
Remediation
# Enable Cloud Logging:
gcloud container clusters update CLUSTER_NAME \
  --zone ZONE --logging=SYSTEM,WORKLOAD
4.1.2 Ensure Cloud Monitoring is enabled (Automated)
L1 Auto
Description

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.

Rationale

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
# Verify Cloud Monitoring is enabled:
gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE --format='value(monitoringService)'

# Should return: monitoring.googleapis.com/kubernetes
Remediation
# Enable Cloud Monitoring:
gcloud container clusters update CLUSTER_NAME \
  --zone ZONE --monitoring=SYSTEM,WORKLOAD

5 — Pod Security

▶

5.1 Pod Configuration

▶
5.1.1 Ensure Pod Security Standards are enforced (Automated)
L1 Auto
Description

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.

Rationale

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.

Audit
# 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
Remediation
# 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
5.1.2 Ensure privileged containers are not used (Automated)
L1 Auto
Description

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.

Rationale

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
# Check for privileged containers:
kubectl get pods --all-namespaces -o json | \
  jq -r '.items[] | select(.spec.containers[].securityContext.privileged==true) | .metadata.namespace + "/" + .metadata.name'
Remediation
# 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}}]}}}}'
5.1.3 Ensure containers run as non-root (Automated)
L2 Auto
Description

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.

Rationale

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
# 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'
Remediation
# 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

▶
5.2.1 Ensure Binary Authorization is enabled (Automated)
L2 Auto
Description

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.

Rationale

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
# Verify Binary Authorization is enabled:
gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE --format='value(binaryAuthorization)'

# Check the policy:
gcloud container binauthz policy export
Remediation
# 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

▶
6.1.1 Ensure application-layer secrets encryption is enabled (Automated)
L1 Auto
Description

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.

Rationale

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
# Verify application-layer secrets encryption:
gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE --format='value(databaseEncryption)'

# Should show state: ENCRYPTED with a KMS key
Remediation
# 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
6.1.2 Ensure secrets are stored in Secret Manager (Manual)
L2 Manual
Description

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.

Rationale

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