AWS EKS Authentication and Authorization using AWS Single SignOn

By January 10, 2020 January 13th, 2020 Blogs

Written by Priyanka Sharma, DevOps Architect, Powerupcloud Technologies

Amazon EKS uses IAM to provide authentication to the Kubernetes cluster. The “aws eks get-token” command is being used to get the token for authentication. However, IAM is only used for authentication of valid IAM entities. All permissions for interacting with the Amazon EKS cluster’s Kubernetes API is managed through the native Kubernetes RBAC system.

In this article, we are covering the authentication and authorization of AWS EKS through OnPrem ActiveDirectory i.e. in general, how we can provide EKS access to Onprem AD users. We have divided the solution into two parts: One is integrating OnPrem AD to AWS through AWS SingleSignOn and another is implementing RBAC policies on Kubernetes Cluster.

For the solution, we are using the following services:

  • OnPrem Active Directory with predefined users and groups: Ensure the below ports are allowed for your AD:
    • TCP 53/UDP 53/TCP 389/UDP 389/TCP 88/UDP 88/UDP 389
  • AD Connector on AWS which connects to the OnPrem AD
  • AWS Single SignOn: Integrates with AD Connector, allowing users to access the AWS Command Line Interface with a set of temporary AWS credentials.
  • AWS EKS: version 1.14

Integrating OnPrem AD with the AWS Single SignOn

For instance, we have created the following users and groups on OnPrem AD for the demo purpose:

AD UsernameRespective AD Group
user1EKS-Admins
user2EKS-ReadOnly
dev1EKS-Developers

Ensure to setup and AD Connector in the same region as AWS SignOn. Refer to our previous blog for setting up an Active Directory Connector.

Switch to AWS SingleSignOn Console and change the user directory. Select the AD connector created in the above step.

Select the account where you have setup the EKS Cluster.

Search for the AD group for which you want to give the EKS access.

Create a custom permission set.

Attach the below custom permission policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
          "Effect": "Allow",
          "Action": "sts:AssumeRole",
          "Resource": "*"
        }
    ]
 }

Select the Permission set created above.

Finish. Similarly, Create for Readonly and Developers too with the same permission set policy. Verify the permission sets in AWS accounts once.

Note that no specific permissions are assigned to the assumed role for the AD Users/Groups at this stage. By default the assumed role will not have permission to perform any operations. The specific authorization permissions will be defined via Kubernetes RBAC in the next section.

Behind the scenes, AWS SSO performs the following operations in Account B (member):

  • Sets up SAML federation by configuring an Identity Provider (IdP) in AWS IAM. The Identity Provider enables the AWS account to trust AWS SSO for allowing SSO access.
  • Creates an AWS IAM role and attaches the above permission set as a policy to the role. This is the role that AWS SSO assumes on behalf of the Microsoft AD user/group to access AWS resources. The role created will have prefix “AWSReservedSSO”.

Go to the account you have applied permission set to. There will be an IAM role created by SSO. In our case, below is the screenshot from the target account:

Creating RBAC Policies on Kubernetes

A Role is used to grant permissions within a single namespace. Apply the below role to create the multiple K8s role for Admins, Readonly and Dev groups respectively:

---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: default:ad-eks-admins
   namespace: default
 rules:
 - apiGroups: ["*"]
   resources: ["*"]
   verbs: ["*"]
---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: default:ad-eks-readonly
   namespace: default
 rules:
 - apiGroups: [""]
   resources: ["*"]
   verbs: ["get", "list", "watch"]
---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: default:ad-eks-developers
   namespace: default
 rules:
 - apiGroups: ["*"]
   resources: ["services","deployments", "pods", "configmaps", "pods/log"]
   verbs: ["get", "list", "watch", "update", "create", "patch"]
---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: default:ad-eks-monitoringadmins
   namespace: monitoring
 rules:
 - apiGroups: ["*"]
   resources: ["*"]
   verbs: ["*"]

Edit the existing aws-auth configmap through the below command:

kubectl edit configmap aws-auth –namespace kube-system

Add the below contents:

- rolearn: arn:aws:iam::ACCOUNTID:role/AWSReservedSSO_AD-EKS-Admins_b2abd90bad1696ac
      username: adminuser:{{SessionName}}
      groups:
        - default:ad-eks-admins
    - rolearn: arn:aws:iam::ACCOUNTID:role/AWSReservedSSO_AD-EKS-ReadOnly_2c5eb8d559b68cb5
      username: readonlyuser:{{SessionName}}
      groups:
        - default:ad-eks-readonly
    - rolearn: arn:aws:iam::ACCOUNTID:role/AWSReservedSSO_AD-EKS-Developers_ac2b0d744059fcd6
      username: devuser:{{SessionName}}
      groups:
        - default:ad-eks-developers
    - rolearn: arn:aws:iam::ACCOUNTID:role/AWSReservedSSO_AD-EKS-Monitoring-Admins_ac2b0d744059fcd6
      username: monitoringadminuser:{{SessionName}}
      groups:
        - default:ad-eks-monitoring-admins

Ensure to remove: aws-reserved/sso.amazonaws.com/ from the role_arn.

kubectl create rolebinding eks-admins-binding --role default:ad-eks-admins --group default:ad-eks-admins --namespace default

kubectl create rolebinding eks-dev-binding --role default:ad-eks-developers --group default:ad-eks-developers --namespace default

kubectl create rolebinding eks-readonly-binding --role default:ad-eks-readonly --group default:ad-eks-readonly --namespace default

kubectl create clusterrolebinding clusterrole-eks-admins-binding --clusterrole=cluster-admin  --group default:ad-eks-admins

kubectl create clusterrolebinding clusterrole-eks-readonly-binding --clusterrole=system:aggregate-to-view  --group default:ad-eks-readonly

Time for some Action

Hit SSO User Portal URL (highlighted in the below screenshot):

Give user AD credentials which is added to EKS-Admins group:

Click on Programmatic access:

It gives temporary AWS Credentials:

Create a ~/.aws/credentials file in the server with the credentials got from SSO:

[ACCOUNTID_AD-EKS-Admins]
aws_access_key_id = ASIAZMQ74VVIMRLK2RLO
aws_secret_access_key = gzOs61AcQ/vyh0/E9y+naT3GF3PDKUqB5stZLWvv
aws_session_token = AgoJb3JpZ2luX2VjENr//////////wEaCXVzLWVhc3QtMSJIMEYCIQCcs8/t5OK/UlOvSQ/NSXt+giJm9WkxVkfUhY6MFVnJwgIhAMOuJxb/CqhNx12ObPY4Obhe4KmxyEdyosqzqq63BOLaKt8CCKP//////////wEQABoMNjQ1Mzg1NzI3MzEyIgzw9o8jbVmjgcjgTHIqswICmRCh/7qIgBbxjG0kZJdmrGFEHjssv1b4Rl3AnIel7p0RizMDzzY9lQIlsuE5S7xYVB4alVVl1MNQ/1+iNSrSAG4LlCtSIaMrmUZ+hspR1qiQ5cqS2954UhgzEb081QCzYMbPgtvtPWwiiDZ9LkYOU2tp9hWbX7mHAZksFTHgEOO62hEuJWl3bh6dGYJWqyvTO3iwSJZYeqKJ/vY0MNnx5bjcqjgehUA6LnpUES3YlxelAGQPns7nbS0kOzDatoMe4erBIUTiP60vJ4JXJ2CFPsPmX6Doray0MWrkG/C9QlH4s/dZNCIm6In5C3nBWLAjpYWXQGA9ZC6e6QZRYq5EfMmgRTV6vCGJuSWRKffAZduXQJiZsvTQKEI0r7sVMGJ9fnuMRvIXVbt28daF+4ugyp+8MOCXjewFOrMB8Km775Vi0EIUiOOItQPj0354cao+V9XTNA/Pz23WTs8kF+wA5+il7mBOOEkmhLNrxEkuRTOCv0sn52tm9TeO9vSHRbH4e4xaKoJohyBYZTlEAysiu8aRQgahg4imniLYge+qvelQeDl1zYTBsea8Z71oQDcVVtBZzxmcIbS0V+AOOm81NTLRIIM1TNcu004Z7MnhGmD+MiisD0uqOmKVLTQsGLeTKur3bKImXoXNaZuF9Tg=

Update the KubeConfig for EKSAdmins groups as below:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: XXXXXX
    server: https://3B6E58DAA490F4F0DD57DAE9D9DFD099.yl4.ap-south-1.eks.amazonaws.com
  name: arn:aws:eks:ap-south-1:ACCOUNTID:cluster/puck8s
contexts:
- context:
    cluster: arn:aws:eks:ap-south-1:ACCOUNTID:cluster/puck8s
    user: arn:aws:eks:ap-south-1:ACCOUNTID:cluster/puck8s
  name: arn:aws:eks:ap-south-1:ACCOUNTID:cluster/puck8s
current-context: arn:aws:eks:ap-south-1:ACCOUNTID:cluster/puck8s
kind: Config
preferences: {}
users:
- name: arn:aws:eks:ap-south-1:ACCOUNTID:cluster/puck8s
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - --region
      - ap-south-1
      - eks
      - get-token
      - --cluster-name
      - puck8s
      - -r
      - arn:aws:iam::ACCOUNTID:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AD-EKS-Admins_b2abd90bad1696ac
      command: aws
      env:
        - name: AWS_PROFILE
          value: "ACCOUNTID_AD-EKS-Admins"

Similarly, update the KubeConfig and get the temporary credentials for ReadOnly and Dev Users.

KubeConfig for ReadOnly Users:

users:
- name: arn:aws:eks:ap-south-1:ACCOUNTID:cluster/puck8s
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - --region
      - ap-south-1
      - eks
      - get-token
      - --cluster-name
      - puck8s
      - --role
      - "arn:aws:iam::ACCOUNTID:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AD-EKS-ReadOnly_2c5eb8d559b68cb5"
      command: aws
      env:
        - name: AWS_PROFILE
          value: "ACCOUNTID_AD-EKS-ReadOnly"

AWS Profile for Temporary Credentials:

Export the KUBECONFIG for ReadOnly Users and try out the following commands:

Export the KUBECONFIG for EKS Admin Users and try out the following commands:

Export the KUBECONFIG for EKS ReadOnly Users and try out the following commands:

That’s all..!! Hope you found it useful.

References:

https://aws.amazon.com/blogs/opensource/integrating-ldap-ad-users-kubernetes-rbac-aws-iam-authenticator-project/

Leave a Reply