Understanding Role Based Access Control (RBAC) with Amazon EKS – Part 2

This is the latest installment of a multi-part series covering RBAC with Amazon EKS, Joe Keegan, BlueChipTek Lead Cloud Services explains how AWS IAM integrates with Kubernetes. In part 1, he covered Kubernetes roles and how to assign those role to IAM principals. That part covers how IAM integrated with Kubernetes for authorization. In this part he’ll cover how IAM integrates with kubectl for authentication of IAM principals. The final part will show how to put it all together to allow multiple teams to coexist on the same cluster without risk of them interfering with each other

aws-iam-authenticator

The aws-iam-authentication utility is used to integrate Kubernetes authentication with IAM and is needed to interact with an EKS cluster. Anytime you use kubectl to perform an action on the EKS cluster the aws-iam-authenticator is used to generate an STS token. That STS token is used to authenticate the client when making API calls.

The aws-iam-authenticator also runs as server mode on the EKS API Server. When the EKS API Server receives the API call it uses the aws-iam-authentication to verify that the token is valid and the IAM principal that created the token. This process is depicted below.

STS-diagram.png#asset:3357


Once the EKS API Server knows the IAM principal who sent the API call it can then use the mappings defined in the aws-auth ConfigMap to see which Kubernetes groups the principal is part of. This is discussed in part 1 of this series.

You can generate tokens with the aws-iam-authentication tool by running it from the command line. You can see that each time you run it generates a new token. The ‘-i eks-cluster’ tells the aws-iam-authentication tool that the cluster id is “eks-cluster”.

$ aws-iam-authenticator token -i eks-cluster
{"kind":"ExecCredential","apiVersion":
"client.authentication.k8s.io/v1alpha1",
"spec":{},"status":{"token":"k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1
hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcn
Npb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFD
LVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFTSUE1REFPVzdFM0lSS
kJDU0NKJTJGMjAxODA5MjclMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M
0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDE4MDkyN1QxOTM1NTRaJl
gtQW16LUV4cGlyZXM9NjAmWC1BbXotU2VjdXJpdHktVG9rZW49RlF
vR1pYSXZZWGR6RUgwYUREaUZ2R3VSeGglMkZUdDN4UVlDTDNBVHI
4R01TbCUyRlZLN2ozbE1sJTJCZ3EyTk5tcjRzUnprakRTdiUyRmFweTlUcl
B6ODRmbENrMERLVHZ1a1ZoMko3WkNJNk1LWDkydW0zQ2p1OUhGcU
p3VFRSTTdXJTJGak1OUENLWjJDWTd3ejFtdWFjaERNJTJGREVnZmlad
FdxYzA3Vjc0JTJCRGhFJTJCN0kyTVMxVmprQ3NEWEtxWWM5S3JkajFP
bTRFc2o1S3lYRVk4ZHpzRG03S2FNcGh4ZUdKaU94VGYxR0M2WTklM
kZLMWZubkElMkIySG51UnJBT3I0M0w3SjNHb3hYaHU1NEVtcEM2T2dm
ZUVKRjQlMkJjSjVXbnFVdnZ4cSUyQjBLTUc5MlJYNGN3NU1RRVFTV2l6
SElpc3pHTTF2RUtYaTRmM2VxVjlheTBtT250cnQ1V3V4S3dmSkMwT0Z
WRmcxeDBkQXBXekYxaFVwU3h1MG9tdUswM1FVJTNEJlgtQW16LVN
pZ25lZEhlYWRlcnM9aG9zdCUzQngtazhzLWF3cy1pZCZYLUFtei1TaWdu
YXR1cmU9YjE4NWZhMjdhMDg1NmE4MzZkOTk3MWJkZWVkMzgxNTF
jODk0YTdjNTM0NWVmODcyMDU0YmUwZTYzMzM3YzM0Ng"}}
$ aws-iam-authenticator token -i eks-cluster
{"kind":"ExecCredential","apiVersion":
"client.authentication.k8s.io/v1alpha1",
"spec":{},"status":{"token":"k8s-aws-v1.aHR0cHM6Ly9zdHMuY
W1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5
JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC
1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFTSUE1REFPVz
dFM0pXVEg1R1dKJTJGMjAxODA5MjclMkZ1cy1lYXN0LTElMkZzdHM
lMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDE4MDkyN1QxOT
M1NTZaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2VjdXJpdHktVG
9rZW49RlFvR1pYSXZZWGR6RUgwYURKTVNaaGl2eW4lMkJFa1NM
dDl5TDNBVEN3M0kxWWxmYXBEVzFJVCUyQjdpTFhZUk1sS0JRa
FJwOHF5MHl3OFdYTDJzanZOQlBrMWZReVloWEpmTTV0anVFdm
E4YXQ0V3RjTUhSNUFWaU04aWlmZHolMkYlMkZiMHEzOGdaOHIw
VVdZdVF6eW5LWWE4VllzVWdBQWxUdHJVRFJVcEx6TCUyRkFDc
Fd1VUVxRVRDTXg5eEZoV3ByaUNPdjJteFklMkYxcmNERVJRcnRaeE
E4T0RmMDh3SjBESXJZcjVsaWo1Q0dDbzcwdVhLQ3g2YzZHZUQy
QkhyVTkwamMzQ2tGaERyQjVVYklEY2w3JTJGM1VDWFdPTXdIb
1Rzbk9qUGdWTlVCcWVsJTJCb3VrelRRS2kybEZMTkp0R1dHZEtP
cDQ3dXU0QVJyYVRIVk9jeEdzTGU1VWJFdjFpTXcwelVhbDYyN
mZlTzFNWG5sTVBWekFvbmVLMDNRVSUzRCZYLUFtei1TaWd
uZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbX
otU2lnbmF0dXJlPTVhMTAyMDcxYzBlZmRmOTUxMTQ5ZDEwZT
dmN2ZhZGZlMjg4MTc4ZGFmZjA1Mjc2ODliYjU0YzhhYzI1NTVmZDU"}}

By default, the IAM principal used to generate the STS token is based on the AWS credentials profile you have configured, in the same manner as when you are using the AWS CLI. This will either be the default profile, or the profile set in the AWS_DEFAULT_PROFILE environment variable.

Alternatively, you can specify an ARN of the role you wish to assume to generate the STS token. This is done with a ‘-r’ argument like so.

$ aws-iam-authenticator token -i eks-cluster -r 
arn:aws:iam::123456789012:role/eks-team1-admins 

kubectl integration

When setting up your EKS cluster you likely generate use ‘aws eks update-kubeconfig` command to generate the kubeconfig needed to connect to your cluster. The section relevant to the aws-iam-authenticator is the users section of the config. By default, it looks something like:

users:
- name: arn:aws:eks:us-west-2:123456789012:cluster/eks-cluster
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - token
      - -i
      - eks-cluster
      command: aws-iam-authenticator

This tells kubectl that when the context is set to use the user “arn:aws:eks:us-west-2:123456789012:cluster/eks-cluster” then the following command to generate the STS token “aws-iam-authenticator token -i eks-cluster” is run prior to sending the API call to the EKS cluster.

I find using kubectl with an EKS cluster to be a bit more sluggish than with a vanilla Kubernetes cluster and it’s because there is a call to STS for each call kubectl command. You can create other users in your kubeconfig file and utilize the “-r” argument to specify different IAM roles to use, which in turn will map to different Kubernetes groups. The following kubeconfig defines 3 users and 3 contexts for our EKS cluster. One user and context for the cluster-admin using the IAM role used to setup the cluster. The other two users and contexts are for specific teams that are given admin to their respective namespaces.

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <SNIP>
    server: https://address.sk1.us-west-2.eks.amazonaws.com
  name: arn:aws:eks:us-west-2:123456789012:cluster/eks-cluster
contexts:
- name: cluster-admins
  context:
    cluster: arn:aws:eks:us-west-2:123456789012:cluster/eks-cluster
    user: arn:aws:eks:us-west-2:123456789012:cluster/eks-cluster
- name: team1-admins
  context:
    cluster: arn:aws:eks:us-west-2:123456789012:cluster/eks-cluster
    user: team1-admins
    namespace: team1
- name: team2-admins
  context:
    cluster: arn:aws:eks:us-west-2:123456789012:cluster/eks-cluster
    user: team2-admins
    namespace: team2
current-context: cluster-admins
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-west-2:123456789012:cluster/eks-cluster
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - token
      - -i
      - eks-cluster
      - -r
      - arn:aws:iam::123456789012:role/eks-cluster-admins
      command: aws-iam-authenticator
- name: team1-admins
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - token
      - -i
      - eks-cluster
      - -r
      - arn:aws:iam::123456789012:role/eks-team1-admins
      command: aws-iam-authenticator
- name: team2-admins
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - token
      - -i
      - eks-cluster
      - -r
      - arn:aws:iam::123456789012:role/eks-team2-admins
      command: aws-iam-authenticator

The next installment of the series shows the full implementation of the two teams and how to grant them access to their respective namespaces.

If you find that you’d like to help talking these kinds of problems with EKS then checkout out Jumpstart for Container Orchestration. We can come on site and show you how to get EKS up and running securely and ready for production.