Skip to main content

Ensure Kubernetes Web Ui Is Disabled

More Info:

The Kubernetes Web Ui (Dashboard) Has Been A Historical Source Of Vulnerability And Should Only Be Deployed When Necessary.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS GKE

Triage and Remediation

Remediation

Manual Steps
  1. Identify all GKE clusters and their locations
    Run on: any machine with gcloud access.

    gcloud container clusters list --project PROJECT_ID \
    --format="table(name,location,endpoint,currentMasterVersion)"

    Replace PROJECT_ID with your GCP project ID and note each cluster name and location.

  2. Check dashboard add‑on status for each cluster
    Run on: any machine with gcloud access. For each cluster:

    gcloud container clusters describe CLUSTER_NAME \
    --location LOCATION \
    --project PROJECT_ID \
    --format="json" | jq '.addonsConfig.kubernetesDashboard'
    • If the result is null or "disabled": true, the legacy add‑on is not enabled.
    • If "disabled": false or an object with enabled: true is present, the dashboard add‑on is enabled.
  3. Decide if the dashboard is strictly required

    • If any cluster shows the dashboard enabled, review with application/operations teams:
      • Is the dashboard actively used for operations, or could kubectl, Cloud Console, or other tools replace it?
      • Are there compliance or security requirements that prohibit in-cluster dashboards?
    • If not strictly required, plan to disable it. If required, ensure strong RBAC, restricted network access, and auditing.
  4. Disable the Kubernetes Dashboard add‑on where not needed
    Run on: any machine with gcloud access. For each cluster where you decided to disable:

    gcloud container clusters update CLUSTER_NAME \
    --location LOCATION \
    --project PROJECT_ID \
    --update-addons=KubernetesDashboard=DISABLED

    Operational impact: this removes the managed dashboard add‑on; any workflows depending on it will lose access and must use alternative tools.

  5. Verify the dashboard add‑on is disabled
    Run on: any machine with gcloud access. For each updated cluster:

    gcloud container clusters describe CLUSTER_NAME \
    --location LOCATION \
    --project PROJECT_ID \
    --format="json" | jq '.addonsConfig.kubernetesDashboard'

    Confirm the output is null or shows "disabled": true.

  6. (Optional) Search for any other dashboard deployments
    This is not controlled by the add‑on setting but may indicate residual dashboards.
    Run on: any machine with gcloud and kubectl access. For each cluster, get credentials then:

    gcloud container clusters get-credentials CLUSTER_NAME \
    --location LOCATION \
    --project PROJECT_ID

    kubectl get deploy,svc,pod -A | grep -i dashboard || echo "No dashboard resources found"

    If you find custom dashboard deployments, review and remove them if they’re not strictly required.

Using kubectl

kubectl cannot disable the managed Kubernetes Web UI (Dashboard) in GKE, because this setting is controlled at the GKE cluster add‑on level in the Google Cloud control plane. Use the cloud provider configuration (gcloud CLI/console/IaC) as described in the Manual Steps section to remediate this finding.

Automation
#!/usr/bin/env bash
#
# Check status of the Kubernetes Dashboard addon across multiple GKE clusters.
# Requirements:
# - gcloud and jq installed
# - You are authenticated (gcloud auth login / impersonation as needed)
# - You have access to the listed projects
#
# USAGE:
# ./check_gke_dashboard.sh project-1 project-2 ...
#
# OUTPUT:
# PROJECT,LOCATION,CLUSTER,ADDON_STATUS
#
# INTERPRETATION:
# - ADDON_STATUS=null or DISABLED => Dashboard is NOT enabled (no problem)
# - ADDON_STATUS=ENABLED => Dashboard is enabled (requires review)
# - ADDON_STATUS=UNKNOWN => Could not determine (investigate manually)

set -euo pipefail

if ! command -v gcloud >/dev/null 2>&1; then
echo "ERROR: gcloud not found in PATH" >&2
exit 1
fi

if ! command-v jq >/dev/null 2>&1; then
echo "ERROR: jq not found in PATH" >&2
exit 1
fi

if [ "$#" -lt 1 ]; then
echo "Usage: $0 <PROJECT_ID_1> [PROJECT_ID_2 ...]" >&2
exit 1
fi

echo "PROJECT,LOCATION,CLUSTER,ADDON_STATUS"

for PROJECT in "$@"; do
CLUSTERS_JSON="$(gcloud container clusters list \
--project "$PROJECT" \
--format=json 2>/dev/null || echo "[]")"

echo "$CLUSTERS_JSON" | jq -r '.[] | @base64' | while read -r CLUSTER_B64; do
_jq() { echo "$CLUSTER_B64" | base64 --decode | jq -r "$1"; }

NAME=$(_jq '.name')
LOCATION=$(_jq '.location')

# Describe cluster to get addonsConfig
DESC_JSON="$(gcloud container clusters describe "$NAME" \
--location "$LOCATION" \
--project "$PROJECT" \
--format=json 2>/dev/null || echo "{}")"

# This field may be null, missing, or an object with enabled flag
RAW_FIELD="$(echo "$DESC_JSON" | jq '.addonsConfig.kubernetesDashboard')"

# Default to UNKNOWN if we cannot parse expected structure
STATUS="UNKNOWN"

# If field is null or missing, treat as not enabled
if [ "$RAW_FIELD" = "null" ] || [ "$RAW_FIELD" = "" ]; then
STATUS="null"
else
ENABLED_VAL="$(echo "$RAW_FIELD" | jq -r '.disabled // empty' 2>/dev/null || true)"
# In older API versions KubernetesDashboard may have `disabled: true|false`
# Interpret:
# disabled: true => effectively DISABLED
# disabled: false => effectively ENABLED
# If structure is different, leave as UNKNOWN for manual review
if [ "$ENABLED_VAL" = "true" ]; then
STATUS="DISABLED"
elif [ "$ENABLED_VAL" = "false" ]; then
STATUS="ENABLED"
fi
fi

echo "${PROJECT},${LOCATION},${NAME},${STATUS}"
done
done

How to run (any machine with gcloud access):

chmod +x check_gke_dashboard.sh
./check_gke_dashboard.sh my-project-1 my-project-2 > gke-dashboard-status.csv
column -t -s',' gke-dashboard-status.csv

What indicates a problem:

  • Any row where ADDON_STATUS is ENABLED indicates the Kubernetes Dashboard addon is active on that cluster and should be reviewed.
  • Rows with ADDON_STATUS=UNKNOWN mean the script could not confidently determine the state; investigate those clusters manually with:
gcloud container clusters describe <cluster_name> \
--location <location> \
--project <project_id> \
--format json | jq '.addonsConfig.kubernetesDashboard'

Additional Reading: