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

# Manage Kubernetes RBAC Users With AWS IAM Authenticator Or Upgrade AWS CLI

### More Info:

Manage Kubernetes RBAC users through the AWS IAM Authenticator (or AWS CLI v1.16.156 or greater) so cluster access is tied to IAM identities.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS EKS

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Confirm AWS CLI / authenticator usage** (any machine with `kubectl` and AWS access)
           ```bash theme={null}
           aws --version
           which aws-iam-authenticator || command -v heptio-authenticator-aws
           ```
           * If `aws` is older than `1.16.156` and you rely on it for cluster auth, plan to upgrade.
           * If you use `aws-iam-authenticator`, confirm it’s the configured auth method (e.g., in kubeconfig, see next step).

        2. **Inspect how `kubectl` authenticates to the cluster** (any machine with `kubectl`)
           ```bash theme={null}
           kubectl config view --minify -o jsonpath='{.users[0].user.exec.command}{" "}{.users[0].user.exec.args[*]}' ; echo
           ```
           * If the command is `aws eks get-token` (AWS CLI ≥ 1.16.156) or `aws-iam-authenticator`, you are using supported IAM-based auth.
           * If some other exec/plugin or static token/cert is used, plan to migrate to IAM-based auth with either AWS CLI or AWS IAM Authenticator.

        3. **Verify aws-auth ConfigMap is used for RBAC mapping** (any machine with `kubectl`)
           ```bash theme={null}
           kubectl -n kube-system get configmap aws-auth -o yaml
           ```
           * Confirm `mapRoles` and/or `mapUsers` entries tie IAM roles/users to Kubernetes groups (e.g., `system:masters`, app-specific groups).
           * If access is granted via non-IAM credentials (e.g., bootstrap admin kubeconfig only), plan to define appropriate IAM identity mappings here.

        4. **Inventory IAM principals that can access the cluster** (any machine with AWS CLI)
           * List IAM roles/users referenced in `aws-auth`:
             ```bash theme={null}
             kubectl -n kube-system get configmap aws-auth -o jsonpath='{.data.mapRoles}{"\n"}{.data.mapUsers}{"\n"}'
             ```
           * For each `rolearn` / `userarn`, inspect IAM policy and trust:
             ```bash theme={null}
             aws iam get-role --role-name <ROLE_NAME>
             aws iam list-attached-role-policies --role-name <ROLE_NAME>
             aws iam list-role-policies --role-name <ROLE_NAME>
             ```
           * Decide whether these IAM identities are appropriate and least-privilege for their mapped Kubernetes groups.

        5. **Adjust IAM–RBAC mappings if needed** (any machine with `kubectl`)
           * Edit `aws-auth` to add/remove/update IAM roles/users and Kubernetes groups:
             ```bash theme={null}
             kubectl -n kube-system edit configmap aws-auth
             ```
           * Ensure:
             * Only intended IAM roles/users are mapped.
             * Admin-level groups (e.g., `system:masters`) are granted only to tightly controlled IAM roles.
             * Application roles map to scoped Kubernetes groups/ClusterRoles defined in your manifests/IaC.

        6. **Re-verify access behavior after changes** (any machine with `kubectl` and AWS CLI)
           * For a given IAM role/user, assume it and attempt to get a token and call the cluster:
             ```bash theme={null}
             aws sts assume-role --role-arn <ROLE_ARN> --role-session-name test-session > /tmp/assume.json
             export AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' /tmp/assume.json)
             export AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' /tmp/assume.json)
             export AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' /tmp/assume.json)

             aws eks update-kubeconfig --region <REGION> --name <CLUSTER_NAME> --alias test-iam
             KUBECONFIG=~/.kube/config kubectl --context test-iam auth can-i get pods -A
             ```
           * Confirm the resulting permissions match the intended RBAC for that IAM principal; iterate on `aws-auth` and RBAC as required.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot configure how Kubernetes RBAC users are mapped to AWS IAM identities or which AWS CLI/IAM Authenticator mechanism is used; this is controlled in the EKS/cluster IAM configuration via the AWS console, CLI, or IaC. To address this finding, make the required changes at the cloud provider / managed control plane level as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Audit EKS RBAC identities vs AWS IAM integration
        # Run from: any machine with kubectl + aws CLI access to the cluster
        # Requires: kubectl, aws, jq, base64

        set -euo pipefail

        # CONFIG: set your AWS region and EKS cluster name
        AWS_REGION="us-east-1"
        EKS_CLUSTER_NAME="my-eks-cluster"

        echo "=== 1) AWS CLI version check ==="
        aws --version || { echo "aws CLI not found in PATH"; exit 1; }
        AWS_CLI_VERSION_RAW="$(aws --version 2>&1 | awk '{print $1}' | cut -d/ -f2)"
        echo "Detected aws CLI version: ${AWS_CLI_VERSION_RAW}"

        # Very small version comparator: returns 0 if v1 >= 1.16.156 or any v2+
        ver_ge() {
          # args: MAJOR.MINOR.PATCH MINOR_TH PATCHTH
          local major="${1%%.*}"
          local rest="${1#*.}"
          local minor="${rest%%.*}"
          local patch="${rest#*.}"

          local t_major="$2" t_minor="$3" t_patch="$4"

          if (( major > t_major )); then return 0; fi
          if (( major < t_major )); then return 1; fi
          if (( minor > t_minor )); then return 0; fi
          if (( minor < t_minor )); then return 1; fi
          if (( patch >= t_patch )); then return 0; fi
          return 1
        }

        AWS_CLI_MAJOR="${AWS_CLI_VERSION_RAW%%.*}"
        if [[ "$AWS_CLI_MAJOR" -ge 2 ]]; then
          echo "OK: aws CLI v2 is in use; IAM Authenticator is not required."
        else
          if ver_ge "$AWS_CLI_VERSION_RAW" 1 16 156; then
            echo "OK: aws CLI v1.${AWS_CLI_VERSION_RAW#1.} >= 1.16.156; IAM Authenticator is not required."
          else
            echo "POTENTIAL ISSUE: aws CLI is < 1.16.156. If you rely on aws eks get-token,"
            echo "you should either upgrade aws CLI or ensure aws-iam-authenticator is used correctly."
          fi
        fi

        echo
        echo "=== 2) Identify likely EKS cluster from kubeconfig ==="
        CURRENT_CTX="$(kubectl config current-context)"
        echo "Current kubectl context: ${CURRENT_CTX}"

        echo
        echo "=== 3) Inspect current-context exec auth configuration ==="
        kubectl config view -o json \
          | jq --arg ctx "$CURRENT_CTX" '
            .contexts[] | select(.name == $ctx) | .context.user as $userName
            | {context: $ctx, userName: $userName}
          '
        echo

        kubectl config view -o json \
          | jq --arg ctx "$CURRENT_CTX" '
            .contexts[] | select(.name == $ctx) | .context.user as $userName
            | {userName: $userName}
            as $u
            | . as $root
            | $root.users[]
            | select(.name == $u.userName)
            | {userName: .name, user: .user}
          '

        cat <<'EOF'

        INTERPRETATION:
        - If the 'user' block under the current context shows:
            "exec": {
              "apiVersion": "client.authentication.k8s.io/v1beta1",
              "command": "aws",
              "args": ["eks", "get-token", ...]
          then authentication is using aws CLI, which is acceptable when tied to IAM identities.

        - If the exec command is 'aws-iam-authenticator', authentication is via the AWS IAM Authenticator binary,
          which is also acceptable when configured correctly.

        - POTENTIAL PROBLEMS:
          * No 'exec' section at all (e.g., using a static token, basic auth, or a client certificate not bound to IAM).
          * 'exec' uses a non-AWS command (custom script / external OIDC token not backed by IAM),
            which may mean RBAC users are not tied directly to AWS IAM identities.

        EOF

        echo "=== 4) Discover RBAC subjects that look like IAM identities ==="
        echo "Collecting ClusterRoles/ClusterRoleBindings/RoleBindings..."

        # Gather all RBAC bindings and show subjects
        kubectl get clusterrolebinding,rolebinding --all-namespaces -o json \
          | jq '
            .items[]
            | {
                kind: .kind,
                name: .metadata.name,
                namespace: .metadata.namespace,
                subjects: (.subjects // [])
              }
          '

        cat <<'EOF'

        INTERPRETATION:
        - In EKS, subjects that map IAM to Kubernetes RBAC typically look like:
          * kind: User
            name: "arn:aws:iam::<ACCOUNT-ID>:user/..."
          * kind: User
            name: "arn:aws:iam::<ACCOUNT-ID>:role/..."
          * kind: Group
            name: "system:masters"  (mapped via aws-auth ConfigMap from IAM entities)

        - POTENTIAL PROBLEMS:
          * Subjects with arbitrary usernames (e.g. "alice", "bob") not corresponding to IAM ARNs.
          * Client-certificate subjects mapped directly to ClusterRoleBindings (kind: User) with non-IAM names.
          * Service accounts are expected for in-cluster workloads, but *human* or external users
            should normally be IAM identities mapped via the aws-auth ConfigMap.

        EOF

        echo "=== 5) Inspect aws-auth ConfigMap for IAM-to-RBAC mappings ==="
        if kubectl get configmap aws-auth -n kube-system >/dev/null 2>&1; then
          kubectl get configmap aws-auth -n kube-system -o yaml
        else
          echo "POTENTIAL ISSUE: aws-auth ConfigMap not found in kube-system namespace."
          echo "This may indicate no explicit IAM role/user to RBAC mappings are configured."
        fi

        cat <<'EOF'

        INTERPRETATION OF aws-auth:
        - Under data.mapRoles and data.mapUsers you should see YAML entries like:
          - rolearn: arn:aws:iam::<ACCOUNT-ID>:role/SomeRole
            username: some-k8s-username
            groups:
              - system:masters
              - some-other-group

        - These entries show which IAM roles/users map into Kubernetes RBAC groups.

        - POTENTIAL PROBLEMS:
          * No mapRoles/mapUsers at all, but cluster access is granted via static kubeconfig
            users unrelated to IAM.
          * mapRoles/mapUsers names that imply shared or generic identities (e.g., "admin", "poweruser")
            without clear IAM ownership and least privilege.

        EOF

        echo "=== 6) Optional: list who can get tokens using aws CLI on this machine ==="
        echo "This does NOT enumerate all cluster users, only what the current AWS identity can do."

        aws sts get-caller-identity --region "${AWS_REGION}"

        aws eks describe-cluster \
          --name "${EKS_CLUSTER_NAME}" \
          --region "${AWS_REGION}" \
          --query 'cluster.{name:name,arn:arn,endpoint:endpoint,version:version}'

        cat <<'EOF'

        HOW TO SPOT PROBLEMS OVERALL:
        - You are NOT aligned with the benchmark intent if:
          * Human/admin access uses static certificates, static bearer tokens, or generic local users
            in kubeconfig instead of aws eks get-token or aws-iam-authenticator.
          * Kubernetes RBAC bindings (ClusterRoleBindings/RoleBindings) primarily reference
            non-IAM usernames for humans (e.g., "admin", "jane", "ops-user") that are not
            IAM ARNs mapped via aws-auth.
          * The aws-auth ConfigMap is missing or nearly empty while significant access
            is granted to non-IAM users.

        - The benchmark is BETTER satisfied when:
          * All human/admin kubectl access authenticates via AWS IAM (aws eks get-token
            or aws-iam-authenticator), and
          * RBAC grants permissions to identities that originate from IAM roles/users
            mapped through aws-auth.

        NOTE:
        - This script only reports; it does NOT change configuration.
        - Use its output to decide:
          * Whether to move non-IAM users to IAM-backed authentication, and
          * Whether to adjust aws-auth mappings and RBAC bindings.

        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
