Containers
Session policies for Amazon EKS Pod Identity
Today, we’re announcing the new session policies capability for Amazon Elastic Kubernetes Service (Amazon EKS) Pod Identity. With this new feature, you can dynamically scope down AWS Identity and Access Management (IAM) permissions for your Kubernetes pods without creating additional IAM roles. Session policies give you a flexible alternative to creating separate IAM roles for each permission variation by specifying an inline IAM policy during Pod Identity association creation. This helps you to manage permissions at scale without multiplying your role count. This means that your Kubernetes applications can now operate with precisely the permissions required, following the principle of least privilege, while avoiding reaching IAM role limits in large-scale deployments.
In this post, we demonstrate how to use session policies to dynamically scope down IAM permissions for your Kubernetes pods without creating additional IAM roles, and discuss important considerations when adopting this feature. At re:Invent 2023, Amazon EKS introduced the EKS Pod Identity feature. This feature helps users to configure Kubernetes applications running on Amazon EKS with fine-grained IAM permissions to access AWS resources such as Amazon Simple Storage Service (Amazon S3) buckets and Amazon DynamoDB tables. This feature addressed many of the existing challenges of IAM Roles for Service Accounts (IRSA) by removing the need to set up OpenID Connect (OIDC) providers for EKS clusters, streamlining IAM trust policies, and streamlining the experience through Amazon EKS APIs. Furthermore, it introduced support for IAM role session tags, so IAM administrators can author a single permissions policy that can work across roles by allowing access to AWS resources based on matching tags.
Through nearly continuous user feedback, we learned that customers often face challenges when they need different permission levels for pods running the same application. Common scenarios include the following:
- Platform Engineering teams managing multi-tenant EKS clusters where different customer workloads need varying levels of access to the same AWS services. For example, a software as a service (SaaS) application where each pod operates against the tenant specific resources and data and must assume only that tenant’s specific roles.
- Teams running multiple environments (dev, test, staging) in the same cluster where pods need different permission scopes based on their environment without creating separate IAM roles for each.
- Data processing workloads where pods need access to different subsets of S3 buckets or DynamoDB tables based on their specific function, but creating individual IAM roles for each variation would exceed the 5,000 IAM roles per account quota.
Previously, you had to choose between creating separate IAM roles (hitting quota limits), granting overly broad permissions (security risk), or using session tags (not supported by all AWS services) to handle these scenarios. To address these challenges and support fine-grained permission control, we’re launching session policies for EKS Pod Identity. You can use session policies to apply inline IAM policies when EKS Pod Identity assumes an IAM role on behalf of your pods. These policies create an intersection between the permissions granted by the IAM role and the session policy. This effectively restricts permissions to only what’s explicitly allowed in both policies. This feature works for both same-account scenarios and cross-account access patterns using IAM role chaining. For in-depth policy evaluation logic, refer to IAM Policy evaluation for single account and cross-account scenarios.
What is changing in EKS Pod Identity APIs
The following APIs are updated to introduce new request and response elements to pass session policies:
CreatePodIdentityAssociation: API call to create an EKS Pod Identity association between a service account in an EKS cluster and an IAM role with EKS Pod Identity.
Request parameters:
- clusterName: The name of the cluster in which to create the association.
- namespace: The name of the Kubernetes namespace inside the cluster in which to create the association.
- serviceAccount: The name of the Kubernetes service account inside the cluster with which to associate the IAM credentials.
- roleArn: The Amazon Resource Name (ARN) of the IAM role to associate with the service account.
- targetRoleArn: The ARN of a target IAM role in another AWS account. When specified, EKS Pod Identity performs IAM role chaining: it first assumes the
roleArn, then uses those credentials to assume thetargetRoleArn. When you specify a session policy, EKS Pod Identity applies it when assuming the target role, not the source role. - policy (new): An IAM policy in JSON format that you want to use as an inline session policy. This parameter is optional. The resulting session’s permissions are the intersection of the role’s identity-based policy and the session policy. The plaintext policy can’t exceed 2,048 characters.
- disableSessionTags: Defaults to false (session tags enabled) when not specified. Session tags cannot be used in combination with session policies due to AWS Security Token Service (AWS STS) policy size quota.
UpdatePodIdentityAssociation: API to update an existing pod identity association. Use this to update the IAM role, target IAM role, session policy, or disableSessionTags attributes of the association.
Request parameters:
- clusterName: The name of the cluster where the association exists
- associationId: The ID of the association to be updated
- roleArn: The new IAM role to associate with the service account (optional)
- targetRoleArn: The new target IAM role to associate with the service account
- policy (new): The new session policy to associate with the service account (optional)
- disableSessionTags: Boolean flag to enable or disable session tags (optional, but must be
truewhen the policy is specified)
How to get started
We demonstrate how to use session policies to restrict a Kubernetes pod’s permissions to only list S3 buckets, even though the underlying IAM role has broader S3 permissions including the ability to create buckets.
Prerequisites
The following prerequisites are necessary to complete this solution:
- An AWS account
- The latest version of AWS Command Line Interface (AWS CLI) configured on your device or AWS CloudShell
- CLI for Amazon EKS (eksctl) for creating and managing EKS clusters
- kubectl, a CLI tool to interact with the Kubernetes API server
Setup
Step 1: Create an EKS cluster with Pod Identity add-on
Let’s start by creating an Amazon EKS Cluster using eksctl with the new eks-pod-identity-agent add-on.
It takes approximately 15 minutes to get the cluster infrastructure created, you can verify the status using the following command or Amazon EKS console.
aws eks describe-cluster --name ${CLUSTER_NAME} --region ${AWS_REGION} --query 'cluster.status'
The output of this command should be ACTIVE.
After the cluster creation is completed, confirm that the eks-pod-identity-agent add-on is running in the cluster.
Step 2: Create an IAM role with broad S3 permissions
Create an IAM role with permissions to perform multiple S3 operations, including listing and creating buckets.
Step 3: Create a Pod Identity association without a session policy
Create a Kubernetes namespace and service account, then associate them with the IAM role.
Step 4: Test the pod with full IAM role permissions
Deploy a test pod and verify it can perform multiple S3 operations.
Both commands should succeed, demonstrating that the pod has full permissions granted by the IAM role.
Step 5: Add a session policy to restrict permissions
Now, update the Pod Identity association to include a session policy that only allows listing S3 buckets.
Important: The --disable-session-tags flag is required when using session policies. Session tags and session policies cannot be used together due to packed policy size limitations enforced by AWS STS. If you attempt to create or update a pod identity association with both a policy and session tags enabled (or omit the --disable-session-tags flag), you will receive a PackedPolicyTooLarge validation error during the API call.
Step 6: Verify the restricted permissions
Due to the eventual consistency nature of the EKS Pod Identity API, it can take a few seconds to propagate the update. Run the following commands to test the scenario again.
Security Note: During the propagation window (up to 10 seconds), pods continue to receive credentials with previous permissions. Plan permission changes accordingly and monitor AWS CloudTrail for any unauthorized access attempts during the transition window.
The first command succeeds because s3:ListAllMyBuckets is allowed by both the IAM role and the session policy. The second command fails with an “Access Denied” error because s3:CreateBucket is not included in the session policy, even though the IAM role permits it.
Step 7: Expand the session policy
You can update the session policy at any time to grant additional permissions (up to what the IAM role allows).
After waiting for the credential cache to expire, the pod will now be able to both list and create S3 buckets. AWS CloudTrail records all events, so you can audit and monitor all IAM role activity, including the session policies, for security and compliance purposes.
Understanding session policy validation
EKS Pod Identity validates session policies when you create or update a pod identity association, providing immediate feedback if there are any issues. The validation process includes:
- JSON format validation: EKS Pod Identity validates that the policy is valid JSON
- Character validation: EKS Pod Identity verifies that your policy contains only valid characters
- Size validation: EKS Pod Identity confirms that the policy doesn’t exceed 2,048 characters
- IAM policy schema validation: EKS Pod Identity validates against IAM policy structure requirements by performing a dry-run call to AWS STS
- Packed policy size validation: EKS Pod Identity makes sure that the session policy doesn’t exceed STS limits after compression
Important considerations
This section outlines key constraints and requirements before adopting session policies with EKS Pod Identity. It covers their interaction with session tags, permission evaluation rules, and how policies are applied in same and cross-account scenarios.
Session tags and session policies
Session tags can’t be used with session policies. When you specify a session policy, you must set --disable-session-tags to true. This is a requirement, not an optional optimization.
Permission intersection
Session policies can only restrict permissions, not expand them. The effective permissions are always the intersection of:
- The IAM role’s identity-based policies
- The session policy (if provided)
This ensures that session policies maintain security boundaries and cannot be used to escalate privileges beyond what the IAM role allows.
Session policy application
Session policies are applied differently depending on whether you’re using a target role. A target role enables cross-account access scenarios where your pods must assume an IAM role in a different AWS account. When you specify a target role, EKS Pod Identity performs the IAM role chaining: it first assumes the source role (roleArn) in your account, then uses those credentials to assume the target role (targetRoleArn) in another account.
When targetRoleArn is specified (cross-account scenarios):
- The session policy is applied when assuming the target role, not the initial source role
- The source role (
roleArn) needs permission to assume the target role usingsts:AssumeRoleandsts:TagSessionactions - The session policy restricts the permissions of the target role through IAM role chaining
When targetRoleArn is not specified (same-account scenarios):
- EKS Pod Identity applies the session policy directly to the roleArn when it assumes the role
- The effective permissions are the intersection of the role’s identity-based policies and the session policy
Other considerations
Following are additional considerations on service and AWS Region availability, Kubernetes version, and infrastructure as code (IaC) requirements.
- Kubernetes version support: The EKS Pod Identity session policy feature is supported on Kubernetes versions supported in Amazon EKS.
- Region availability: Session policies are available in AWS Commercial, Mainland China, and AWS GovCloud (US) Regions where Amazon EKS is supported.
- Role association limits: You can associate only one IAM role to a Kubernetes service account using EKS Pod Identity. However, you can update the role, target role, and session policy later.
- Tooling support: You can use AWS CloudFormation, eksctl, AWS CLI, and Amazon EKS API to create pod identity associations with session policies.
Cleaning up
Important: Complete these cleanup steps to avoid ongoing charges for the resources created in this walkthrough:
Conclusion
In this post, we demonstrated the new session policy capability of Amazon EKS Pod Identity, which enables fine-grained permission control for Kubernetes workloads without the overhead of managing thousands of IAM roles. With dynamic permission scoping at the Pod Identity level, this feature helps you build more secure, scalable, and maintainable applications on Amazon EKS while following least privilege. We encourage you to start using this feature and share your feedback at AWS Containers Roadmap.
Additional resources
- Amazon EKS Pod Identity Documentation
- IAM session policies
- AWS Security Best Practices for EKS
- EKS Pod Identity: A new way for applications on EKS to obtain IAM credentials
About the authors
Aditya Potdar is a Software Engineer on the Amazon EKS team at Amazon Web Services. With experience spanning multiple leading technology companies, he specializes in architecting and delivering container-based infrastructure that powers large-scale production systems and machine learning workloads.
Ashok Srirama is a Principal Solutions Architect at Amazon Web Services, based in Washington Crossing, PA. He specializes in serverless applications, containers, and architecting distributed systems. When he’s not spending time with his family, he enjoys watching cricket, and driving his bimmer.
George John is a Senior Product Manager for Amazon Elastic Kubernetes Service (EKS) at AWS, where he drives product strategy and innovation for one of the industry’s leading managed Kubernetes platforms. In his role, George works closely with customers, partners, and the broader cloud-native community to shape the future of container orchestration on AWS. When he is not building products, he loves to explore the Pacific Northwest with his family.