> ## 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. List all RoleBindings and ClusterRoleBindings that reference `system:anonymous` or `system:unauthenticated` (run on any machine with kubectl access):
           ```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. For each violating binding you plan to remove, inspect it to understand what access it grants and whether an authenticated subject (e.g., specific user/group/service account) should replace it (run on any machine with kubectl access). Example for a namespaced RoleBinding:
           ```bash theme={null}
           kubectl get rolebinding <ROLEBINDING_NAME> -n <NAMESPACE> -o yaml
           ```
           Example for a ClusterRoleBinding:
           ```bash theme={null}
           kubectl get clusterrolebinding <CLUSTERROLEBINDING_NAME> -o yaml
           ```

        3. If you decide the binding is not required, delete the offending RoleBinding or ClusterRoleBinding (run on any machine with kubectl access). Example for a namespaced RoleBinding:
           ```bash theme={null}
           kubectl delete rolebinding <ROLEBINDING_NAME> -n <NAMESPACE>
           ```
           Example for a ClusterRoleBinding:
           ```bash theme={null}
           kubectl delete clusterrolebinding <CLUSTERROLEBINDING_NAME>
           ```

        4. If equivalent access is still needed, create or update a binding that grants the same Role/ClusterRole only to authenticated subjects (run on any machine with kubectl access). For example, to bind a ClusterRole to a specific group instead of `system:unauthenticated`:
           ```bash theme={null}
           cat << 'EOF' | kubectl apply -f -
           apiVersion: rbac.authorization.k8s.io/v1
           kind: ClusterRoleBinding
           metadata:
             name: <NEW_BINDING_NAME>
           subjects:
             - kind: Group
               name: <APPROVED_AUTHENTICATED_GROUP>
               apiGroup: rbac.authorization.k8s.io
           roleRef:
             apiGroup: rbac.authorization.k8s.io
             kind: ClusterRole
             name: <EXISTING_CLUSTERROLE_NAME>
           EOF
           ```

        5. Repeat steps 2–4 until all RoleBindings and ClusterRoleBindings that reference `system:anonymous` or `system:unauthenticated` have been deleted or appropriately replaced.

        6. Verify compliance (run on any machine with kubectl access):
           ```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'
           ```
           The output should be:
           ```text theme={null}
           is_compliant=true
           ```
      </Accordion>

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

        1. Identify 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)"
          ] as $rows
          | if ($rows | length) == 0 then "is_compliant=true" else $rows[] end'
        ```

        2. For each violating RoleBinding, delete it

        * Namespaced RoleBinding (replace `<namespace>` and `<name>`):

        ```bash theme={null}
        kubectl delete rolebinding <name> -n <namespace>
        ```

        Example:

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

        3. For each violating ClusterRoleBinding, delete it

        * Cluster-wide ClusterRoleBinding (replace `<name>`):

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

        Example:

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

        4. Re-apply any required access using authenticated subjects only (optional, declarative)

        Create a manifest file (for example, `rb-authenticated-only.yaml`) with safe subjects, then apply:

        ```yaml theme={null}
        apiVersion: rbac.authorization.k8s.io/v1
        kind: RoleBinding
        metadata:
          name: authenticated-view
          namespace: default
        roleRef:
          apiGroup: rbac.authorization.k8s.io
          kind: ClusterRole
          name: view
        subjects:
          - kind: Group
            apiGroup: rbac.authorization.k8s.io
            name: system:authenticated
        ```

        Apply it:

        ```bash theme={null}
        kubectl apply -f rb-authenticated-only.yaml
        ```

        5. Verification (must return `is_compliant=true`)

        ```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
        #
        # Remediation: Delete any RoleBinding or ClusterRoleBinding that grants access
        # to subjects named system:anonymous or system:unauthenticated.
        #
        # Requirements:
        # - Run from any machine with kubectl access and current kube-context set to the OKE cluster.
        # - kubectl and jq must be installed and on PATH.

        set -euo pipefail

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

        # Capture current violations in a temporary file for idempotence and traceability
        WORKDIR="$(mktemp -d)"
        VIOLATIONS_JSON="${WORKDIR}/violations.json"

        kubectl get rolebindings,clusterrolebindings --all-namespaces -o json > "${VIOLATIONS_JSON}"

        # Extract unique binding identifiers (kind, namespace, name) that reference the bad subjects
        mapfile -t BINDINGS_TO_DELETE < <(
          jq -r '
            .items[]
            | .kind as $kind
            | .metadata as $m
            | .subjects // []
            | map(select(.name == "system:anonymous" or .name == "system:unauthenticated"))
            | select(length > 0)
            | [
                $kind,
                ($m.namespace // ""),
                $m.name
              ]
            | @tsv
          ' "${VIOLATIONS_JSON}" | sort -u
        )

        if [ "${#BINDINGS_TO_DELETE[@]}" -eq 0 ]; then
          echo "[INFO] No RoleBindings or ClusterRoleBindings reference system:anonymous or system:unauthenticated. Cluster is already compliant."
        else
          echo "[INFO] The following bindings will be deleted:"
          printf '  %s\n' "${BINDINGS_TO_DELETE[@]}"

          for line in "${BINDINGS_TO_DELETE[@]}"; do
            kind="$(echo "${line}" | awk '{print $1}')"
            ns="$(echo "${line}"   | awk '{print $2}')"
            name="$(echo "${line}" | awk '{print $3}')"

            # Determine kubectl delete command based on scope
            if [ "${kind}" = "RoleBinding" ]; then
              if [ -z "${ns}" ]; then
                echo "[WARN] RoleBinding ${name} has no namespace; skipping (invalid object)."
                continue
              fi
              echo "[INFO] Deleting RoleBinding ${name} in namespace ${ns}..."
              kubectl delete rolebinding "${name}" -n "${ns}" --ignore-not-found
            elif [ "${kind}" = "ClusterRoleBinding" ]; then
              echo "[INFO] Deleting ClusterRoleBinding ${name}..."
              kubectl delete clusterrolebinding "${name}" --ignore-not-found
            else
              echo "[WARN] Unknown kind ${kind} for ${name}; skipping."
            fi
          done
        fi

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

        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 "[INFO] Cleanup temporary files..."
        rm -rf "${WORKDIR}"

        echo "[INFO] Remediation script completed."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
