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

# Avoid Non-Default Bindings To System:authenticated

### More Info:

Non-default bindings to the group system:authenticated grant permissions to every authenticated user in the cluster. They should be removed or replaced with narrowly scoped, user-defined groups.

### Risk Level

Critical

### Address

Security

### Compliance Standards

* CIS GKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. List all non-default bindings to `system:authenticated` (any machine with kubectl access):

           ```bash theme={null}
           (
             kubectl get clusterrolebindings -o json | jq -r '
               .items[]
               | select((.metadata.name != "system:basic-user") and (.metadata.name != "system:discovery"))
               | select((.subjects | length) > 0)
               | select(any(.subjects[]?;
                   .kind=="Group" and .name=="system:authenticated"
                 ))
               | "FOUND_AUTH:ClusterRoleBinding:\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
             ';
             kubectl get rolebindings -A -o json | jq -r '
               .items[]
               | select((.subjects | length) > 0)
               | select(any(.subjects[]?;
                   .kind=="Group" and .name=="system:authenticated"
                 ))
               | "FOUND_AUTH:RoleBinding:\(.metadata.namespace):\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
             '
           ) | (grep -q "^FOUND_AUTH:" && cat || echo "NO_NON_DEFAULT_AUTH_BINDINGS")
           ```

        2. For each `FOUND_AUTH:ClusterRoleBinding:...` entry, inspect the binding and the referenced role to understand impact (any machine with kubectl access):

           ```bash theme={null}
           # Example: replace <CRB_NAME> with the name reported in step 1
           kubectl get clusterrolebinding <CRB_NAME> -o yaml

           # Inspect the referenced ClusterRole
           # (from the ROLE=ClusterRole/<ROLE_NAME> part)
           kubectl get clusterrole <ROLE_NAME> -o yaml
           ```

        3. For each `FOUND_AUTH:RoleBinding:...` entry, inspect the binding and the referenced role (any machine with kubectl access):

           ```bash theme={null}
           # Example: replace <NAMESPACE> and <RB_NAME> with values from step 1
           kubectl get rolebinding <RB_NAME> -n <NAMESPACE> -o yaml

           # Inspect the referenced Role or ClusterRole
           # (from the ROLE=<KIND>/<ROLE_NAME> part)
           kubectl get <KIND> <ROLE_NAME> -n <NAMESPACE> -o yaml
           ```

        4. Decide safer replacements before deletion (any machine with kubectl access):

           * Identify or create user-defined groups in your IdP (e.g., `devs`, `ops-team`) and map them to Kubernetes groups via your authentication setup (GKE RBAC, OIDC, etc.).

           * Create least-privilege `Role`/`ClusterRole` objects and bind them to those user-defined groups instead of `system:authenticated`. Example pattern:

             ```bash theme={null}
             # Example: create a least-privilege ClusterRole
             kubectl apply -f - << 'EOF'
             apiVersion: rbac.authorization.k8s.io/v1
             kind: ClusterRole
             metadata:
               name: custom-read-only
             rules:
             - apiGroups: [""]
               resources: ["pods"]
               verbs: ["get", "list", "watch"]
             EOF

             # Bind it to a user-defined group, not system:authenticated
             kubectl apply -f - << 'EOF'
             apiVersion: rbac.authorization.k8s.io/v1
             kind: ClusterRoleBinding
             metadata:
               name: custom-read-only-binding
             subjects:
             - kind: Group
               name: my-organization-devs   # user-defined group from your IdP
               apiGroup: rbac.authorization.k8s.io
             roleRef:
               kind: ClusterRole
               name: custom-read-only
               apiGroup: rbac.authorization.k8s.io
             EOF
             ```

           * Validate with application/cluster owners that these new bindings cover all legitimate access needs before you remove the unsafe ones.

        5. Remove each non-default binding to `system:authenticated` once a safer alternative exists and operational impact is accepted (any machine with kubectl access):

           ```bash theme={null}
           # Delete unsafe ClusterRoleBindings
           # Repeat for each <CRB_NAME> identified in step 1 that you have approved for removal
           kubectl delete clusterrolebinding <CRB_NAME>

           # Delete unsafe RoleBindings
           # Repeat for each <NAMESPACE> and <RB_NAME> identified in step 1 that you have approved for removal
           kubectl delete rolebinding <RB_NAME> -n <NAMESPACE>
           ```

        6. Verification (any machine with kubectl access):

           ```bash theme={null}
           (
             kubectl get clusterrolebindings -o json | jq -r '
               .items[]
               | select((.metadata.name != "system:basic-user") and (.metadata.name != "system:discovery"))
               | select((.subjects | length) > 0)
               | select(any(.subjects[]?;
                   .kind=="Group" and .name=="system:authenticated"
                 ))
               | "FOUND_AUTH:ClusterRoleBinding:\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
             ';
             kubectl get rolebindings -A -o json | jq -r '
               .items[]
               | select((.subjects | length) > 0)
               | select(any(.subjects[]?;
                   .kind=="Group" and .name=="system:authenticated"
                 ))
               | "FOUND_AUTH:RoleBinding:\(.metadata.namespace):\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
             '
           ) | (grep -q "^FOUND_AUTH:" && cat || echo "NO_NON_DEFAULT_AUTH_BINDINGS")
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        On any machine with kubectl access:

        1. List all non-default bindings to `system:authenticated` (from the audit)

        ```bash theme={null}
        (
          kubectl get clusterrolebindings -o json | jq -r '
            .items[]
            | select((.metadata.name != "system:basic-user") and (.metadata.name != "system:discovery"))
            | select((.subjects | length) > 0)
            | select(any(.subjects[]?;
                .kind=="Group" and .name=="system:authenticated"
              ))
            | "FOUND_AUTH:ClusterRoleBinding:\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
          ';
          kubectl get rolebindings -A -o json | jq -r '
            .items[]
            | select((.subjects | length) > 0)
            | select(any(.subjects[]?;
                .kind=="Group" and .name=="system:authenticated"
              ))
            | "FOUND_AUTH:RoleBinding:\(.metadata.namespace):\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
          '
        )
        ```

        Review each listed binding and decide whether it is truly required. For any binding that is not strictly necessary, delete it.

        2. Delete unsafe ClusterRoleBindings to `system:authenticated`

        Replace `CLUSTER_ROLE_BINDING_NAME` with each offending ClusterRoleBinding name you chose to remove:

        ```bash theme={null}
        kubectl delete clusterrolebinding CLUSTER_ROLE_BINDING_NAME
        ```

        3. Delete unsafe RoleBindings to `system:authenticated`

        Replace `ROLE_BINDING_NAMESPACE` and `ROLE_BINDING_NAME` with the namespace and name of each offending RoleBinding you chose to remove:

        ```bash theme={null}
        kubectl delete rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE
        ```

        4. (Optional) Replace with safer, user-defined group bindings

        Create or edit bindings so they refer to a narrower, non-default group you manage (example):

        ```yaml theme={null}
        apiVersion: rbac.authorization.k8s.io/v1
        kind: ClusterRoleBinding
        metadata:
          name: myteam-readonly
        roleRef:
          apiGroup: rbac.authorization.k8s.io
          kind: ClusterRole
          name: view
        subjects:
          - kind: Group
            apiGroup: rbac.authorization.k8s.io
            name: myteam@example.com
        ```

        Apply:

        ```bash theme={null}
        kubectl apply -f myteam-readonly.yaml
        ```

        5. Verification (run on any machine with kubectl)

        ```bash theme={null}
        (
          kubectl get clusterrolebindings -o json | jq -r '
            .items[]
            | select((.metadata.name != "system:basic-user") and (.metadata.name != "system:discovery"))
            | select((.subjects | length) > 0)
            | select(any(.subjects[]?;
                .kind=="Group" and .name=="system:authenticated"
              ))
            | "FOUND_AUTH:ClusterRoleBinding:\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
          ';
          kubectl get rolebindings -A -o json | jq -r '
            .items[]
            | select((.subjects | length) > 0)
            | select(any(.subjects[]?;
                .kind=="Group" and .name=="system:authenticated"
              ))
            | "FOUND_AUTH:RoleBinding:\(.metadata.namespace):\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
          '
        ) | (grep -q "^FOUND_AUTH:" && cat || echo "NO_NON_DEFAULT_AUTH_BINDINGS")
        ```
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Remediate non-default bindings to group "system:authenticated"
        # Scope: any machine with kubectl access (requires jq)
        #
        # Behavior:
        # - Lists all ClusterRoleBindings and RoleBindings that bind system:authenticated
        # - Skips GKE default CRBs: system:basic-user, system:discovery
        # - Prompts for each binding to delete (default: no)
        # - Safe to re-run; already-deleted objects are ignored
        # - Prints final verification matching the benchmark audit

        set -euo pipefail

        # -------- configuration --------
        # Set to "true" to delete without prompting
        AUTO_APPROVE="${AUTO_APPROVE:-false}"
        # -------------------------------

        if ! command -v kubectl >/dev/null 2>&1; then
          echo "ERROR: kubectl 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

        echo "Discovering non-default bindings to group 'system:authenticated'..."

        TMP_DIR="$(mktemp -d)"
        trap 'rm -rf "$TMP_DIR"' EXIT

        CRB_CANDIDATES_FILE="${TMP_DIR}/crb_candidates.txt"
        RB_CANDIDATES_FILE="${TMP_DIR}/rb_candidates.txt"

        # Find offending ClusterRoleBindings (excluding allowed defaults)
        kubectl get clusterrolebindings -o json | jq -r '
          .items[]
          | select((.metadata.name != "system:basic-user") and (.metadata.name != "system:discovery"))
          | select((.subjects // [] | length) > 0)
          | select(any(.subjects[]?;
              .kind=="Group" and .name=="system:authenticated"
            ))
          | .metadata.name
        ' | sort -u > "${CRB_CANDIDATES_FILE}"

        # Find offending RoleBindings (all namespaces)
        kubectl get rolebindings -A -o json | jq -r '
          .items[]
          | select((.subjects // [] | length) > 0)
          | select(any(.subjects[]?;
              .kind=="Group" and .name=="system:authenticated"
            ))
          | .metadata.namespace + ":" + .metadata.name
        ' | sort -u > "${RB_CANDIDATES_FILE}"

        CRB_COUNT="$(wc -l < "${CRB_CANDIDATES_FILE}" | tr -d ' ')"
        RB_COUNT="$(wc -l < "${RB_CANDIDATES_FILE}" | tr -d ' ')"

        if [[ "${CRB_COUNT}" -eq 0 && "${RB_COUNT}" -eq 0 ]]; then
          echo "No non-default bindings to 'system:authenticated' found."
        else
          echo "Found ${CRB_COUNT} offending ClusterRoleBindings and ${RB_COUNT} offending RoleBindings."
        fi

        # Helper: ask for confirmation (unless AUTO_APPROVE)
        confirm_delete() {
          local desc="$1"
          if [[ "${AUTO_APPROVE}" == "true" ]]; then
            return 0
          fi
          while true; do
            read -r -p "Delete ${desc}? [y/N]: " ans
            case "${ans:-}" in
              [Yy]*) return 0 ;;
              [Nn]*|"") return 1 ;;
              *) echo "Please answer y or n." ;;
            esac
          done
        }

        # Process ClusterRoleBindings
        if [[ -s "${CRB_CANDIDATES_FILE}" ]]; then
          echo
          echo "Reviewing ClusterRoleBindings binding to 'system:authenticated' (excluding defaults)..."
          while read -r crb; do
            [[ -z "${crb}" ]] && continue

            echo
            echo "----- ClusterRoleBinding: ${crb} -----"
            kubectl get clusterrolebinding "${crb}" -o yaml || {
              echo "  (Already deleted or not found, skipping.)"
              continue
            }

            # Show the roleRef and subjects for quick assessment
            echo
            echo "Summary (roleRef and subjects):"
            kubectl get clusterrolebinding "${crb}" -o json | jq '{roleRef, subjects}'

            if confirm_delete "ClusterRoleBinding '${crb}'"; then
              echo "Deleting ClusterRoleBinding '${crb}'..."
              if ! kubectl delete clusterrolebinding "${crb}" >/dev/null 2>&1; then
                echo "WARNING: Failed to delete ClusterRoleBinding '${crb}'. Continuing." >&2
              fi
            else
              echo "Skipping deletion of ClusterRoleBinding '${crb}'."
            fi
          done < "${CRB_CANDIDATES_FILE}"
        fi

        # Process RoleBindings
        if [[ -s "${RB_CANDIDATES_FILE}" ]]; then
          echo
          echo "Reviewing RoleBindings binding to 'system:authenticated'..."
          while read -r entry; do
            [[ -z "${entry}" ]] && continue
            ns="${entry%%:*}"
            rb="${entry#*:}"

            echo
            echo "----- RoleBinding: ${ns}/${rb} -----"
            kubectl get rolebinding "${rb}" -n "${ns}" -o yaml || {
              echo "  (Already deleted or not found, skipping.)"
              continue
            }

            # Show the roleRef and subjects for quick assessment
            echo
            echo "Summary (roleRef and subjects):"
            kubectl get rolebinding "${rb}" -n "${ns}" -o json | jq '{roleRef, subjects}'

            if confirm_delete "RoleBinding '${ns}/${rb}'"; then
              echo "Deleting RoleBinding '${ns}/${rb}'..."
              if ! kubectl delete rolebinding "${rb}" -n "${ns}" >/dev/null 2>&1; then
                echo "WARNING: Failed to delete RoleBinding '${ns}/${rb}'. Continuing." >&2
              fi
            else
              echo "Skipping deletion of RoleBinding '${ns}/${rb}'."
            fi
          done < "${RB_CANDIDATES_FILE}"
        fi

        echo
        echo "Verification: re-running audit for non-default bindings to 'system:authenticated'..."
        (
          kubectl get clusterrolebindings -o json | jq -r '
            .items[]
            | select((.metadata.name != "system:basic-user") and (.metadata.name != "system:discovery"))
            | select((.subjects | length) > 0)
            | select(any(.subjects[]?;
                .kind=="Group" and .name=="system:authenticated"
              ))
            | "FOUND_AUTH:ClusterRoleBinding:\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
          ';
          kubectl get rolebindings -A -o json | jq -r '
            .items[]
            | select((.subjects | length) > 0)
            | select(any(.subjects[]?;
                .kind=="Group" and .name=="system:authenticated"
              ))
            | "FOUND_AUTH:RoleBinding:\(.metadata.namespace):\(.metadata.name):ROLE=\(.roleRef.kind)/\(.roleRef.name)"
          '
        ) | (grep -q "^FOUND_AUTH:" && cat || echo "NO_NON_DEFAULT_AUTH_BINDINGS")

        echo
        echo "Completed."
        ```

        Usage (run on any machine with kubectl access and jq):

        ```bash theme={null}
        chmod +x ./fix-authenticated-bindings.sh
        # Interactive review & delete
        ./fix-authenticated-bindings.sh

        # Or non-interactive (auto-delete all offending bindings)
        AUTO_APPROVE=true ./fix-authenticated-bindings.sh
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
