Skip to main content

Ensure Kubernetes Web UI Is Disabled

More Info:

Disable the Kubernetes Dashboard (Web UI) add-on, which has historically been an attack vector for privilege escalation. Cluster management should use the CLI or console instead.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS GKE

Triage and Remediation

Remediation

Manual Steps
  1. Identify clusters to review

    • On any machine with gcloud configured, list clusters and note their names and locations:
      gcloud container clusters list --project PROJECT_ID
  2. Check the Dashboard addon status for each cluster

    • For each cluster, run:
      gcloud container clusters describe CLUSTER_NAME \
      --location LOCATION \
      --project PROJECT_ID \
      --format='json' | jq '.addonsConfig.kubernetesDashboard'
    • Record whether .disabled is true or false (or if the field is missing).
  3. Decide whether the Dashboard is required

    • For any cluster where the Dashboard is not explicitly disabled, confirm with cluster owners:
      • Whether anyone relies on the in‑cluster Kubernetes Dashboard for operations.
      • Whether all required management can be done via kubectl and cloud console.
    • If there is no documented, approved use case, plan to disable it.
  4. Disable the Dashboard where not needed

    • For each cluster where the Dashboard should be disabled, run:
      gcloud container clusters update CLUSTER_NAME \
      --location LOCATION \
      --project PROJECT_ID \
      --update-addons=KubernetesDashboard=DISABLED
    • Note: this is a control plane configuration change; coordinate with operations if you have strict change windows.
  5. Handle exceptions (if you must keep it)

    • If a cluster must keep the Dashboard:
      • Document the business justification and owner.
      • Ensure access is tightly controlled (e.g., strong authn/z, least-privilege RBAC, network restrictions).
      • Set a review date for decommissioning or replacing it.
  6. Verify remediation

    • Re-run the audit for each cluster intended to have the Dashboard disabled:
      gcloud container clusters describe CLUSTER_NAME \
      --location LOCATION \
      --project PROJECT_ID \
      --format='json' | jq '.addonsConfig.kubernetesDashboard'
    • Confirm that the output shows the Dashboard configuration present with "disabled": true (or equivalent indication that it is disabled).
Using kubectl

kubectl cannot enable or disable the managed Kubernetes Dashboard addon in GKE; that setting is controlled only via the GCP console, gcloud CLI, or your IaC for the cluster configuration. See the Manual Steps section for how to review and change the addon state at the cloud provider level.

Automation
#!/usr/bin/env bash
# Report Kubernetes Dashboard (Web UI) status for all GKE clusters in a project.
# Usage: ./check_gke_dashboard.sh <GCP_PROJECT_ID>

set -euo pipefail

PROJECT_ID="${1:-}"

if [[ -z "$PROJECT_ID" ]]; then
echo "Usage: $0 <GCP_PROJECT_ID>" >&2
exit 1
fi

echo "Checking Kubernetes Dashboard addon status in project: ${PROJECT_ID}"
echo

# List all clusters (both zonal and regional)
mapfile -t CLUSTERS < <(
gcloud container clusters list \
--project "${PROJECT_ID}" \
--format 'value(name,location)'
)

if [[ "${#CLUSTERS[@]}" -eq 0 ]]; then
echo "No GKE clusters found in project ${PROJECT_ID}"
exit 0
fi

printf "%-40s %-20s %-12s\n" "CLUSTER_NAME" "LOCATION" "DASHBOARD"
printf "%-40s %-20s %-12s\n" "------------" "--------" "---------"

for ENTRY in "${CLUSTERS[@]}"; do
CLUSTER_NAME="$(awk '{print $1}' <<< "${ENTRY}")"
LOCATION="$(awk '{print $2}' <<< "${ENTRY}")"

# Query the addonsConfig.kubernetesDashboard field
RAW=$(
gcloud container clusters describe "${CLUSTER_NAME}" \
--location "${LOCATION}" \
--project "${PROJECT_ID}" \
--format json | \
jq -r '.addonsConfig.kubernetesDashboard // empty'
)

# Default to DISABLED if field is entirely absent
if [[ -z "${RAW}" || "${RAW}" == "null" ]]; then
STATUS="DISABLED (implicit)"
else
ENABLED=$(jq -r '.disabled // false | not' <<< "${RAW}")
# ENABLED will be "true" if dashboard is enabled, "false" otherwise
if [[ "${ENABLED}" == "true" ]]; then
STATUS="ENABLED"
else
STATUS="DISABLED"
fi
fi

printf "%-40s %-20s %-12s\n" "${CLUSTER_NAME}" "${LOCATION}" "${STATUS}"
done

cat <<'EOF'

Interpretation:
- Any row with DASHBOARD = "ENABLED" indicates a problem for CIS GKE 5.10.1:
the Kubernetes Web UI (Dashboard) is enabled and should be reviewed/disabled.
- Rows with "DISABLED" or "DISABLED (implicit)" are compliant for this control.
EOF