A Guide to AWS IAM Roles: Securely Delegating Permissions
An essential guide to understanding AWS IAM Roles. Learn what they are, how they work, and see practical examples for granting EC2 instances access to S3 and enabling cross-account access.
When you're working with AWS, one of the most fundamental security concepts to master is the IAM Role. While an IAM User represents a specific person or application and has long-term credentials (like a password or access keys), an IAM Role is an identity that a trusted entity can assume to get temporary security credentials.
Using IAM Roles is the standard, best-practice way to delegate permissions in AWS, and it's a concept you'll encounter everywhere.
Why Use Roles Instead of Users?
The biggest reason is to avoid using long-lived access keys. If you create an IAM user and embed its access key and secret key in your application running on an EC2 instance, you have a major security risk. If that key is ever leaked, an attacker could gain access to your AWS account.
IAM Roles solve this by providing temporary, automatically rotated credentials. There are no keys to manage or embed in your code.
The Core Components of an IAM Role
An IAM Role is defined by two key policies:
Permissions Policy: This is a standard IAM policy (like the ones you attach to users) that defines what the role is allowed to do (e.g.,
s3:GetObject
,dynamodb:PutItem
).Trust Policy: This is the most important part. The trust policy defines who is allowed to assume the role. The entity that can assume the role is called the trusted principal.
Common Use Case 1: Granting an EC2 Instance Access to S3
This is the classic example. You have an application running on an EC2 instance that needs to read files from an S3 bucket.
The Wrong Way: Create an IAM user, generate access keys, and store them in a configuration file on the EC2 instance.
The Right Way (with an IAM Role):
Create a Permissions Policy that allows read access to your S3 bucket.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-app-bucket/*" } ] }
Create an IAM Role and set its trusted principal to be the EC2 service (
ec2.amazonaws.com
). This is the trust policy:{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } }
This policy says, "I trust the AWS EC2 service to assume this role."
Attach the Permissions Policy to the role.
Launch your EC2 instance and associate it with the role you just created (this is called an "instance profile").
Now, any application running on that instance can use an AWS SDK (like Boto3 for Python or the AWS SDK for .NET). The SDK will automatically and securely retrieve temporary credentials from the EC2 metadata service. Your code doesn't need to know anything about access keys.
Common Use Case 2: Cross-Account Access
Imagine you have a Production
account and a Tooling
account. You want to allow a user in the Tooling
account to access resources in the Production
account.
In the
Production
Account: Create an IAM Role. This time, the trusted principal will be the AWS account number of theTooling
account.{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:root" }, // Tooling Account ID "Action": "sts:AssumeRole" } }
Attach a permissions policy to this role that grants the desired access in the
Production
account.In the
Tooling
Account: Grant your IAM user permissions to callsts:AssumeRole
on the ARN of the role you just created in theProduction
account.
Now, the user in the Tooling
account can switch roles in the AWS console or programmatically assume the role to get temporary credentials for the Production
account.
Other Common Trusted Principals
- Lambda (
lambda.amazonaws.com
): Every Lambda function runs with an execution role that grants it permissions to interact with other AWS services. - Federated Users (
cognito-identity.amazonaws.com
or a SAML provider): Allows users from an identity provider (like Amazon Cognito or an external IdP) to assume a role and get temporary AWS credentials.
Conclusion
IAM Roles are a fundamental building block for security on AWS. They are the mechanism that allows you to follow the principle of least privilege and avoid the use of long-lived credentials. By mastering the concepts of permissions policies and trust policies, you can build secure and scalable applications that delegate permissions in a clean and manageable way.