Skip to main content

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​

Manual Steps
  1. Confirm AWS CLI / authenticator usage (any machine with kubectl and AWS access)

    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)

    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)

    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:
      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.
  5. Adjust IAM–RBAC mappings if needed (any machine with kubectl)

    • Edit aws-auth to 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.
  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:
      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.
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