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
- Remediation
Remediation
Manual Steps
-
On any machine with kubectl access, confirm cluster identity and context to avoid changing the wrong cluster:
kubectl config current-contextkubectl config view --minify -
Still on the kubectl machine, check whether the legacy
aws-authConfigMap is in use and inspect its contents:kubectl get configmap aws-auth -n kube-system -o yamlReview:
- Whether
mapRoles,mapUsers, ormapAccountsare present. - Who currently has access (IAM roles/users/accounts) and whether this matches your organization’s intended access model.
- Whether
-
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).
-
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.
-
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-authas the source of truth and maintain it via GitOps/IaC, ensuring its contents are regularly reviewed and audited.
- 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
-
Re-verify configuration after any changes:
- In the console: confirm the “Cluster authentication mode” under Access → Access configuration.
- With kubectl: confirm
aws-authmatches your intended mapping (or is empty/unused if you’ve fully moved to EKS API):kubectl get configmap aws-auth -n kube-system -o yaml
Using kubectl
# 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
ConfigMapauthentication mode, that’s a problem. - If
mapRoles/mapUsers/mapAccountscontain 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-arnmapping you don’t recognize or that grants cluster-admin privileges widely, that is a red flag.
# 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
ClusterRoleBindingobjects that bindcluster-admin(or other powerful roles) to subjects that correspond to IAM users/roles (often viasystem:mastersgroup or mapped IAM entities inaws-auth) more broadly than intended. - Any binding that effectively grants admin rights to principals you did not intend to be administrators is a problem.
# 3. Inspect a specific powerful binding in detail (any machine with kubectl access)
kubectl get clusterrolebinding <binding-name> -o yaml
Review points:
- Confirm that
subjectsmatch 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.
# 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-authmappings and RBAC.
Explanation of what kubectl cannot show:
kubectlcannot 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.
Automation
#!/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 andaws-authare in play.EKSAUTH/EKS_API-only orCONFIG_MAP-only are consistent with a single source, but must match your intended design.
-
ACCESS_ENTRY_COUNT:- If
AUTH_MODEisEKS_API(or equivalent) andACCESS_ENTRY_COUNTis0, access via IAM/EKS API may be misconfigured or overly restrictive.
- If
-
HAS_CM/CM_MODE:- If
AUTH_MODEisEKS_APIbutHAS_CM=YESandCM_MODE=ACTIVE, there are legacyaws-authmappings that should be reviewed and possibly removed. - If
AUTH_MODEisCONFIG_MAPandHAS_CM=NOorCM_MODE=EMPTY, the cluster may not have any IAM principal mappings configured.
- If
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.