Manage Kubernetes RBAC Users With AWS IAM Authenticator Or
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​
- Remediation
Remediation​
Manual Steps
-
Confirm AWS CLI / authenticator usage (any machine with
kubectland AWS access)aws --versionwhich aws-iam-authenticator || command -v heptio-authenticator-aws- If
awsis older than1.16.156and 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).
- If
-
Inspect how
kubectlauthenticates to the cluster (any machine withkubectl)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) oraws-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.
- If the command is
-
Verify aws-auth ConfigMap is used for RBAC mapping (any machine with
kubectl)kubectl -n kube-system get configmap aws-auth -o yaml- Confirm
mapRolesand/ormapUsersentries 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.
- Confirm
-
Inventory IAM principals that can access the cluster (any machine with AWS CLI)
- List IAM roles/users referenced in
aws-auth: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: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.
- List IAM roles/users referenced in
-
Adjust IAM–RBAC mappings if needed (any machine with
kubectl)- Edit
aws-authto add/remove/update IAM roles/users and Kubernetes groups: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.
- Edit
-
Re-verify access behavior after changes (any machine with
kubectland AWS CLI)- For a given IAM role/user, assume it and attempt to get a token and call the cluster:
aws sts assume-role --role-arn <ROLE_ARN> --role-session-name test-session > /tmp/assume.jsonexport 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-iamKUBECONFIG=~/.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-authand RBAC as required.
- For a given IAM role/user, assume it and attempt to get a token and call the cluster:
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.
Automation
#!/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