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

# Limit Use Of The Bind, Impersonate And Escalate Permissions

### More Info:

The bind, impersonate, and escalate verbs allow privilege escalation beyond a principals assigned permissions. They should only be granted where strictly required for cluster operation.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS AKS

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **List all Roles/ClusterRoles using bind/impersonate/escalate**
           * Run on: any machine with kubectl access
           ```bash theme={null}
           kubectl get clusterroles -o json \
             | jq -r '.items[]
               | select(.rules[]
                 | select(.verbs[]? as $v
                   | ["bind","impersonate","escalate"] | index($v)))
               | .metadata.name' | sort -u
           ```
           ```bash theme={null}
           kubectl get roles --all-namespaces -o json \
             | jq -r '.items[]
               | select(.rules[]
                 | select(.verbs[]? as $v
                   | ["bind","impersonate","escalate"] | index($v)))
               | "\(.metadata.namespace):\(.metadata.name)"' | sort -u
           ```

        2. **Exclude known Kubernetes system roles from modification**
           * Run on: any machine with kubectl access
           * Identify roles that are likely required system roles and note them for special care (usually do not change without strong justification):
           ```bash theme={null}
           kubectl get clusterroles \
             system:masters \
             clusterrole-aggregation-controller \
             system:controller:service-account-controller \
             -o yaml || true
           ```
           * For each ClusterRole/Role from step 1, check if its name starts with `system:` or is clearly a control-plane/controller role; mark those as “system – review but generally keep”.

        3. **Inspect each non‑system ClusterRole/Role rule detail**
           * Run on: any machine with kubectl access
           * For each name from step 1 that is *not* a system role, show full spec:
           ```bash theme={null}
           # Example for a cluster role
           kubectl get clusterrole <clusterrole-name> -o yaml

           # Example for a namespaced role
           kubectl get role <role-name> -n <namespace> -o yaml
           ```
           * For each, record:
             * Which verb(s) are present: `bind`, `impersonate`, `escalate`
             * Which `apiGroups`, `resources`, and `resourceNames` they apply to
             * Whether the scope (cluster-wide vs namespace) matches a real operational need.

        4. **Identify who is bound to these powerful roles**
           * Run on: any machine with kubectl access
           ```bash theme={null}
           # ClusterRoleBindings to roles found in step 1
           kubectl get clusterrolebindings -o yaml \
             | yq '.items[] |
               select(.roleRef.kind == "ClusterRole" and
                      (.roleRef.name == "<clusterrole-name-1>" or
                       .roleRef.name == "<clusterrole-name-2>" )) |
               {name: .metadata.name, role: .roleRef.name, subjects: .subjects}'
           ```
           ```bash theme={null}
           # RoleBindings in all namespaces
           kubectl get rolebindings --all-namespaces -o yaml \
             | yq '.items[] |
               select(.roleRef.kind == "Role" and
                      (.roleRef.name == "<role-name-1>" or
                       .roleRef.name == "<role-name-2>" )) |
               {ns: .metadata.namespace, name: .metadata.name, role: .roleRef.name, subjects: .subjects}'
           ```
           * For each binding, decide if each subject (user, group, service account) truly requires these verbs for its function. Flag any human users or generic service accounts as high priority to restrict.

        5. **Decide and apply least-privilege changes**
           * Run on: any machine with kubectl access
           * For each non‑system role where use is not strictly required:
             * Prefer narrowing permissions before removal:
               * Remove unnecessary verbs (`bind`, `impersonate`, `escalate`) from the rules.
               * Restrict resources / resourceNames to the minimal required set.
             * If no subject legitimately needs those verbs, remove them entirely from the role.
           * Apply by editing the role definitions:
           ```bash theme={null}
           # Edit a ClusterRole
           kubectl edit clusterrole <clusterrole-name>

           # Edit a namespaced Role
           kubectl edit role <role-name> -n <namespace>
           ```
           * If necessary, adjust bindings to use a different, less-privileged Role/ClusterRole instead of the powerful one.

        6. **Re-verify the cluster for remaining bind/impersonate/escalate use**
           * Run on: any machine with kubectl access
           ```bash theme={null}
           kubectl get clusterroles -o json \
             | jq -r '.items[]
               | select(.rules[]
                 | select(.verbs[]? as $v
                   | ["bind","impersonate","escalate"] | index($v)))
               | .metadata.name' | sort -u
           ```
           ```bash theme={null}
           kubectl get roles --all-namespaces -o json \
             | jq -r '.items[]
               | select(.rules[]
                 | select(.verbs[]? as $v
                   | ["bind","impersonate","escalate"] | index($v)))
               | "\(.metadata.namespace):\(.metadata.name)"' | sort -u
           ```
           * Confirm that:
             * Only necessary system roles and explicitly justified operational roles retain these verbs.
             * Non-system users and service accounts no longer have unjustified access to them via RoleBindings/ClusterRoleBindings.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all ClusterRoles that use bind, impersonate, or escalate
        # Run on: any machine with kubectl access
        kubectl get clusterroles -o json | jq '
          .items[]
          | select(
              [.rules[].verbs[]?] | inside(["bind","impersonate","escalate"]) or
              ([.rules[].verbs[]?] | map(select(.=="bind" or .=="impersonate" or .=="escalate")) | length > 0)
            )
          | {name: .metadata.name, rules: .rules}
        '

        # 2) List all namespace Roles that use bind, impersonate, or escalate
        kubectl get roles --all-namespaces -o json | jq '
          .items[]
          | select(
              [.rules[].verbs[]?] | inside(["bind","impersonate","escalate"]) or
              ([.rules[].verbs[]?] | map(select(.=="bind" or .=="impersonate" or .=="escalate")) | length > 0)
            )
          | {namespace: .metadata.namespace, name: .metadata.name, rules: .rules}
        '
        ```

        What indicates a problem:

        * Any `ClusterRole` or `Role` in the output whose `metadata.name` or `metadata.namespace` suggests it belongs to:
          * Application-specific components (e.g. business apps, CI/CD jobs, monitoring agents), or
          * Human users (e.g. `dev-*`, `qa-*`, `ops-*`, `admin-*`),
            and whose `rules` contain verbs `bind`, `impersonate`, or `escalate`.
        * Roles not obviously part of Kubernetes’ own system roles/groups (for example, not starting with `system:` and not documented as core cluster controllers) that have these verbs.

        You must manually decide:

        * Whether each non-system role truly needs `bind`, `impersonate`, or `escalate` for its function.
        * Whether these verbs can be removed or split into a more constrained role.

        To inspect a specific suspicious role in more detail:

        ```bash theme={null}
        # Inspect a ClusterRole
        kubectl get clusterrole <clusterrole-name> -o yaml

        # Inspect a namespaced Role
        kubectl get role <role-name> -n <namespace> -o yaml
        ```

        To see who is using a suspicious role:

        ```bash theme={null}
        # ClusterRoleBindings referencing the role
        kubectl get clusterrolebindings -o json | jq '
          .items[]
          | select(.roleRef.kind=="ClusterRole" and .roleRef.name=="<clusterrole-name>")
          | {name: .metadata.name, subjects: .subjects}
        '

        # RoleBindings referencing a namespaced Role
        kubectl get rolebindings -A -o json | jq '
          .items[]
          | select(.roleRef.kind=="Role" and .roleRef.name=="<role-name>" and .metadata.namespace=="<namespace>")
          | {namespace: .metadata.namespace, name: .metadata.name, subjects: .subjects}
        '
        ```

        Verification after you make any manual changes:

        ```bash theme={null}
        # Re-run the discovery to confirm only intended system roles have these verbs
        kubectl get clusterroles -o json | jq '
          .items[]
          | select([.rules[].verbs[]?] | map(select(.=="bind" or .=="impersonate" or .=="escalate")) | length > 0)
          | .metadata.name
        '

        kubectl get roles --all-namespaces -o json | jq '
          .items[]
          | select([.rules[].verbs[]?] | map(select(.=="bind" or .=="impersonate" or .=="escalate")) | length > 0)
          | {namespace: .metadata.namespace, name: .metadata.name}
        '
        ```

        The remaining names should be only Kubernetes system roles that you have consciously approved to retain these permissions (for example, `system:masters`, `clusterrole-aggregation-controller`, or other documented system roles in your environment).
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report Roles/ClusterRoles that use bind, impersonate, or escalate
        # Run on: any machine with kubectl access and current-context set to the target cluster

        set -euo pipefail

        # Verbs of interest
        VERBS='bind|impersonate|escalate'

        echo "=== ClusterRoles with bind/impersonate/escalate ==="
        kubectl get clusterroles -o json \
          | jq -r '
            .items[]
            | {
                name: .metadata.name,
                rules: (
                  .rules // []
                  | map(
                      select(
                        (.verbs // []) | map(tostring) | map(ascii_downcase)
                        | join(" ")
                        | test("'"$VERBS"")
                      )
                    )
                )
              }
            | select(.rules | length > 0)
            | "ClusterRole: \(.name)\n" +
              (
                .rules[]
                | "  Resources: \(.resources // ["-""] | join(","))\n" +
                  "  APIGroups: \(.apiGroups // ["-""] | join(","))\n" +
                  "  Verbs: \(.verbs // ["-""] | join(","))\n"
              )
          ' | sed '/^$/d' || echo "Failed to list ClusterRoles"

        echo
        echo "=== Namespaced Roles with bind/impersonate/escalate ==="
        kubectl get roles --all-namespaces -o json \
          | jq -r '
            .items[]
            | {
                ns: .metadata.namespace,
                name: .metadata.name,
                rules: (
                  .rules // []
                  | map(
                      select(
                        (.verbs // []) | map(tostring) | map(ascii_downcase)
                        | join(" ")
                        | test("'"$VERBS"")
                      )
                    )
                )
              }
            | select(.rules | length > 0)
            | "Role: \(.ns)/\(.name)\n" +
              (
                .rules[]
                | "  Resources: \(.resources // ["-""] | join(","))\n" +
                  "  APIGroups: \(.apiGroups // ["-""] | join(","))\n" +
                  "  Verbs: \(.verbs // ["-""] | join(","))\n"
              )
          ' | sed '/^$/d' || echo "Failed to list Roles"

        echo
        echo "=== RoleBindings & ClusterRoleBindings that reference these roles ==="

        # Build a list of roleRef targets that have the sensitive verbs
        SENSITIVE_CLUSTERROLES=$(kubectl get clusterroles -o json \
          | jq -r '
            .items[]
            | select(
                (.rules // [])
                | map(
                    (.verbs // []) | map(tostring) | map(ascii_downcase)
                    | join(" ")
                    | test("'"$VERBS"")
                  )
                | any
              )
            | .metadata.name
          ')

        SENSITIVE_ROLES=$(kubectl get roles --all-namespaces -o json \
          | jq -r '
            .items[]
            | select(
                (.rules // [])
                | map(
                    (.verbs // []) | map(tostring) | map(ascii_downcase)
                    | join(" ")
                    | test("'"$VERBS"")
                  )
                | any
              )
            | (.metadata.namespace + ":" + .metadata.name)
          ')

        echo "--- ClusterRoleBindings ---"
        kubectl get clusterrolebindings -o json \
          | jq -r --argjson crNames "$(printf '%s\n' $SENSITIVE_CLUSTERROLES | jq -R . | jq -s .)" '
            .items[]
            | select(
                .roleRef.kind == "ClusterRole"
                and (.roleRef.name as $rn | $crNames | index($rn))
              )
            | "ClusterRoleBinding: \(.metadata.name)\n" +
              "  roleRef: \(.roleRef.kind)/\(.roleRef.name)\n" +
              (
                "  subjects:\n" +
                (
                  (.subjects // [])
                  | map("    - kind=\(.kind) name=\(.name) namespace=\(.namespace // "-")")
                  | join("\n")
                )
              ) + "\n"
          ' | sed '/^$/d' || echo "Failed to list ClusterRoleBindings"

        echo
        echo "--- RoleBindings ---"
        kubectl get rolebindings --all-namespaces -o json \
          | jq -r --argjson rNames "$(printf '%s\n' $SENSITIVE_ROLES | jq -R . | jq -s .)" '
            .items[]
            | . as $rb
            | select(
                .roleRef.kind == "Role"
                and (
                  ($rb.metadata.namespace + ":" + $rb.roleRef.name) as $key
                  | $rNames | index($key)
                )
              )
            | "RoleBinding: \(.metadata.namespace)/\(.metadata.name)\n" +
              "  roleRef: \(.roleRef.kind)/\(.roleRef.name)\n" +
              (
                "  subjects:\n" +
                (
                  (.subjects // [])
                  | map("    - kind=\(.kind) name=\(.name) namespace=\(.namespace // "-")")
                  | join("\n")
                )
              ) + "\n"
          ' | sed '/^$/d' || echo "Failed to list RoleBindings"

        echo
        echo "=== Interpretation ==="
        cat <<'EOF'
        Any ClusterRole or Role listed above that:
        - is not clearly a Kubernetes system role (e.g. system:*, clusterrole-aggregation-controller, system:masters), and
        - grants bind, impersonate, or escalate

        should be manually reviewed. Pay particular attention to:

        1) Human users or non-system service accounts in the listed RoleBindings/ClusterRoleBindings.
        2) Namespaces used by application workloads (non-kube-* namespaces).

        These cases typically indicate over-privilege and should be candidates for removing
        bind/impersonate/escalate or replacing with more limited permissions.

        No changes are made by this script; it only reports state for manual review.
        EOF
        ```

        **Output indicating a problem**

        * Any `ClusterRole:` or `Role:` that is not a known system role and shows `Verbs:` containing `bind`, `impersonate`, or `escalate`.
        * Any `ClusterRoleBinding:` or `RoleBinding:` where:
          * `roleRef` points to one of those roles, and
          * `subjects` list non-system users or service accounts (e.g., app service accounts in application namespaces).
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
