> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify all GKE clusters and their locations**\
           Run on: any machine with `gcloud` access.
           ```bash theme={null}
           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:
           ```bash theme={null}
           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:
           ```bash theme={null}
           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:
           ```bash theme={null}
           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:
           ```bash theme={null}
           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.
      </Accordion>

      <Accordion title="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.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/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):**

        ```bash theme={null}
        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:

        ```bash theme={null}
        gcloud container clusters describe <cluster_name> \
          --location <location> \
          --project <project_id> \
          --format json | jq '.addonsConfig.kubernetesDashboard'
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://cloud.google.com/kubernetes-engine/docs/how-to/hardening-your-cluster#disable\_kubernetes\_dashboard](https://cloud.google.com/kubernetes-engine/docs/how-to/hardening-your-cluster#disable_kubernetes_dashboard)
