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

# Manage Kubernetes RBAC Users With Google Groups For GKE

### More Info:

Bind Kubernetes RBAC roles to Google Groups so cluster access is managed centrally through group membership. This simplifies and secures access administration versus per-user bindings.

### 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. **Review current cluster Google Groups for GKE settings**
           * On any machine with gcloud configured, run:
             ```bash theme={null}
             gcloud container clusters describe CLUSTER_NAME \
               --location CONTROL_PLANE_LOCATION \
               --project PROJECT_ID \
               --format json | jq '{Enabled: .authenticatorGroupsConfig.enabled, "Security Group": .authenticatorGroupsConfig.securityGroup}'
             ```
           * Decide whether `Enabled` is `true` and `Security Group` is set to the intended parent group (for example `gke-security-groups@YOUR_DOMAIN`).

        2. **If not enabled, decide on the security group and enable it (control-plane impact)**
           * Identify or create, in Google Workspace / Cloud Identity, a *parent* group (e.g. `gke-security-groups@YOUR_DOMAIN`) and document its purpose and membership policy (who can be added, who can administer it).
           * On any machine with gcloud, update the existing cluster:
             ```bash theme={null}
             gcloud container clusters update CLUSTER_NAME \
               --location CONTROL_PLANE_LOCATION \
               --project PROJECT_ID \
               --security-group="gke-security-groups@YOUR_DOMAIN"
             ```
           * Be aware: updating this may change how users authenticate/authorize; plan and execute during a maintenance window if needed.

        3. **Inventory existing RBAC bindings that use direct users vs groups**
           * On any machine with kubectl access:
             ```bash theme={null}
             # ClusterRoleBindings using user subjects
             kubectl get clusterrolebindings -o json | jq -r '
               .items[]
               | select(.subjects != null)
               | select([.subjects[].kind] | index("User"))
               | .metadata.name as $n
               | "CRB: \($n)\n" + (.subjects[] | select(.kind=="User") | "  User: \(.name)") + "\n"
             '

             # RoleBindings using user subjects across all namespaces
             kubectl get rolebindings --all-namespaces -o json | jq -r '
               .items[]
               | select(.subjects != null)
               | select([.subjects[].kind] | index("User"))
               | .metadata.namespace as $ns
               | .metadata.name as $n
               | "RB: \($ns)/\($n)\n" + (.subjects[] | select(.kind=="User") | "  User: \(.name)") + "\n"
             '
             ```
           * Use this output to identify principals that should instead be granted access via Google Groups.

        4. **Design target Google Groups-to-RBAC mapping**
           * For each set of permissions you want to manage centrally (e.g. “cluster-admins”, “namespace-owners”, “read-only”), define a Google Group email that will be used as the RBAC subject (e.g. `gke-cluster-admins@YOUR_DOMAIN`).
           * Map:
             * Google Group → Kubernetes (Cluster)Role(s) → Scope (cluster or namespace).
           * Ensure membership of these groups is managed through your standard identity governance process.

        5. **Implement or update RBAC bindings to use Google Groups**
           * On any machine with kubectl access, for each intended mapping, create or update bindings referencing the Google Group (subject `kind: Group`, `name: GROUP_EMAIL`). Example (adjust names/namespaces as needed):
             ```bash theme={null}
             cat <<'EOF' | kubectl apply -f -
             apiVersion: rbac.authorization.k8s.io/v1
             kind: ClusterRoleBinding
             metadata:
               name: cluster-admins-gke-group
             subjects:
             - kind: Group
               apiGroup: rbac.authorization.k8s.io
               name: gke-cluster-admins@YOUR_DOMAIN
             roleRef:
               apiGroup: rbac.authorization.k8s.io
               kind: ClusterRole
               name: cluster-admin
             EOF
             ```
           * Gradually phase out direct `User` subjects by removing or editing the existing bindings once you’ve confirmed equivalent group-based access is in place.

        6. **Verify configuration and access behavior**
           * Re-run the cluster describe command on any machine with gcloud to ensure Google Groups for GKE is enabled and pointing at the correct security group:
             ```bash theme={null}
             gcloud container clusters describe CLUSTER_NAME \
               --location CONTROL_PLANE_LOCATION \
               --project PROJECT_ID \
               --format json | jq '{Enabled: .authenticatorGroupsConfig.enabled, "Security Group": .authenticatorGroupsConfig.securityGroup}'
             ```
           * On any machine with kubectl access, confirm that RBAC bindings now reference `Group` subjects (and not `User`) for intended access paths:
             ```bash theme={null}
             kubectl get clusterrolebindings,rolebindings --all-namespaces -o json | jq -r '
               .items[]
               | select(.subjects != null)
               | .kind + "/" + .metadata.name + " (" + (.metadata.namespace // "cluster-scope") + ")\n" +
                 ( .subjects[]
                   | "  " + .kind + ": " + .name
                 )
             '
             ```
           * Optionally, have a test user who is only a member of the appropriate Google Group log in and confirm they receive the expected level of access and no more.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot configure Google Groups for GKE or the cluster’s `--security-group` setting; those are managed in the GKE control plane via gcloud, console, or IaC. To remediate this finding, follow the guidance in the Manual Steps section, using the cloud provider tools to enable Google Groups for GKE and then create the appropriate RBAC bindings.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Audit Google Groups for GKE usage across all GKE clusters in one or more projects.
        # Requirements:
        #   - gcloud, jq
        #   - You are authenticated and have sufficient IAM permissions.
        #
        # Usage:
        #   ./audit-gke-google-groups.sh PROJECT_ID [PROJECT_ID_2 ...]
        #

        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 [PROJECT_ID_2 ...]" >&2
          exit 1
        fi

        echo "Collecting GKE Google Groups for GKE configuration and RBAC bindings..."
        echo

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

          MAP_OUTPUT=$(gcloud projects get-iam-policy "${PROJECT}" \
            --format='json(bindings)' 2>/dev/null | jq -r '
              .bindings[]
              | select(.role=="roles/container.admin" or .role=="roles/container.clusterAdmin")
              | "  IAM: " + .role + " -> " + (.members | join(", "))
            ' || true)

          echo "Project-level IAM holders of container.admin / container.clusterAdmin:"
          if [ -z "${MAP_OUTPUT}" ]; then
            echo "  (none found)"
          else
            echo "${MAP_OUTPUT}"
          fi
          echo

          CLUSTERS=$(gcloud container clusters list \
            --project="${PROJECT}" \
            --format='value(name,location)' 2>/dev/null || true)

          if [ -z "${CLUSTERS}" ]; then
            echo "No GKE clusters found in project ${PROJECT}"
            echo
            continue
          fi

          while read -r NAME LOCATION; do
            [ -z "${NAME:-}" ] && continue

            echo "----------------------------------------------------------------------"
            echo "Cluster: ${NAME}"
            echo "Location: ${LOCATION}"
            echo "----------------------------------------------------------------------"

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

            ENABLED=$(echo "${DESC_JSON}" | jq -r '.authenticatorGroupsConfig.enabled // false')
            SEC_GROUP=$(echo "${DESC_JSON}" | jq -r '.authenticatorGroupsConfig.securityGroup // ""')

            echo "Google Groups for GKE:"
            echo "  Enabled: ${ENABLED}"
            echo "  Security Group: ${SEC_GROUP}"

            if [ "${ENABLED}" != "true" ] || [ -z "${SEC_GROUP}" ] || [ "${SEC_GROUP}" = "null" ]; then
              echo "  STATUS: NOT COMPLIANT with CISGKE 5.8.2 (Google Groups for GKE not fully configured)"
            else
              echo "  STATUS: Google Groups for GKE configured at cluster level"
            fi
            echo

            echo "RBAC ClusterRoleBindings referencing Google Groups (by email-like subjects):"
            # This uses kubectl and requires cluster access.
            # Any machine with kubectl access and current context pointing to this cluster.
            if kubectl config use-context "gke_${PROJECT}_${LOCATION}_${NAME}" >/dev/null 2>&1; then
              kubectl get clusterrolebindings.rbac.authorization.k8s.io -o json 2>/dev/null | jq -r '
                .items[]
                | . as $crb
                | $crb.subjects // []
                | map(select(.kind=="Group" and (.name | test("@"))))
                | select(length > 0)
                | $crb.metadata.name as $name
                | .[]
                | "  " + $name + " -> Group: " + .name
              ' || echo "  (none found or error retrieving ClusterRoleBindings)"
              echo

              echo "RBAC RoleBindings referencing Google Groups (by email-like subjects):"
              kubectl get rolebindings.rbac.authorization.k8s.io --all-namespaces -o json 2>/dev/null | jq -r '
                .items[]
                | . as $rb
                | $rb.subjects // []
                | map(select(.kind=="Group" and (.name | test("@"))))
                | select(length > 0)
                | ($rb.metadata.namespace + "/" + $rb.metadata.name) as $name
                | .[]
                | "  " + $name + " -> Group: " + .name
              ' || echo "  (none found or error retrieving RoleBindings)"
            else
              echo "  NOTE: kubectl context gke_${PROJECT}_${LOCATION}_${NAME} not found or unusable."
              echo "        Skipping RBAC binding inspection for this cluster."
            fi

            echo
          done <<< "${CLUSTERS}"

          echo
        done

        cat <<'EOF'
        INTERPRETING RESULTS:

        1) Cluster-level Google Groups for GKE configuration:
           - Compliant / desired:
               Enabled: true
               Security Group: gke-security-groups@<your-domain>
             and the script prints:
               STATUS: Google Groups for GKE configured at cluster level
           - Potential problem (requires review):
               Enabled: false
               or Security Group is empty or "null"
             and the script prints:
               STATUS: NOT COMPLIANT with CISGKE 5.8.2 ...
             This indicates:
               * The cluster is not using Google Groups for GKE, OR
               * The security group is not set, which does not meet the benchmark guidance.

        2) RBAC role bindings:
           - Desired pattern:
               ClusterRoleBindings and RoleBindings reference Google Groups
               (subjects of kind: Group, name looks like an email, e.g. team-admins@domain).
           - Problem indicators:
               * Few or no Group subjects using email-style names, but many User subjects
                 (per-user bindings), meaning access is managed per-user instead of via groups.
               * Group names that are not your intended Google Groups for GKE (e.g. legacy groups).

        This script only reports configuration for review. Enabling Google Groups for GKE
        and restructuring RBAC bindings to use groups must be done manually following
        the provider documentation and your access-control design.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
