Skip to main content

Ensure Authentication Using Client Certificates Is Disabled

More Info:

Disable client certificate authentication for the cluster, as client certs cannot be easily revoked and are a weak long-lived credential. Rely on short-lived IAM-based authentication instead.

Risk Level

Critical

Address

Security

Compliance Standards

  • CIS GKE

Triage and Remediation

Remediation

Manual Steps
  1. Identify clusters and current client certificate setting

    • Run on: any machine with gcloud access
    • Command:
      gcloud container clusters list --project YOUR_PROJECT_ID --format="table(name,location,master_version,endpoint)"
      For each cluster:
      CLUSTER_NAME="YOUR_CLUSTER_NAME"
      LOCATION="YOUR_CLUSTER_LOCATION" # e.g. us-central1, us-central1-c
      PROJECT_ID="YOUR_PROJECT_ID"

      gcloud container clusters describe "$CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID" \
      --format=json | jq '.masterAuth'
      Note whether .masterAuth.clientKey and .masterAuth.clientCertificate are null/empty or contain data.
  2. Determine if client certificates are in active use

    • Run on: any machine with kubectl access
    • For each context using this cluster, inspect user auth type:
      kubectl config view --minify --raw
      Check under users[].user for client-certificate / client-key fields.
    • On admin workstations or CI/CD configs, search for kubeconfigs with client certs:
      grep -R "client-certificate" -n ~/.kube 2>/dev/null || true
      grep -R "client-key" -n ~/.kube 2>/dev/null || true
      Document any automation or users that still rely on client cert auth.
  3. Decide whether the cluster can be recreated without client certificates

    • Review:
      • Whether you rely exclusively on GKE IAM / gke-gcloud-auth-plugin (preferred).
      • Any legacy tooling that cannot use IAM-based auth.
    • If any critical dependency requires client certificates and cannot be migrated, plan a migration first before proceeding.
  4. Plan and perform cluster recreation with --no-issue-client-certificate (if acceptable)

    • Design a migration: node pools, workloads, storage (PVs), and network settings (VPC, firewall rules, authorized networks).
    • Create a new cluster without client certificates:
      NEW_CLUSTER_NAME="NEW_CLUSTER_NAME"
      LOCATION="YOUR_CLUSTER_LOCATION"
      PROJECT_ID="YOUR_PROJECT_ID"

      gcloud container clusters create "$NEW_CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID" \
      --no-issue-client-certificate \
      # add your existing cluster options here (network, subnetwork, master-authorized-networks, release-channel, etc.)
    • Recreate node pools, migrate workloads (e.g., via kubectl apply or GitOps), and rebind IAM and RBAC as needed.
    • Once validated, decommission the old cluster:
      OLD_CLUSTER_NAME="OLD_CLUSTER_NAME"

      gcloud container clusters delete "$OLD_CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID"
  5. Update all access methods to use IAM-based authentication

    • Ensure gcloud and gke-gcloud-auth-plugin are installed and enabled on admin/CI machines:
      gcloud components install gke-gcloud-auth-plugin
      gcloud container clusters get-credentials "$NEW_CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID"
    • Confirm kubeconfig users no longer reference client certificates:
      kubectl config view --raw
      Verify user entries rely on auth-provider: gcp or exec with gke-gcloud-auth-plugin.
  6. Verify remediation

    • Run on: any machine with gcloud access
    • Command for each active cluster:
      gcloud container clusters describe "$CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID" \
      --format=json | jq '.masterAuth.clientKey, .masterAuth.clientCertificate'
    • The values should be null (or absent) for clusters where client certificate authentication is disabled.
Using kubectl

kubectl cannot disable client certificate authentication, because this setting is managed at the GKE control-plane / cloud provider configuration layer (via gcloud, console, or IaC). Refer to the Manual Steps section for guidance on reviewing and recreating the cluster with --no-issue-client-certificate.

Automation
#!/usr/bin/env bash
#
# Report whether GKE clusters are issuing client certificates (CIS GKE 5.8.1)
# Requires: gcloud, jq
#
# Run location: any machine with gcloud access to the projects you want to audit.

set -euo pipefail

# --- CONFIGURATION ---
# Comma-separated list of GCP projects to check
PROJECTS="my-project-1,my-project-2" # <-- EDIT THIS

IFS=',' read -r -a PROJECT_ARR <<< "$PROJECTS"

echo "Checking client certificate issuance on GKE clusters (CIS GKE 5.8.1)"
echo "Problematic state: masterAuth.clientKey != null (client certs enabled)"
echo

for PROJECT in "${PROJECT_ARR[@]}"; do
echo "==== Project: $PROJECT ===="

# List all clusters in the project (all locations)
CLUSTERS_JSON=$(gcloud container clusters list \
--project "$PROJECT" \
--format json 2>/dev/null || echo "[]")

CLUSTER_COUNT=$(echo "$CLUSTERS_JSON" | jq 'length')
if [ "$CLUSTER_COUNT" -eq 0 ]; then
echo " No clusters found."
echo
continue
fi

echo "$CLUSTERS_JSON" | jq -r '.[] | "\(.name) \(.location)"' | while read -r CLUSTER_NAME LOCATION; do
# Describe cluster to get masterAuth.clientKey
DESC=$(gcloud container clusters describe "$CLUSTER_NAME" \
--location "$LOCATION" \
--project "$PROJECT" \
--format json 2>/dev/null || echo "{}")

CLIENT_KEY=$(echo "$DESC" | jq -r '.masterAuth.clientKey // "null"')

if [ "$CLIENT_KEY" != "null" ] && [ "$CLIENT_KEY" != "" ]; then
STATUS="NON-COMPLIANT"
NOTE="(client certificate authentication ENABLED)"
else
STATUS="OK"
NOTE="(client certificate authentication DISABLED)"
fi

echo " Cluster: $CLUSTER_NAME"
echo " Location : $LOCATION"
echo " Status : $STATUS"
echo " clientKey set : $CLIENT_KEY"
echo " Note : $NOTE"
echo
done
done

cat <<'EOF'
Interpretation:

- COMPLIANT / desired:
masterAuth.clientKey == null
In the script output this appears as:
Status : OK
clientKey set : null
Note : (client certificate authentication DISABLED)

- PROBLEM / needs review:
masterAuth.clientKey != null
In the script output this appears as:
Status : NON-COMPLIANT
clientKey set : <base64-encoded key material>
Note : (client certificate authentication ENABLED)

For NON-COMPLIANT clusters, review whether they should be replaced with
new clusters created using:
gcloud container clusters create CLUSTER_NAME --no-issue-client-certificate
EOF