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

# Use Cluster Access Manager API To Manage Access Controls

### More Info:

The Cluster Access Manager API streamlines management of authenticated IAM principals for EKS clusters. Choose the appropriate authentication mode to centralize and secure access control.

### 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. On any machine with kubectl access, confirm cluster identity and context to avoid changing the wrong cluster:
           ```bash theme={null}
           kubectl config current-context
           kubectl config view --minify
           ```

        2. Still on the kubectl machine, check whether the legacy `aws-auth` ConfigMap is in use and inspect its contents:
           ```bash theme={null}
           kubectl get configmap aws-auth -n kube-system -o yaml
           ```
           Review:
           * Whether `mapRoles`, `mapUsers`, or `mapAccounts` are present.
           * Who currently has access (IAM roles/users/accounts) and whether this matches your organization’s intended access model.

        3. In the AWS Management Console, navigate to Amazon EKS → your cluster → Access → Access configuration and review:
           * The “Cluster authentication mode” setting (EKS API vs ConfigMap).
           * Whether this matches your intended source of authenticated IAM principals (centralized via EKS Access Entries, or managed via `aws-auth`).

        4. If the cluster authentication mode does not align with your desired model and the cluster is newly created or being created via IaC, adjust it at creation time:
           * In the console: choose either **EKS API** or **ConfigMap** under “Cluster authentication mode” before provisioning.
           * In IaC (CloudFormation/Terraform/etc.): set the equivalent parameter for authentication mode so that future clusters are created with the correct setting.

        5. For existing clusters (where authentication mode cannot be changed), decide on your management model:
           * If using **EKS API**: ensure all required IAM principals are granted access via EKS Access Entries (console or IaC) and gradually phase out any reliance on `aws-auth`.
           * If using **ConfigMap**: keep `aws-auth` as the source of truth and maintain it via GitOps/IaC, ensuring its contents are regularly reviewed and audited.

        6. Re-verify configuration after any changes:
           * In the console: confirm the “Cluster authentication mode” under Access → Access configuration.
           * With kubectl: confirm `aws-auth` matches your intended mapping (or is empty/unused if you’ve fully moved to EKS API):
             ```bash theme={null}
             kubectl get configmap aws-auth -n kube-system -o yaml
             ```
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1. Check aws-auth ConfigMap (any machine with kubectl access)
        kubectl -n kube-system get configmap aws-auth -o yaml
        ```

        Review points:

        * If the ConfigMap does not exist or is empty but you expect to be using `ConfigMap` authentication mode, that’s a problem.
        * If `mapRoles` / `mapUsers` / `mapAccounts` contain IAM principals that should not have cluster access, or use overly broad roles (e.g., admin roles for many users), that indicates a problem with access control design.
        * If there is an `eks.amazonaws.com/role-arn` mapping you don’t recognize or that grants cluster-admin privileges widely, that is a red flag.

        ```bash theme={null}
        # 2. Check which subjects currently have RBAC-level access (any machine with kubectl access)
        kubectl get clusterrolebindings -o wide
        kubectl get rolebindings -A -o wide
        ```

        Review points:

        * Look for `ClusterRoleBinding` objects that bind `cluster-admin` (or other powerful roles) to subjects that correspond to IAM users/roles (often via `system:masters` group or mapped IAM entities in `aws-auth`) more broadly than intended.
        * Any binding that effectively grants admin rights to principals you did not intend to be administrators is a problem.

        ```bash theme={null}
        # 3. Inspect a specific powerful binding in detail (any machine with kubectl access)
        kubectl get clusterrolebinding <binding-name> -o yaml
        ```

        Review points:

        * Confirm that `subjects` match only the IAM-mapped Kubernetes users/groups that should have that level of access.
        * Mismatches between intended IAM principals and actual bound subjects indicate misaligned access control.

        ```bash theme={null}
        # 4. Confirm current authentication behavior at the API server level (any machine with kubectl access)
        kubectl auth can-i --list
        ```

        Review points:

        * Run this as different principals (e.g., assume different IAM roles and re-run `kubectl auth can-i --list`) to see what each IAM-mapped identity can do.
        * If non-admin IAM principals can perform cluster-admin-level actions (create clusterroles, clusterrolebindings, etc.) when they should not, that indicates a problem in your current combination of `aws-auth` mappings and RBAC.

        Explanation of what kubectl cannot show:

        * `kubectl` cannot display or change the EKS Cluster Authentication Mode itself (EKS API vs ConfigMap); that setting is only visible and configurable via the AWS console/CLI/IaC at cluster creation time. Use the above commands to understand the *effective* access model and then review the cluster’s Authentication Mode manually in the AWS console as described in the remediation.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report EKS Cluster Access Manager / authentication mode state
        # Run on: any machine with kubectl and AWS CLI configured

        set -euo pipefail

        # Optional: restrict to a single region by setting AWS_REGION beforehand
        : "${AWS_REGION:=}"

        echo "=== Detecting EKS clusters and their authentication mode ===" >&2

        # Get all clusters (optionally per-region if AWS_REGION is set)
        if [ -n "${AWS_REGION}" ]; then
          clusters=$(aws eks list-clusters --region "$AWS_REGION" --output text --query 'clusters[]')
        else
          # All regions
          regions=$(aws ec2 describe-regions --output text --query 'Regions[].RegionName')
          clusters=""
          for r in $regions; do
            c=$(aws eks list-clusters --region "$r" --output text --query 'clusters[]' || true)
            if [ -n "$c" ]; then
              for name in $c; do
                clusters+="${r}:${name}"$'\n'
              done
            fi
          done
        fi

        if [ -z "${clusters:-}" ]; then
          echo "No EKS clusters found." >&2
          exit 0
        fi

        printf "%-20s %-40s %-20s %-30s %-10s %-10s\n" "REGION" "CLUSTER_NAME" "AUTH_MODE" "ACCESS_ENTRY_COUNT" "HAS_CM" "CM_MODE"

        if [ -n "${AWS_REGION}" ]; then
          # clusters is just names when a single region is used
          for name in $clusters; do
            region="$AWS_REGION"
            mode=$(aws eks describe-cluster \
              --region "$region" \
              --name "$name" \
              --query 'cluster.accessConfig.authenticationMode' \
              --output text 2>/dev/null || echo "UNKNOWN")

            # Count EKS Access Entries (only useful if mode is EKS_API or API_AND_CONFIG_MAP)
            entry_count=$(aws eks list-access-entries \
              --region "$region" \
              --cluster-name "$name" \
              --query 'length(accessEntries)' \
              --output text 2>/dev/null || echo "0")

            # Inspect aws-auth ConfigMap via kubectl (if this cluster context exists)
            # Assumes kubeconfig has a context matching the cluster name
            has_cm="NO"
            cm_mode="N/A"
            if kubectl config get-contexts -o name | grep -qx "$name"; then
              ctx="$name"
              if kubectl --context "$ctx" get configmap aws-auth -n kube-system >/dev/null 2>&1; then
                has_cm="YES"
                # Very simple heuristic: if mapRoles or mapUsers are non-empty, say "ACTIVE"
                data=$(kubectl --context "$ctx" get configmap aws-auth -n kube-system -o jsonpath='{.data}' 2>/dev/null || echo "")
                if echo "$data" | grep -qE 'mapRoles:|mapUsers:'; then
                  cm_mode="ACTIVE"
                else
                  cm_mode="EMPTY"
                fi
              fi
            fi

            printf "%-20s %-40s %-20s %-30s %-10s %-10s\n" "$region" "$name" "$mode" "$entry_count" "$has_cm" "$cm_mode"
          done
        else
          # clusters is region:name lines
          while IFS=: read -r region name; do
            [ -z "$region" ] && continue

            mode=$(aws eks describe-cluster \
              --region "$region" \
              --name "$name" \
              --query 'cluster.accessConfig.authenticationMode' \
              --output text 2>/dev/null || echo "UNKNOWN")

            entry_count=$(aws eks list-access-entries \
              --region "$region" \
              --cluster-name "$name" \
              --query 'length(accessEntries)' \
              --output text 2>/dev/null || echo "0")

            has_cm="NO"
            cm_mode="N/A"
            if kubectl config get-contexts -o name | grep -qx "$name"; then
              ctx="$name"
              if kubectl --context "$ctx" get configmap aws-auth -n kube-system >/dev/null 2>&1; then
                has_cm="YES"
                data=$(kubectl --context "$ctx" get configmap aws-auth -n kube-system -o jsonpath='{.data}' 2>/dev/null || echo "")
                if echo "$data" | grep -qE 'mapRoles:|mapUsers:'; then
                  cm_mode="ACTIVE"
                else
                  cm_mode="EMPTY"
                fi
              fi
            fi

            printf "%-20s %-40s %-20s %-30s %-10s %-10s\n" "$region" "$name" "$mode" "$entry_count" "$has_cm" "$cm_mode"
          done <<< "$clusters"
        fi
        ```

        Explanation of output and what indicates a problem (for review):

        * `AUTH_MODE`:
          * `API_AND_CONFIG_MAP` (or similar mixed modes) requires review: both EKS Access Entries and `aws-auth` are in play.
          * `EKSAUTH`/`EKS_API`-only or `CONFIG_MAP`-only are consistent with a single source, but must match your intended design.

        * `ACCESS_ENTRY_COUNT`:
          * If `AUTH_MODE` is `EKS_API` (or equivalent) and `ACCESS_ENTRY_COUNT` is `0`, access via IAM/EKS API may be misconfigured or overly restrictive.

        * `HAS_CM` / `CM_MODE`:
          * If `AUTH_MODE` is `EKS_API` but `HAS_CM=YES` and `CM_MODE=ACTIVE`, there are legacy `aws-auth` mappings that should be reviewed and possibly removed.
          * If `AUTH_MODE` is `CONFIG_MAP` and `HAS_CM=NO` or `CM_MODE=EMPTY`, the cluster may not have any IAM principal mappings configured.

        This script does not change any configuration; it only surfaces current state so you can manually decide whether the Cluster Authentication Mode and `aws-auth` usage match your security requirements.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
