A detailed look at IAM in AWS

IAM (Identity & Access Management) is the term used to describe the management of users, groups, policies and roles within AWS. This is your first layer of security, when it comes to all you do in AWS.

The benefits of IAM:

There are a number of benefits to using IAM. Firstly, we have centralized control of all our resources and those individuals that have access to the resources. This enables you to manage all your users, their permissions and their security credentials in a single place.

IAM also gives you the ability to only grant access from specified networks (for API requests or console login), using the source IP clause. This would enable you to only provision access to those individuals sitting within your company offices – further enhancing security.

You can also set up temporary user access when needed – we can integrate with Microsoft Active Directory so that we can grant temporary permissions to users.

IAM also gives you the ability to enforce a password policy for your users and enables you to set out MFA requirements. MFA is Multi Factor Authentication, which is used to enhance security as it requires your account password in addition to a randomly generated passcode.

Getting Started – Best Practices:

When you first create an account in AWS, we consider this to be your ‘root’ account. That is, the top level admin that owns all services & can carry out any activity on the AWS account. It is best practice to carry out the following on the root account as soon as possible:

  • Delete your root access keys: You should not use your root account for day to day activities and should delete your root access keys as soon as possible
  1. Setup Multi-Factor Authentication (MFA): MFA is an additional layer of security which requires a unique, frequently changing code to be entered in addition to your password in order to access your account. You can configure this to use your mobile device or can request a hard token to be provided by AWS
  2. Create new IAM users: as above, best practice states that the ‘root’ account should not be used for day-to-day activities. As such, you should create a new IAM user and assign admin privileges to that user
  3. Use groups to assign permissions to each user: for easier and less error-prone user management, you should assign permissions to users via groups, rather than assigning permissions directly to the user profile.
  4. Create a strong password policy for your users: forcing your users to have a strong password ensures their accounts are as safe as possible

IAM in action:

Before we see how IAM works, let’s get a few definitions in place for each of the elements:

  • Groups: enable us to group users together and manage their permissions from a single place. The alternative is to manage permissions, one user at a time which is very time consuming and prone to human error.
  • Policies: provide the access levels we desire and can be applied to users, groups and roles. For example, an S3 all access policy can be applied to a group called ‘developers’, which will give all users within that group access to all S3 buckets.
  • Roles: are used to provide permissions to other AWS services. For example, let’s say you have a server that runs an application that will need to access your S3 bucket. You’d need to assign that server a role & attach a policy to that role to enable the server to access the S3 bucket. Note: only one role can be applied at a time. Roles can be changed at any time,

    Roles can be:
    • To provide other AWS services permissions (e.g. EC2 permission to access S3)
    • Cross-account access: to assume the access rights of another AWS account
    • External accounts (no AWS account) to connect via Active Directory or an SSO provider (like Google or Facebook) – can be from on-premise environments

Each of the components discussed above are outlined in the below diagram. Let’s talk through each of the ‘actors’ one at a time.


Bob and Carl are both part of the admin group. That group has a policy applied to it which grants access to S3 to all members of the group. As such, Bob & Carl are able to access the S3 bucket with no issues. If we want to revoke their access, we can do that at group-level, avoiding the management overhead of editing each account individually.

Helena isn’t a member of a group but has an S3 policy applied directly to her user account. This means that she is able to access the S3 bucket. To manage her permissions, we would have to do it at account level as she is not a member of a group.

Sam is a little different, he is accessing AWS services via the command line & as such requires API keys to use the AWS S3 service. Once he’s authenticated using his keys, AWS applies the policy that’s been attached to his account to manage his access and provision S3 privileges. We would have to edit Sam’s permissions at account level too as he is not a member of a group.

Side Note:

You may be wondering why there are two ways to provision access to a user – through a group or directly to their user account. Well, best practice is to manage user access privileges through groups. Why? Well, let’s say that you’re selling your company. The company acquiring you, have a legal team. This team need to carry out due diligence before they’ll commit to buy your company – the process will take 3 months. So you provision their team with access to the S3 bucket, intending to revoke that access in 3 months time. If you use a group to manage these users, you can revoke access to all users at the same time – with no risk of missing one or two users. Whereas, if you apply policies directly to the user account, you add additional administrative burden & risk accidentally leaving some users with access that they should not have.

What happens if someone has two policies assigned to them – one that allows access to Amazon S3 and the other denies access to Amazon S3? Well, an explicit deny ALWAYS overrides an explicit allow. That means, in this case, the user would be denied access to Amazon S3. Why is this useful? Well, let’s say a user goes on maternity leave. You don’t want them to have access while they’re away but you may not want to manually remove every policy now, just to put them all back in 9 months time. So, you can add a deny-all policy to the user, which will override any other policies attached to the users account.


The EC2 instance in the above scenario needs to be able to read and write to and from the S3 bucket for your application to run as it needs to. So, we apply a role to the EC2 instance allowing it to assume ‘user-like’ permissions to access the S3 bucket. Policies are then attached to the role in AWS, allowing us to easily edit permissions granted to the EC2 instance.

AWS Policies

AWS has a tonne of prebuilt policies, including:

  • Administrative Access: full access to everything
  • Power user access: full access to everything except user/group management
  • Read only – no ability to create or modify, just read

If none of the above suit your usecase & you can’t find any other pre-built policies that do, AWS offers a policy generator tool to help you build your own policy or you can even write your own from scratch. You can always test the policies you’ve written with the policy simulator, which helps you to understand whether your policy is working as you intended.

API Keys

API keys are generated and displayed only once. If you lose your API keys, you’ll need to deactivate the old keys & generate new ones. Only AWS users can have API keys – roles do not. API keys are required for:

  • AWS CLI Calls
  • Windows Powershell
  • HTTP calls using the API
  • Other development tools


  • User credentials should never be passed to an EC2 instance, roles should be used instead
  • Never create or store your API keys on an EC2 instance
  • Users should be granted permission to access only resources they need to do their assigned job, we call this the principle of least privilege.