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

# No RoleBinding Should Grant Access To Anonymous Or Unauthenticated Users

### More Info:

Verifies no (Cluster)RoleBinding targets system:anonymous or system:unauthenticated. Such bindings grant access to unauthenticated callers.

### Risk Level

Critical

### Address

Security

### Compliance Standards

* Cloudanix Best Practice

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. Review current violating bindings (any machine with kubectl access):
           ```sh theme={null}
           kubectl get rolebindings,clusterrolebindings --all-namespaces -o json | jq -r '
             [ .items[]
               | .kind as $kind | .apiVersion as $api | .metadata as $m
               | ((.subjects // [])[] | select(.name == "system:anonymous" or .name == "system:unauthenticated"))
               | "kind=\($kind)"
                 + (if ($m.namespace // "") == "" then "" else " ns=\($m.namespace)" end)
                 + " name=\($m.name) uid=\($m.uid)"
                 + (if ($api // "") == "" then "" else " apiVersion=\($api)" end)
                 + (if ($m.creationTimestamp // "") == "" then "" else " created=\($m.creationTimestamp)" end)
                 + " subject=\(.name) is_compliant=false"
             ] as $rows
             | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end'
           ```

        2. For each offending RoleBinding, inspect details and confirm it is safe to remove (any machine with kubectl access):
           ```sh theme={null}
           # example: namespace-scoped RoleBinding
           kubectl get rolebinding <ROLEBINDING_NAME> -n <NAMESPACE> -o yaml

           # example: ClusterRoleBinding
           kubectl get clusterrolebinding <CLUSTERROLEBINDING_NAME> -o yaml
           ```

        3. Delete offending RoleBindings that reference `system:anonymous` or `system:unauthenticated` (any machine with kubectl access):
           ```sh theme={null}
           # namespace RoleBinding
           kubectl delete rolebinding <ROLEBINDING_NAME> -n <NAMESPACE>

           # ClusterRoleBinding
           kubectl delete clusterrolebinding <CLUSTERROLEBINDING_NAME>
           ```

        4. If a deleted binding was legitimately needed, recreate a safer binding to an authenticated subject (any machine with kubectl access). Example pattern:
           ```sh theme={null}
           kubectl create rolebinding <NEW_BINDING_NAME> \
             --clusterrole=<EXISTING_CLUSTERROLE_NAME> \
             --user=<AUTHENTICATED_USER_OR_SERVICEACCOUNT> \
             -n <NAMESPACE>
           ```
           or for cluster-wide:
           ```sh theme={null}
           kubectl create clusterrolebinding <NEW_BINDING_NAME> \
             --clusterrole=<EXISTING_CLUSTERROLE_NAME> \
             --user=<AUTHENTICATED_USER_OR_GROUP>
           ```

        5. If bindings are managed via manifests or GitOps, update the source manifests to remove any subjects named `system:anonymous` or `system:unauthenticated` so they are not re-applied (edit locally, then apply from any machine with kubectl access):
           ```sh theme={null}
           kubectl apply -f <UPDATED_MANIFEST_FILE>.yaml
           ```

        6. Verification (any machine with kubectl access):
           ```sh theme={null}
           kubectl get rolebindings,clusterrolebindings --all-namespaces -o json | jq -r '
             [ .items[]
               | .kind as $kind | .apiVersion as $api | .metadata as $m
               | ((.subjects // [])[] | select(.name == "system:anonymous" or .name == "system:unauthenticated"))
               | "kind=\($kind)"
                 + (if ($m.namespace // "") == "" then "" else " ns=\($m.namespace)" end)
                 + " name=\($m.name) uid=\($m.uid)"
                 + (if ($api // "") == "" then "" else " apiVersion=\($api)" end)
                 + (if ($m.creationTimestamp // "") == "" then "" else " created=\($m.creationTimestamp)" end)
                 + " subject=\(.name) is_compliant=false"
             ] as $rows
             | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end'
           ```
           The command should output only:
           ```text theme={null}
           is_compliant=true
           ```
      </Accordion>

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

        1. Identify the violating RoleBindings / ClusterRoleBindings

        ```bash theme={null}
        kubectl get rolebindings,clusterrolebindings --all-namespaces -o json | jq -r '
          [ .items[]
            | .kind as $kind | .apiVersion as $api | .metadata as $m
            | ((.subjects // [])[] | select(.name == "system:anonymous" or .name == "system:unauthenticated"))
            | "kind=\($kind)"
              + (if ($m.namespace // "") == "" then "" else " ns=\($m.namespace)" end)
              + " name=\($m.name) uid=\($m.uid)"
              + (if ($api // "") == "" then "" else " apiVersion=\($api)" end)
              + (if ($m.creationTimestamp // "") == "" then "" else " created=\($m.creationTimestamp)" end)
              + " subject=\(.name) is_compliant=false"
          ] as $rows
          | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end'
        ```

        2. Delete each violating binding

        For a namespaced RoleBinding (note the `ns=` field from the previous output):

        ```bash theme={null}
        kubectl delete rolebinding <ROLEBINDING_NAME> -n <NAMESPACE>
        ```

        Example:

        ```bash theme={null}
        kubectl delete rolebinding public-view -n default
        ```

        For a ClusterRoleBinding (no `ns=` field):

        ```bash theme={null}
        kubectl delete clusterrolebinding <CLUSTERROLEBINDING_NAME>
        ```

        Example:

        ```bash theme={null}
        kubectl delete clusterrolebinding unauthenticated-read
        ```

        3. Verification

        Re-run the audit to confirm no bindings reference `system:anonymous` or `system:unauthenticated`:

        ```bash theme={null}
        kubectl get rolebindings,clusterrolebindings --all-namespaces -o json | jq -r '
          [ .items[]
            | .kind as $kind | .apiVersion as $api | .metadata as $m
            | ((.subjects // [])[] | select(.name == "system:anonymous" or .name == "system:unauthenticated"))
            | "kind=\($kind)"
              + (if ($m.namespace // "") == "" then "" else " ns=\($m.namespace)" end)
              + " name=\($m.name) uid=\($m.uid)"
              + (if ($api // "") == "" then "" else " apiVersion=\($api)" end)
              + (if ($m.creationTimestamp // "") == "" then "" else " created=\($m.creationTimestamp)" end)
              + " subject=\(.name) is_compliant=false"
          ] as $rows
          | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end'
        ```
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Remove any RoleBinding or ClusterRoleBinding that grants access to
        # system:anonymous or system:unauthenticated.
        #
        # Run on: any machine with kubectl access to the cluster.
        # Requirements: kubectl, jq; current context points to the target GKE cluster.

        set -euo pipefail

        echo "[INFO] Discovering RoleBindings and ClusterRoleBindings that target system:anonymous or system:unauthenticated..."

        # Get full JSON only once
        RB_JSON="$(kubectl get rolebindings,clusterrolebindings --all-namespaces -o json)"

        # Build a list of offending bindings as "KIND NAMESPACE NAME" (namespace is "-" for cluster-scoped)
        mapfile -t OFFENDERS < <(
          jq -r '
            .items[]
            | .kind as $kind
            | .metadata.namespace as $ns
            | .metadata.name as $name
            | ((.subjects // [])[]
               | select(.name == "system:anonymous" or .name == "system:unauthenticated"))
            | [$kind, ($ns // "-"), $name] | @tsv
          ' <<< "$RB_JSON" | sort -u
        )

        if [ "${#OFFENDERS[@]}" -eq 0 ]; then
          echo "[INFO] No offending RoleBindings or ClusterRoleBindings found. Cluster is already compliant."
        else
          echo "[INFO] Found ${#OFFENDERS[@]} offending binding(s):"
          printf '  %s\n' "${OFFENDERS[@]}"
          echo

          for line in "${OFFENDERS[@]}"; do
            KIND="$(awk '{print $1}' <<< "$line")"
            NS_OR_DASH="$(awk '{print $2}' <<< "$line")"
            NAME="$(awk '{print $3}' <<< "$line")"

            if [ "$NS_OR_DASH" = "-" ]; then
              # ClusterRoleBinding (cluster-scoped)
              echo "[ACTION] Deleting $KIND $NAME (cluster-scoped)..."
              kubectl delete "$KIND" "$NAME" --ignore-not-found
            else
              # Namespaced RoleBinding
              echo "[ACTION] Deleting $KIND $NAME in namespace $NS_OR_DASH..."
              kubectl delete "$KIND" "$NAME" -n "$NS_OR_DASH" --ignore-not-found
            fi
          done
        fi

        echo
        echo "[INFO] Verifying compliance..."

        VERIFY_OUTPUT="$(kubectl get rolebindings,clusterrolebindings --all-namespaces -o json | jq -r '
          [ .items[]
            | .kind as $kind | .apiVersion as $api | .metadata as $m
            | ((.subjects // [])[] | select(.name == "system:anonymous" or .name == "system:unauthenticated"))
            | "kind=\($kind)"
              + (if ($m.namespace // "") == "" then "" else " ns=\($m.namespace)" end)
              + " name=\($m.name) uid=\($m.uid)"
              + (if ($api // "") == "" then "" else " apiVersion=\($api)" end)
              + (if ($m.creationTimestamp // "") == "" then "" else " created=\($m.creationTimestamp)" end)
              + " subject=\(.name) is_compliant=false"
          ] as $rows
          | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end')"

        echo "$VERIFY_OUTPUT"

        if grep -qx 'is_compliant=true' <<< "$VERIFY_OUTPUT"; then
          echo "[INFO] Remediation successful: no RoleBinding or ClusterRoleBinding grants access to system:anonymous or system:unauthenticated."
          exit 0
        else
          echo "[WARN] Some offending bindings remain. Please inspect the lines above."
          exit 1
        fi
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
