IAM stands for Identity and Access Management. It is the service that lets you manage authentication and authorization within your AWS account.
Authentication and Authorisation in AWS are based on six building blocks1: Account, User, Group, Policy, Action and Role.
Everything I write here, and much more, can be found in the AWS documentation. This post is nothing more than a quick introduction to get you started with the basics.
Account
Account is the AWS equivalent of a Github Organization. In AWS, you can “log in as an organization”: it’s called “root account” or “account root user”, and you should only use it for the initial setup.
User
A User identifies a person wihin an Account. You can create as many Users as you like. Every person accessing your AWS account should have their own User.
You can attach zero or more Policies to a User, but you probably want to assign policies to a Group instead, and then assign the User to that Group.
Group
A Group is a collection of Users. You can assign zero or more Users to any Group. You can assign any User to zero or more Groups.
You can attach zero or more Policies to a Group.
Policy & Action
A Policy is a JSON document allowing or denying one or more Actions.
There are hundreds of Managed Policies written and maintained by Amazon that you can just pick and use. Or you can freely compose yours.
Here is the Managed Policy named AmazonS3ReadOnlyAccess:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "*"
}
]
}
Version is the version of the Policy schema. It is not the version of the policy; changing the date will make your policy invalid.
Actions are an enumeration of everything you can do in AWS: including spinning a new EC2 machine, reading from a database, adding a machine to a virtual network, changing your password… or creating a Policy.
Resource is the target of the policy. The actions in the example above refer to S3, so the wilcard star *
lets the actions apply to any S3 bucket in the Account.
Example: you need a policy for allowing read-only access to one specific bucket named my_bucket
. You can create a new policy like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "arn:aws:s3:::my_bucket"
}
]
}
Role
A Role is an identity with optionally embedded Policies. You can attach zero or more Policies to a Role.
You can’t authenticate against AWS “as a Role”: a Role does not have credentials nor AccessKeys. Instead, a Role can be assumed by many actors:
- Users
- Groups
- machines (like an EC2 instance) or other AWS Resources
- Users from other Accounts
- Roles
To “assume” a Role means to impersonate it. As a User, while assuming a Role, you temporarily assume the Policies of the Role instead of your own.
You define who can assume a Role by attaching Trust Policies to it. A Trust Policy is a JSON document that defines who is allowed to assume a Role.
This Trust Policy allows all the users in the Account 123456789012
to assume (that is: impersonate) it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole"
}
]
}
Note that after attaching this Trust Policy to a Role, you must explicitly allow Users or Groups (or Roles) in Account 123456789012
to assume that Role. Use a Policy like this one:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::123456789012:role/RoleName"
}
]
}
You can assume a Role using the AWS CLI as described in the docs.
Roles can be useful for:
- Allowing a User from another Account to access specific resources belonging to your account
- Allowing a machine to operate AWS resources autonomously
- Using your AWS credentials to authenticate against non-AWS systems: for example, a Kubernetes instance.