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

# Minimize Wildcard Use In Roles And ClusterRoles

### More Info:

Wildcards in RBAC rules grant access to all resources or verbs, effectively broad privilege. Replace them with explicit resources and actions.

### Risk Level

Critical

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. Identify ClusterRoles using wildcards (any machine with kubectl access)
           ```bash theme={null}
           kubectl get clusterroles -o name | while read -r cr; do
             rules=$(kubectl get "$cr" -o json | jq -c '.rules')
             if echo "$rules" | grep -q '\["\*"\]'; then
               echo "$cr uses wildcards:"
               echo "$rules"
               echo
             fi
           done
           ```

        2. For each non-system ClusterRole using wildcards, export its definition for review (any machine with kubectl access)
           ```bash theme={null}
           # example for one ClusterRole; repeat for each affected ClusterRole
           kubectl get clusterrole <clusterrole-name> -o yaml > /tmp/clusterrole-<clusterrole-name>.yaml
           ```

        3. Manually analyze required permissions and replace wildcards (manual review)
           * Consult application/team owners to determine the minimum set of:
             * `apiGroups` actually needed (e.g. `""`, `apps`, `batch`, `rbac.authorization.k8s.io`)
             * `resources` actually used (e.g. `pods`, `deployments`, `secrets`, `configmaps`, `cronjobs`)
             * `verbs` actually required (e.g. `get`, `list`, `watch`, `create`, `update`, `patch`, `delete`)
           * In each exported YAML under `.rules`:
             * Replace `apiGroups: ["*"]` with an explicit list of required API groups.
             * Replace `resources: ["*"]` with an explicit list of required resources.
             * Replace `verbs: ["*"]` with an explicit list of required verbs.
           * Do not modify Kubernetes-critical or provider-managed ClusterRoles (e.g. those starting with `system:`, `eks:`, `gke-`, `azure-`, etc.) unless you fully understand the impact.

        4. Apply the edited ClusterRole definitions back to the cluster (any machine with kubectl access)
           ```bash theme={null}
           # example for one ClusterRole; repeat for each edited file
           kubectl apply -f /tmp/clusterrole-<clusterrole-name>.yaml
           ```

        5. If necessary, split very broad ClusterRoles into multiple least-privilege roles (any machine with kubectl access)
           * When different consumers need different subsets of permissions, create separate ClusterRoles:
             ```bash theme={null}
             # create from edited manifest
             kubectl apply -f /tmp/clusterrole-<new-name>.yaml
             ```
           * Update existing ClusterRoleBindings or RoleBindings to point to the new, narrower ClusterRoles:
             ```bash theme={null}
             kubectl get clusterrolebindings --field-selector roleRef.name=<old-clusterrole> -o name
             # edit each binding to use the new ClusterRole
             kubectl edit clusterrolebinding <binding-name>
             ```

        6. Verify no ClusterRoles still use wildcards (any machine with kubectl access)
           ```bash theme={null}
           kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers | while read -r clusterrole_name
           do
             clusterrole_rules=$(kubectl get clusterrole "${clusterrole_name}" -o=json | jq -c '.rules')
             if echo "${clusterrole_rules}" | grep -q '\["\*"\]'; then
               clusterrole_is_compliant="false"
             else
               clusterrole_is_compliant="true"
             fi
             echo "**clusterrole_name: ${clusterrole_name} clusterrole_rules: ${clusterrole_rules} clusterrole_is_compliant: ${clusterrole_is_compliant}"
           done
           ```
      </Accordion>

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

        1. Identify noncompliant ClusterRoles (those with `"*"` in rules):

        ```bash theme={null}
        kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers | while read -r clusterrole_name
        do
          clusterrole_rules=$(kubectl get clusterrole "${clusterrole_name}" -o=json | jq -c '.rules')
          if echo "${clusterrole_rules}" | grep -q "\[\"\*\"\]"; then
            echo "${clusterrole_name}"
          fi
        done
        ```

        2. For each noncompliant ClusterRole, export the manifest for editing:

        ```bash theme={null}
        kubectl get clusterrole <CLUSTERROLE_NAME> -o yaml > /tmp/clusterrole-<CLUSTERROLE_NAME>.yaml
        ```

        3. Edit `/tmp/clusterrole-<CLUSTERROLE_NAME>.yaml` and replace wildcard entries with explicit resources/verbs. For example, change:

        ```yaml theme={null}
        rules:
        - apiGroups: ["*"]
          resources: ["*"]
          verbs: ["*"]
        ```

        to something like (adjust to the minimal required permissions):

        ```yaml theme={null}
        rules:
        - apiGroups: [""]
          resources: ["pods", "services"]
          verbs: ["get", "list", "watch"]
        - apiGroups: ["apps"]
          resources: ["deployments"]
          verbs: ["get", "list", "watch"]
        ```

        Ensure no `["*"]` remains in `apiGroups`, `resources`, `verbs`, `resourceNames`, or `nonResourceURLs`.

        4. Apply the updated ClusterRole:

        ```bash theme={null}
        kubectl apply -f /tmp/clusterrole-<CLUSTERROLE_NAME>.yaml
        ```

        Repeat steps 2–4 for each affected ClusterRole.

        5. Verification (rerun check for ClusterRoles):

        ```bash theme={null}
        kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers | while read -r clusterrole_name
        do
          clusterrole_rules=$(kubectl get clusterrole "${clusterrole_name}" -o=json | jq -c '.rules')
          if echo "${clusterrole_rules}" | grep -q "\[\"\*\"\]"; then
            clusterrole_is_compliant="false"
          else
            clusterrole_is_compliant="true"
          fi;
          echo "**clusterrole_name: ${clusterrole_name} clusterrole_rules: ${clusterrole_rules} clusterrole_is_compliant: ${clusterrole_is_compliant}"
        done
        ```
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Purpose: Identify and interactively remediate wildcard (“*”) use in ClusterRoles.
        # Scope:   Run on any machine with kubectl access to the cluster.
        # NOTE:    This control is MANUAL. This script only helps you find and edit
        #          problematic ClusterRoles; it cannot safely choose replacements for "*".

        set -euo pipefail

        # REQUIREMENTS:
        # - kubectl configured to point at the target cluster
        # - jq installed

        # CONFIGURATION:
        EDITOR_CMD="${EDITOR:-kubectl neat 2>/dev/null || true; :}" # not actually used; edits go via kubectl edit

        echo "=== Step 1: Discover ClusterRoles using wildcard [\"*\"] in rules ==="

        noncompliant_clusterroles=()

        while read -r clusterrole_name; do
          # Skip empty lines
          [[ -z "${clusterrole_name}" ]] && continue

          rules_json="$(kubectl get clusterrole "${clusterrole_name}" -o=json | jq -c '.rules')"

          if echo "${rules_json}" | grep -q '\["\*"\]'; then
            noncompliant_clusterroles+=("${clusterrole_name}")
            echo "NON-COMPLIANT: ${clusterrole_name}"
            echo "  rules: ${rules_json}"
          fi
        done < <(kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers)

        if [ "${#noncompliant_clusterroles[@]}" -eq 0 ]; then
          echo "No ClusterRoles with wildcard [\"*\"] in rules were found."
          exit 0
        fi

        echo
        echo "=== Step 2: Manual review & edit guidance ==="
        echo "For each listed ClusterRole, you must:"
        echo "  1) Determine which resources and verbs are actually required."
        echo "  2) Replace any occurrence of \"*\" in:"
        echo "       - .rules[].verbs"
        echo "       - .rules[].resources"
        echo "       - .rules[].apiGroups"
        echo "       - .rules[].resourceNames"
        echo "     with explicit values (e.g. [\"get\",\"list\"] instead of [\"*\"],"
        echo "     or [\"pods\",\"configmaps\"] instead of [\"*\"])."
        echo "  3) Avoid modifying system/provided ClusterRoles unless you fully"
        echo "     understand the impact; prefer creating a new, least-privilege role."

        echo
        echo "You will now be prompted to edit each non-compliant ClusterRole using:"
        echo "  kubectl edit clusterrole <name>"
        echo

        for cr in "${noncompliant_clusterroles[@]}"; do
          echo "----- Editing ClusterRole: ${cr} -----"
          echo "Current rules (JSON):"
          kubectl get clusterrole "${cr}" -o=json | jq '.rules'
          echo
          read -r -p "Open this ClusterRole for editing now? [y/N]: " ans
          case "${ans}" in
            [yY][eE][sS]|[yY])
              # This opens the resource in $EDITOR. User must manually replace "*" with explicit values.
              kubectl edit clusterrole "${cr}"
              ;;
            *)
              echo "Skipping edit for ${cr}. It will remain NON-COMPLIANT until corrected."
              ;;
          esac
          echo
        done

        echo "=== Step 3: Re-run compliance check for ClusterRoles only ==="

        clusterrole_noncompliant_after=0

        while read -r clusterrole_name; do
          [[ -z "${clusterrole_name}" ]] && continue
          clusterrole_rules="$(kubectl get clusterrole "${clusterrole_name}" -o=json | jq -c '.rules')"

          if echo "${clusterrole_rules}" | grep -q '\["\*"\]'; then
            clusterrole_is_compliant="false"
            clusterrole_noncompliant_after=$((clusterrole_noncompliant_after + 1))
          else
            clusterrole_is_compliant="true"
          fi

          echo "**clusterrole_name: ${clusterrole_name} clusterrole_rules: ${clusterrole_rules} clusterrole_is_compliant: ${clusterrole_is_compliant}"
        done < <(kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers)

        echo
        if [ "${clusterrole_noncompliant_after}" -eq 0 ]; then
          echo "Result: All ClusterRoles are now compliant with respect to wildcard [\"*\"] usage."
        else
          echo "Result: ${clusterrole_noncompliant_after} ClusterRole(s) still contain wildcard [\"*\"] in rules."
          echo "Re-run this script after further manual remediation."
        fi
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
