Adding limited access IAM user to EKS Cluster
Introduction
Elastic Kubernetes Service (EKS) is the fully managed Kubernetes service from AWS. It is deeply integrated with many AWS services such as AWS Identity and Access Management (IAM) for authentication to the cluster, Amazon CloudWatch for logging, Auto Scaling Groups for scaling the worker nodes, and Amazon Virtual Private Cloud (VPC) for networking. Many reputed companies trust Amazon EKS to run their containerized workloads.

EKS uses IAM to provide authentication to your Kubernetes cluster (via the aws eks get-token command, or the AWS IAM Authenticator for Kubernetes), it relies on native Kubernetes Role Based Access Control (RBAC) for authorization. IAM is used for authentication to your EKS Cluster. The permissions for interacting with your cluster’s Kubernetes API is managed through the native Kubernetes RBAC system.
Creating an IAM User
Go to your AWS Console, you will find the IAM service listed under the “Security, Identity & Compliance” group. Inside the IAM dashboard click on the Users tab and click the “Add User” button.

Create a new user and allow the user programmatic access by clicking on the Programmatic access checkbox. You do not need any particular permission for your user to access EKS. You can go ahead without selecting any permission.

After the user is created, you will have access to the users Access Key ID and Secret Access Key. You will be required to use these keys in the next step.
Configure AWS CLI
Configuring your AWS CLI with a new user is as simple as running the aws configure command and providing the AWS Access Key ID and the AWS Secret Access Key, the Default region name and Default Output format are optional though.
$ aws configure --profile eks-user
AWS Access Key ID [None]: AKIAI44QH8DHBEXAMPLE
AWS Secret Access Key [None]: je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: textOnce configured you can test to see if the user is properly configured using the aws sts get-caller-identity command:
$ aws sts get-caller-identity --profile eks-userIf the user is properly configured with the aws cli utility you should see a response like the one shown below:
{
"UserId": "AIDAX7JPBEM4A6FTJRTMB",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/eks-user"
}Creating a Role and RoleBinding for the user
With your IAM user properly configured, you can go ahead by creating a role for the user. This snippet of code creates a role named eks-user-role with a modest list permission to pods resource in your cluster.
kind: Role
metadata:
name: eks-user-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]Save the above snippet of code in a file and then apply the Role to your Kubernetes cluster:
$ kubectl apply -f role.yamlWith the role configured you need to create a corresponding RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: eks-user-role-binding
subjects:
- kind: User
name: eks-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: eks-user-role
apiGroup: rbac.authorization.k8s.ioSave the above snippet of code in a file and then apply the Role Binding to your Kubernetes cluster:
$ kubectl apply -f role-binding.yamlAdding the user to the aws-auth configmap
To grant additional AWS users or roles the ability to interact with your EKS cluster, you must add the users/roles to the aws-auth ConfigMap within Kubernetes in the kube-system namespace.
You can do this by either editing it using kubectl edit command:
$ kubectl edit configmap aws-auth -n kube-systemOr by importing the aws-auth ConfigMap and applying the changes:
$ kubectl get configmap aws-auth -n kube-system -o yaml > aws-auth.yamlAdd the user under the mapUsers as an item in the aws-auth ConfigMap:
data:
mapUsers: |
- userarn: arn:aws:iam::123456789012:user/eks-user
username: eks-user
groups:
- eks-roleIf the user is properly configured you should be able to list pods in the Cluster:
$ kubectl get pods --as eks-userThe --as flag impersonates the request to Kubernetes as the given user, you can use this flag to test permissions for any given user.
Configuring permissions for the user
The role which you defined previously had the permission of only listing pods, the eks-user cannot access any other Kubernetes resources like Deployments, ConfigMaps, Events, Secrets, logs or even shell into a given pod.
In a real-world scenario, you will need to provide permissions to a given user to access the required resources. The below snippet of code provides access to resources such as events, pods, deployments, configmaps and secrets.
rules:
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods", "pods/log", "pods/exec"]
verbs: ["list", "get", "create", "update", "delete"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["list", "get", "create", "update", "delete"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["list", "get", "create", "update", "delete"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["list", "get", "create", "update", "delete"]Add the above permissions to the role.yaml file and apply the changes, using kubectl apply -f.
Test, test and test!
Now go ahead and test to see if the permissions have been properly applied to the eks-user. You can test the same using the above mentioned --as USERNAME flag or set the eks-user as the default profile for the aws cli.
$ export AWS_PROFILE=eks-userOnce configured you can test to see if the user is properly configured using the aws sts get-caller-identity command:
$ aws sts get-caller-identityYou should see a response like the following, indicating the user is properly configured with your aws cli utility:
{
"UserId": "AIDAX7JPBEM4A6FTJRTMB",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/eks-user"
}Test the permissions of the user with the below-mentioned commands.
$ kubectl get pods
$ kubectl get secrets
$ kubectl get configmaps
$ kubectl get deployments
$ kubectl logs <pod-name>
$ kubectl exec -it <pod-name> sh
$ kubectl create configmap my-cm --from-literal=db_username=<USERNAME> --from-literal=db_host=<HOSTNAME>
$ kubectl create secret generic my-secret --from-literal=db_password=<SOME_STRONG_PASSWORD>Simply put the eks-user user should be able to perform all the actions specified in the verbs array for pods, secrets, configmaps, deployments, and events. You can read more about it here Kubernetes Authorization Overview.
Can-I or Not
You can use auth can-i to check if you have permission to a resource. To see if you have the permission to get pods simply run:
$ kubectl auth can-i get podsThe answer will be a simple yes or no. Amazing isn’t it.
Wanna check if you have cluster-admin permissions, fire this:
$ kubectl auth can-i "*" "*"Wrapup!
EKS provides the Kubernetes control plane with the backend persistence layer, the Kubernetes API server and the master nodes are provisioned and scaled across various availability zones, resulting in high availability and eliminating a single point of failure. The AWS-managed Kubernetes cluster can withstand the loss of an availability zone.
Access and authorization controls are critical for any security system. Kubernetes provides us with an awesome robust RBAC permission mechanism.
Subscribe to Faizan Bashir
Get the latest posts delivered right to your inbox