IAM Introduction
Everything in AWS is private by default. That means that if we setup an S3 bucket and put files in it, no one is able to access that bucket or those files, unless they are granted permission.
This also means that services can't access other services in AWS. If we setup an EC2 instance in the same account, it would not be able to access the files in that S3 bucket without being granted permission.
This is the principle of least privilege, and it means that we have to very explicitly grant permission for users or services to be able to access other services.
What is IAM?
IAM stands for Identity and Access Management, it's AWS's security service that allows us to control how different services can be accessed and what or who can access them.
There are four key IAM components that we need to know about: policies, roles, users, and groups. For the most part, we'll just be working with policies and roles, but let's take a look at all four.
Let's say we have an S3 bucket that we're using for file storage, kind of like dropbox. By default, nothing will be able to access the S3 bucket, so how do we change that?
Policies
Policies are JSON documents that define the permissions for a service. So if we want to allow something or someone to get files and add new files to our S3 bucket, we could write an IAM policy that looks like this.
This policy allows GetObject
and PutObject
on any object(*
) in the S3 bucket named your-bucket-name
.
Remember the principle of least privilege - only grant the minimum permissions needed to get the job done.
Even though policies are JSON, you don't have to write them by hand every time you make one. There's tools in AWS that do it for you, or just get your favourite LLM to do it for you.
And remember, policies are literally just JSON documents, nothing more. Creating a policy does nothing more than just creating a JSON document. We can't just give the policy to a service like EC2, we instead have to use a Role or a User
Roles
An IAM role is something we can actually assign to a service. So we could create a role and assign it to a service like an EC2 instance. The role would then act as that EC2 instances identity when it tries to access other services.
It's as if the EC2 instance is "logged in" to the AWS account, but instead of it having to use a username and password, it uses temporary security credentials managed by IAM. Assigning a role to an EC2 instance gives that EC2 instance an identity in AWS.
But roles don't have any default permissions, the EC2 instance can't do anything until we associate one or more policies with the role.
So if we create a new role, assign that role to our ec2 instance, and associate the policy from before with that role, the EC2 instance will now be able to GetObject
and PutObject
on the S3 bucket. This is the secure way to give EC2 instances AWS access.
Users
If a role can be used to give an identity to a service within AWS, a user can be used to give an identity to anything outside AWS.
As the name implies, we can use an IAM user to allow a real person to login to our AWS account with a username and password and access certain services. If we associated our current policy with a user, they would be able to GetObject
and PutObject
on the S3 bucket.
But this isn't the best way of allowing someone to access services in our accounts. For that we used IAM Identity Center which is a different service and I'll mention it again at the end.
Another use case for IAM users is to allow services outside of AWS to access our accounts. We can create an IAM user that uses access keys instead of a username and password which would allow an application to "log in" to our account and access things.
It's not uncommon for a web app hosted outside of AWS to use an IAM user to access an S3 bucket in this exact way. But there are some security pitfalls to this if the tokens ever get leaked.
Groups
Groups are collections of users that make it easier to manage permissions for multiple people.
Instead of attaching our S3 policy to 5 different developers individually, we could create a "Developers" group, attach the policy to the group, and then add all 5 developers to that group.
Groups are only for organizing users though - you can't add roles to groups or assign groups to EC2 instances. And since IAM Identity Center (the better way to give people access) has its own group system, IAM groups are used less frequently now.
IAM vs IAM Identity Center
IAM Identity Center is what we used to setup our user in the first part of the course. This service manages our permissions and how we login to the web console. We're using IAM Identity Center every time we login to the web dashboard or authenticate with the AWS CLI.
Basically, IAM Identity Center is a service we use to allow real people to login to our AWS account and manage exactly what that user has access to.
IAM on the other hand is what we use to handle access and permissions for everything else (like giving a Lambda function permission to write to CloudWatch, or an EC2 instance access to S3).
However, we can also use IAM to manage users in the same way as IAM Identity Center, but it's much better to use IAM Identity Center for that because it's newer, more secure, and designed specifically for this task.
IAM is Global and Free
One last thing, IAM is a global service and it's free. That means we create a roles and policies globally and assign roles to services in any region without having to re create these things in every region we deploy infrastructure to.
IAM is also free, so we can create as many policies, roles, and users as we like. No extra charge.