Background
IAM Role chaining is a method of granting temporary access to AWS resources by assuming multiple IAM roles in a sequence.
This approach is useful when you have a scenario where one role needs to assume another role to access certain resources or perform specific actions. Typically cross-account.
In this segment, I will dive into the details of role chaining, including its need, benefits, and drawbacks.
Solution diagram
Source: Abdul R. Wahab
Why is IAM Role Chaining Needed?
Role chaining is needed in AWS to facilitate granular access control and limit the blast radius of potential security breaches.
It allows you to delegate permissions to different roles based on specific responsibilities and then chain those roles together to enable a sequence of trust relationships.
By chaining roles, you can implement the principle of least privilege and ensure that access is granted only when required, minimizing the risk of unauthorized access to critical resources.
Pros of IAM Role Chaining
Granular Access Control
Role chaining enables you to finely control access permissions by breaking down responsibilities into separate roles.
Reduced Credential Exposure
Chaining roles reduces the need to distribute long-lived access keys and instead relies on temporary / ephemeral credentials, which mitigates the risk of credential compromise.
Least Privilege Principle
With role chaining, each role can have a minimal set of permissions necessary for its specific tasks, enhancing security by limiting unnecessary access.
Flexible and Modular Design
The ability to chain roles provides a flexible design pattern to accommodate complex authorization requirements within an application or infrastructure.
Cons of IAM Role Chaining
Increased Complexity
Chaining roles can introduce complexity, especially when dealing with multiple roles and trust relationships. It requires careful planning and management to avoid confusion and misconfigurations.
Limited Chain Length
Currently AWS imposes a limit on the number of roles that can be assumed in a chain, typically a maximum of 10. Exceeding this limit requires reconfiguring the roles or adopting alternative solutions.
Potential Latency
Each role assumption adds a small delay, resulting in a minor performance impact when chaining multiple roles.
Code Examples 👨💻
Let’s consider an example scenario where a web application running on an EC2 instance in Account ABC
needs to access some files in Account XYZ’s
S3 bucket. The EC2 instance assumes Role ABC
, which, in turn, assumes Role XYZ
to gain access to the S3 bucket contents.
1) Creating Role ABC
import boto3
iam_client = boto3.client('iam')
response = iam_client.create_role(
RoleName='RoleABC',
AssumeRolePolicyDocument='''{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
}'''
)
# Attach policies to RoleABC
response = iam_client.attach_role_policy(
RoleName='RoleABC',
PolicyArn='arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess'
)
2) Creating Role XYZ
response = iam_client.create_role(
RoleName='RoleXYZ',
AssumeRolePolicyDocument='''{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_ID:role/RoleABC"
},
"Action": "sts:AssumeRole"
}]
}'''
)
# Attach policies to RoleXYZ
response = iam_client.attach_role_policy(
RoleName='RoleXYZ',
PolicyArn='arn:aws:iam::aws
3) Creating an IAM Instance Profile for Role ABC
response = iam_client.create_instance_profile(
InstanceProfileName='InstanceProfileABC'
)
response = iam_client.add_role_to_instance_profile(
InstanceProfileName='InstanceProfileABC',
RoleName='RoleABC'
)
4) Creating an IAM Policy for Role XYZ
response = iam_client.create_policy(
PolicyName='PolicyXYZ',
PolicyDocument='''{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::web-application-bucket/*"
}]
}'''
)
policy_arn = response['Policy']['Arn']
response = iam_client.attach_role_policy(
RoleName='RoleXYZ',
PolicyArn=policy_arn
)
5) Creating an IAM Role for EC2 Instances with Role ABC
response = iam_client.create_instance_profile(
InstanceProfileName='InstanceProfileEC2'
)
response = iam_client.add_role_to_instance_profile(
InstanceProfileName='InstanceProfileEC2',
RoleName='RoleABC'
)
Implementation summary
With the above code, we have created RoleABC
and RoleXYZ
, established trust relationships between them, attached policies to each role, and created instance profiles for EC2 instances with RoleABC
.
Now, when an EC2 instance is launched with InstanceProfileEC2
, it can assume RoleABC
, which then chains to RoleXYZ
, granting access to the specified S3 bucket.
Please note that this example provides a simplified illustration of role chaining. In a real-world / enterprise scenario, you would need to consider additional factors such as proper error handling, resource-specific policies, and the appropriate trust relationships.
Closing thoughts 👏
Role chaining in AWS offers a powerful mechanism to enforce secure access controls and limit the scope of permissions.
However, it requires careful configuration and management to ensure effective authorization while minimizing complexity and potential pitfalls.
Thanks for following along. Feel free to comment below with questions / inputs.
Related reading