07.09.20

AWS EKS: Fine-Grained IAM Roles for Service Accounts (IRSA)

By Gabriel Garrido
AWS EKS - Fine-grained IAM Roles for Service Accounts (#IRSA)

AWS is renowned for its robustness and flexibility, and one of the reasons for that is the fact that it has an extensive set of APIs and automation tools. AWS APIs are not just handy for managing cloud environments, but also for integrating the services within AWS and cloud-native applications running on top of it.

In the old days, you had to set up an IAM role for your worker node with extra permissions. That is no longer the case now that IAM Roles for Service Accounts, or IRSA, is available. Rather than compromising security by giving worker nodes more permissions, you can now ask services to communicate with AWS APIs directly. This is Amazon’s way of replacing tools like kiam or kube2iam specifically for Kubernetes.

Beyond Access Management

IRSA is not limited to simple access management for services. In fact, a primary benefit of using IRSA is native integration with existing AWS resources through APIs rather than access management itself. You no longer have to jump through hoops to get services communicating directly with AWS.

For this, you need to create a specific IAM role for your Kubernetes services. This adds traceability to the mix, meaning that every API call and changes made by services can be traced back to a specific IAM role. There is no need to share IAM credentials between services either.

That brings us to the biggest advantage of them all: fine-grained control over the roles attached to service accounts. You no longer have to grant unnecessary permissions to nodes or pods, plus you can isolate the use of credentials in any way you like.

We haven’t even gotten to support for cross-account configurations. While you can easily define pod identity using the annotation:

AWS_ROLE_ARN=arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME

you can also use chained AssumeRole operations to create cross-account permissions. You just have to attach policies from another account’s cluster by using it as a source for the assigned role. That allows for more complex access management without the added complexity.

Expanding Services

IRSA supports services running in Kubernetes pods regardless of how the pods are configured. What’s more important is the SDK used inside the pod. Right now, IRSA supports certain versions of SDKs, with some of them being newer than the versions included in AWS Linux distribution package managers.

Go, for instance, needs to be in version 1.23.13 to be compatible with IRSA. Java version 2 must be in its 2.10.11 iteration or newer for IRSA to work properly. Before you plan your use of IRSA with services running in the cloud, be sure to check the required SDK version.

IRSA is also supported by several Kubernetes add-ons, including the ALB Ingress Controller and Cluster Autoscaler. Jenkins X and Terraform also support IRSA, while other add-ons such as tEKS extend support for KIAM as well.

Getting Started with IRSA

IAM Roles for Service Accounts is instantly available on clusters running the Amazon EKS Kubernetes version 1.14. Older clusters updated to version 1.13 will also receive support for IRSA. You can check if your clusters support IRSA by checking if an OpenID Connect issuer URL is attached to them.

Use the following command:

aws eks describe-cluster –name cluster_name –query “cluster.identity.oidc.issuer” –output text

to get the issuer URL. To configure IRSA, go to AWS Management Console and Create Provider from the Identity Provider section. Add the issuer URL to Provider URL and make sure the Provider Type is set to OpenID Connect. Enter sts.amazonaws.com as the Audience for that provider and you are all set.

You can start creating an IAM role and policy from the IAM console. This is where you can be very granular about how access is managed. After creating a policy, go to AWS Management Console to create a new role for your service. Use the Identity Provider we created earlier and attach a policy for that role.

One last step to complete is creating a trust relationship for the newly created role. This is where you replace sts.amazonaws.com with your service account ID. Switch the OIDC provider suffix from :aud to :sub and hit the Update Trust Policy button to complete the process.

You can now associate the role with any service in your cluster. To do that, you have to add an annotation⁠—as described earlier in this article⁠—and link the role accordingly. Use eksctl or kubectl to add the suitable annotation.

Taking It Further

The actual implementation of IRSA is actually very simple. Amazon EKS will host a public OIDC discovery endpoints that will verify the identity of your Kubernetes services. You just have to configure your services to generate the correct⁠—and valid⁠—OICD tokens and that those tokens get validated whenever API calls are made.

The rest is a matter of configuring roles and policies to maximize the benefits of using IRSA. This is where you can really take things further, but we will save discussions on this matter for another article. In the meantime, implement IRSA to take full advantage of the features it offers.


Caylent provides a critical DevOps-as-a-Service function to high growth companies looking for expert support with Kubernetes, cloud security, cloud infrastructure, and CI/CD pipelines. Our managed and consulting services are a more cost-effective option than hiring in-house, and we scale as your team and company grow. Check out some of the use cases, learn how we work with clients, and read more about our DevOps-as-a-Service offering.