If you’ve been working with AWS for any amount of time, you’ve probably heard about IAM (Identity and Access Management)—and you’ve probably found it a little confusing at first. Trust me, even after two years working at AWS, I still find myself second-guessing some of its more complex features, especially IAM Roles.
But here’s the thing: mastering IAM is one of the most important steps you can take to secure and manage your AWS environment effectively. Whether you’re a newcomer to cloud development or a seasoned pro, understanding how to control access using IAM Users, Roles, Policies, and Trust Relationships is essential for both security and scalability.
In this guide, I’ll break down these IAM components step by step, so you can confidently manage who has access to your AWS resources, what they can do, and how to avoid common mistakes.
IAM Users: Long-Term Access for People
IAM Users are individual identities (representing people or services) with long-term credentials—either a username and password for console access or access keys for programmatic access. These credentials allow users to interact with AWS resources continuously.
The Root User and Why You Should Avoid Using It
When you create an AWS account, a root user is automatically created. This user has unrestricted access to all AWS resources and services. While the root user is necessary for certain critical actions, it’s not recommended to use it for day-to-day tasks because of its full access permissions.
- Why avoid it? If your entire team shares the root account, it becomes impossible to track who is performing actions, and you risk someone accidentally (or intentionally) causing major issues, such as deleting resources.
When to Use IAM Users
Instead of using the root user, create IAM Users for individuals who need regular access to your AWS environment, such as developers, QA testers, or administrators. Each user should have their own credentials, making it easy to manage permissions and track actions.
- Default Permissions: By default, newly created IAM Users have no access to any resources. AWS operates on the principle of least privilege, meaning you’ll need to explicitly assign permissions to allow users to perform specific tasks.
While IAM Users are great for individuals, they’re not recommended for services or applications. The reason? IAM Users rely on long-term credentials, which can be more easily compromised if stored improperly or used over time.
- Long-Term Credential Risk: Storing long-term credentials, like access keys, is risky because they can be exposed or exploited by bad actors.
For services, AWS provides IAM Roles, which offer a more secure, temporary way to manage access. We’ll dive into IAM Roles next!
IAM Roles: Temporary Permissions for Services and Users
IAM Roles provide temporary credentials that are assumed by AWS services or external users to access AWS resources. An IAM Role is essentially a set of permissions that can be temporarily assumed by any user, service, or application. Unlike users, roles do not have permanent credentials (like passwords or access keys). Instead, roles are assumed when needed, and they automatically provide temporary credentials that expire after a set time.
How are IAM Roles Different from IAM Users?
IAM Roles are not tied to a single person or entity. Instead, they can be assumed by any trusted entity—whether it’s an EC2 instance, an external user from another AWS account, or even a third-party identity provider like GitHub or Google. Users, on the other hand, are unique to one individual and have long-term credentials.
When to Use IAM Roles:
- AWS Services: Roles allow services like EC2, Lambda, or ECS to access other AWS resources without storing long-term credentials.
- Cross-Account Access: When you need to grant temporary access to resources in another AWS account.
- Federated Access: Allowing external users (e.g., from GitHub or Google) to access AWS without creating dedicated IAM Users.
IAM Policies: Controlling Access in AWS
Policies are what actually controls who can do what in AWS. They define which actions a user, group, or role can perform on which resources. Policies are JSON documents that specify actions, resources, and optional conditions.
Types of Policies:
-
AWS Managed Policies: Pre-built and maintained by AWS. These cover common use cases (e.g.,
AdministratorAccess or AmazonS3ReadOnlyAccess). - Example: Use a managed policy like
AmazonS3ReadOnlyAccess for all team members who only need to view objects in S3 buckets.
-
Customer Managed Policies: Policies that you create for specific needs, providing more granular control.
- Example: You create a customer-managed policy that gives developers permission to launch EC2 instances but restricts them from modifying security groups.
-
Inline Policies: Policies directly attached to a specific user, group, or role, used for more specific one-off permissions.
- Example: Attach an inline policy directly to a role that allows a third-party contractor to perform a specific task, like uploading files to a particular S3 bucket, during the contract period.
If a change happens inside a managed policy, whether AWS- or Customer-managed, the changes will be automatically applied to all the entities the policy is attached to.
Example Policy:
Below is an example of a policy that allows a user to upload objects to an S3 bucket but restricts actions to a specific IP range:
```
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: “s3:PutObject”,
“Resource”: “arn:aws:s3:::example-bucket/*”,
“Condition”: {
“IpAddress”: {
“aws:SourceIp”: “192.0.2.0/24”
}
}
}
]
}
```
Explanation:
- Effect: This policy allows (
Allow) the action defined (Can only be Allow or Deny)
-
Action: Defines what action can be taken by the entity that has this policy attached to it. It typically follows the scheme of
serviceAbbreviation:action. - The specific action permitted in the example is
s3:PutObject, meaning the user can upload objects to the bucket.
-
Resource: The AWS resource the action can be performed upon.
- In this case, the action applies only to the
example-bucket S3 bucket.
-
Condition: Specifies additional restrictions. See the list of supported condition operators here.
- In this example, the action is restricted to requests originating from the IP address
192.0.2.0/24.
Even after defining a role and attaching the permissions to it, we’re not done yet. We also need to specify who is allowed to assume the role and perform the actions defined in the policy.
Trust Relationships: Who Can Assume a Role?
Trust Relationships are essential for IAM Roles. They define who or what is allowed to assume a role and use the permissions granted by that role. Without a trust relationship, no entity can assume a role, even if policies are in place.
How Trust Relationships Work:
- Principals: The entity that can assume the role. This could be an AWS service (like EC2), an IAM user, an external AWS account, or even a user from an external identity provider, such as Google.
-
Actions: The action
sts:AssumeRole allows the trusted entity to assume the role and temporarily use its permissions. sts stands for ‘Security Token Service’. Its sole purpose is to enable entities to assume a role.
Example Trust Relationship:
Here’s a trust relationship that allows EC2 instances to assume a role:
```
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Principal”: {
“Service”: “ec2.amazonaws.com”
},
“Action”: “sts:AssumeRole”
}
]
}
```
Explanation:
- Principal: The principal here is
ec2.amazonaws.com, allowing EC2 instances to assume the role.
- Action: The action
sts:AssumeRole allows the EC2 instance to temporarily use the role’s permissions.
I hope this newsletter helped clear up any confusion about AWS IAM and gave you the confidence to manage access more effectively. Remember, mastering IAM is a crucial step in securing your AWS environment.
If you have any questions or need further guidance on setting up IAM roles, policies, or anything AWS-related, feel free to reach out—I’m always happy to help!
And if you’re looking for more in-depth, hands-on examples, don’t forget to subscribe to my YouTube channel. I’ll be posting a detailed video on IAM in the next couple of weeks, so stay tuned!
Cheers!
Evgeny Urubkov (@codevev)