AWS Identity and Access Management (IAM)

What is Identity and Access Management?

In this post we will get a quick overview of what Identity and Access Management service is. Firstly, I want to define what is meant by Identity and Access Management. I shall break this down into two parts, starting with identity management.


Identities such as AWS usernames are required to authenticate to your AWS account. Authentication is the process of presenting an identity, in this case, a username, and providing verification of the identity such as entering the correct password associated.


The second part, access management, relates to authorization and access control. Authorization determines what an identity can access within your AWS account once it’s been authenticated to it. An example of this authorization would be the identity’s list of permissions to access specific AWS resources. Access control can be classed as a mechanism of accessing a secured resource. For example, username and password, multi-factor authentication (MFA) and federated access.

Essentially IAM can be defined by its ability to manage, control and govern authentication, authorization and access control mechanisms of identities to your resources within your AWS account.

The AWS IAM service is used to centrally manage and control security permissions for any identity requiring access to your AWS account and its resources.

This is achieved by using different features within IAM consisting of:


  • Users: These are objects within IAM identifying different users.
  • Groups: These are objects that contain multiple users.
  • Roles: These are objects that different identities can adopt to assume a new set of permissions.
  • Policy Permissions: These are JSON policies that define what resources can and can’t be accessed.
  • Access Control Mechanisms: These are mechanisms that govern how a resource is accessed.

Within AWS some services are regional and some are global. IAM is a global service, meaning that you do not have to create different users or groups within each AWS region that you have resources. IAM covers all regions.

IAM is the first service a user will interact with when using AWS, the reason being the identity needs to be authenticated by IAM before accessing any AWS resource. This could be via the AWS management console within your browser or via the AWS command line interface using an API call trying to gain access to a resource.


It’s critical to understand how IAM works and what can be achieved via the service, but it’s even more important to know how to implement its features. Without IAM there would be no way of maintaining security or control of who or what could access your resources and what they could do with them, both internally and externally.

IAM provides the components to maintain this management of access, but it’s only as strong and secure as you configure it. The responsibility of implementing secure, robust and tight security within your AWS account using IAM is yours, the owners of the AWS account. You must define how secure your access control procedures must be, how much you want to restrict users from accessing certain resources, how complex a password policy must be and if users should be using multi-factor authentication.

Users, Groups and Roles

I am going to define the user, group and role objects within AWS IAM, and the differences between them.


Users are objects created to represent an identity. This could be a real person within your organization who requires access to operate and maintain your AWS environment. Or it could be an account to be used by an application that may require permissions to access your AWS resources programmatically. Users are simply objects representing an identity which are used in the authentication process to your AWS account.


When creating a new user, you have the option to create it via

  • the AWS Management Console,
  • or programmatically via the AWS CLI,
  • or Tools for Windows Powershell,
  • or using the IAM HTTP API.

I shall be using the AWS Management Console to demonstrate how to configure various elements of AWS IAM.

User object creation involves the following seven steps.

Use groups for assigning permissions: Permission assignments can either be assigned to the user, or inherited from being a member of a group. Using groups to assign permissions is one of the best practices. With this in mind, and as best practice, you should consider using groups for permission assignment over assigning permission to individual users. So let’s now take a look at groups to help explain why.


Groups: IAM Groups are objects much like user objects. However, they are not used in any authentication process. However, they are used to authorize access to AWS resources, through the use of AWS Policies.

IAM Groups contain IAM Users, and these groups will have IAM Policies associated that will allow or explicitly deny access to AWS resources.


These policies are either AWS managed policies, that can be selected from within IAM, or customer managed policies, that are created by you, the customer.

Groups are normally created, that relate to a specific requirement or job role. Any users that are a member of that group inherit the permissions applied to the group. By applying permissions to the group instead of individual users, it makes it easy to modify permissions for multiple users at once. All you would need to do is modify the permissions of a group, and all users associated with the group would inherit the new access.

The alternative would be to update permissions for each and every user, which is time-intensive and prone to human error, which is why it’s best practice to assign permissions to groups rather than individual users, especially in an enterprise environment. Creating a group is very simple, and is essentially a three step process.

Firstly, you give your group a meaningful name, you’ll then assign permissions via policies, and finally, review your group. Once created, you can then assign users to the group.

IAM Roles

IAM Roles: IAM Roles allow users and other AWS services and applications to adopt a set of temporary IAM permissions to access AWS resources.

To appreciate the beauty of IAM roles, firstly, let’s look at an example of how the Amazon EC2 service uses an IAM role.

Consider the following scenario. You have an EC2 instance running an application that requires access to Amazon S3 to Put and Get objects using the relevant API calls.

To allow access to S3, a set of credentials could be stored on the EC2 instance itself, allowing any application to use those credentials to gain access to the relevant bucket for any Put or Get API requests. However, in this scenario, you would need to manage these credentials manually, including the rotation of access keys, which is obviously an administrative burden. As shown in this figure:


To alleviate this issue, the EC2 instance could be assigned an IAM role that would contain the relevant permissions granting the EC2 instance and its applications access to S3 to perform the Put and Get API calls. This assignment can be made during the EC2 instance creation by selecting the role to be associated, or once the EC2 instance is up and running, a role could also be applied.

An existing role associated to an EC2 instance can also be replaced by a different role if required. From a security best practice perspective, you should always associate a role to an EC2 instance for accessing AWS resources over storing local credentials on the instance itself.


Advantanges of IAM Roles: There are many advantages to roles, the IAM roles themselves do not have any access keys or credentials associated to them. Instead, when used, these credentials are dynamically assigned by AWS. Also, imagine you have a fleet of EC2 instances, all performing the same task, and using the same role. Now, consider that your existing application, which was used to perform Put and Get requests was now only required to perform Put requests only and Get requests must be denied.


To make the change, all you would need to do is to alter the permissions assigned to the IAM role, and all EC2 instances associated with that role would now have the correct access. If this same scenario happened by embedding credentials locally on the EC2 instance, then again, this would take a long time to replicate the change on every instance.

Roles and Users

Let’s now look at how IAM roles can be used with IAM users. There may be circumstances where you’ll need to grant temporary access to AWS resources for a particular user. Instead of adopting their group permissions, or granting permissions to the individual user, which, as we know, is not best practice, we could simply allow the user to assume a role, temporarily replacing their existing permissions.

To do this, the user must first be given permission to adopt the role via an access policy. Let’s take a deeper look at roles, to see how they are constructed and the different types of roles that are available.

Types of Roles

There are currently four different types of roles that can be created, all of which serve a different purpose.

  1. Firstly, the AWS Service Role. This role would be used by other services that would assume the role to perform specific functions based on a set of permissions associated with it. Some examples of AWS Service Role would be Amazon EC2, AWS Directory Services, and AWS Lambda, etc. Once you have selected your service role, you would then need to attach a policy with the required permissions, and set a role name to complete its creation.


  1. Secondly, the AWS Service-Linked Role. These are very specific roles that are associated to certain AWS services. They are pre-defined by AWS, and the permissions can’t be altered in any way, as they are set to perform a specific function. Examples of these AWS Service-Linked Roles are Amazon Lex-Bots, and Amazon Lex-Channels. Once you have selected your service-linked role, you simply need to assign it a name and complete the creation. Remember, these roles do not allow you to modify the permissions assigned.

  2. Thirdly, roles for Cross-Account Access. This role type offers two options. Providing access between AWS accounts that you own, and providing access between an account that you own and a third party AWS account.

  3. Lastly, role for Identity Provider Access. This role type offers three different options. Grant access to web identity providers. This is used to create a trust for users using Amazon Cognito, Amazon, Facebook, Google, or any other open ID connect provider. Grant web single sign on to SAML providers. This allows access for users coming from a SAML provider, which stands for Security Assertion Markup Language. Grant API access to SAML providers.

Steps for creating Users, Groups and Roles

This figure shows the order of steps to be taken in a typical scenario: aws_iam10

  • start by creating a group,
  • then attach permissions to this group by using an existing AWS managed IAM policy,
  • then create a new user, as a part of this process,
  • assign this user to the group, as per best practice.
  • then set up a new service role to be associated to an EC2 instance,
  • and then assign this role to an EC2 instance at creation.

IAM Policies

Here we will take a look at IAM policies. How they are created, modified and constructed. The syntax and structure of these policies.

IAM policies are used to assign permissions to users, groups, and roles.

But what do these policies look like? IAM policies are formatted as JSON documents. Each policy will have at least one statement, where the structure may look like this example. Let me break the structure of this policy down to allow you to understand each element.


  • Version: This going to the policy language version and at the time of this writing, the current policy version is 2012-10-17.
  • Statement: This defines the main element of the policy, which will also include other sub-elements, including Sid, Action, Effect, Resource, and Condition. These elements will identify the level of access, granted or denied, and to which resource.
    • Sid Statement ID is simply a unique identifier within the Statement array. As you add more permissions, you will have multiple Sids within the Statement.
    • Action. This is the action that will either be allowed or denied, depending on the value entered for the Effect element. Actions are effectively API calls for different services. As a result, different Actions are used for each service. For example, for delete bucket action is available for s3, but not for ec2. And likewise, the create key pair action is available for ec2 but not s3. The Action is prefixed with the associated AWS service. Action could be an array, like shown here on the left - here we have two Actions for cloudtrail, one is to CreateTrail and the other is to DeleteTrail. Or you could, as seen on the right, use an asterisk as a wild card which represents all Actions for the cloudtrail service, essentially granting full access to the service. aws_iam12
    • Effect: This element can either be set to allow or deny, which will either grant or restrict access for the previous Actions defined in the statement. By default, access to your resources are denied and, so therefore, if this is set to allow, it replaces the default deny. Similarly, if this was set to deny, it would override any previous allow.
    • Resource: This element specifies the actual resource you wish the “Action” and “Effect” to be applied to. AWS uses unique identifiers, known as ARNs, Amazon Resource Names to specify specific resources. Typically, these ARNs follow a syntax of: aws_iam13
      • Partition: This relates to the partition that the resource is found in. For standard AWS regions, this section would be AWS.
      • Service: This reflects the specific AWS service. For example, s3 or ec2.
      • Region: This is the region that the resource is located. Some services do not need the region specified, so this can sometimes be left blank.
      • Account-id: This is your AWS account-id, without hyphens. Again, some services do not need this information, and so it can be left blank.
      • Resource: The value of this field will depend on the AWS service you are using. For example, if I were using the Action “s3:PutObject”, then I could use the bucket that I wanted those permissions to apply to using the following ARN.
      • Condition: This is an optional element that allows you to control when the permissions will be effective based upon set criteria. The element itself is made up of a condition and a key-value pair. And all elements of the condition must be met for the permissions to be effective. In the example, the IP address is the condition itself, which the key-value pair will be effective against. The AWS Source IP is the key and the IP address is the value of the key. So effectively, what this is saying is if the Source IP address of the user who is using the policy is within their 10. 10. 0. 0/16 network range, then allow the permissions to be used. aws_iam14

As I mentioned previously, you can have multiple Sids within a statement, each granting a different level of access.

The example below demonstrates this and I have highlighted each a different color to show the separation.


  • The first Sid allows any resource full access to "cloudtrail" as long as their Source IP address is within the 10. 10. 0. 0/16 range.
  • The second Sid allows any resource to have full access to “autoscaling”.
  • The third Sid allows the creation and deletion of s3 buckets within the “iam-course-ca” bucket on s3.

Types of IAM policies

Now we know what an IAM policy looks like, I want to talk to you about two different types of IAM policies available. These being Managed Policies and In-line Policies. Managed policies come in two different flavors, AWS Managed Policies and Customer Managed Policies. These managed IAM policies can be associated with a Group, Role, or User. Although assigning to a User is not best practice, the difference between AWS and Customer Managed is as you would expect.


The AWS Managed policy have been pre-configured by AWS and made availble to you to help with some of the most common permissions that you may wish to assign. For example, these two AWS Managed policies covering s3. By selecting one of these policies, the necessary IAM JSON policy and its permissions will already be configured.

The two policies are configured as follows. The difference between the two separating full access from ready only is made clear in the “Action” element. The great thing about these AWS Managed policies is that you are able to edit them and make tweaks and changes before saving it as a new policy. This then becomes a Customer Managed policy.

This is great when an AWS Managed policy is almost as you need it, as it saves you time creating the policy from scratch. Let’s look at a scenario.

A user requires read only access to everything on s3, plus the ability to create new buckets for management purposes. To create the appropriate policy for this user, we should consider using the AWS Managed policy “AmazonS3ReadOnlyAccess”, which would give us the “ReadOnly” permission. But it would need to be copied and altered to allow the creation of buckets too.

Therefore, during the creation of this policy, the AWS Managed “AmazonS3ReadOnlyAccess” policy would be selected and then edited, as shown in red, to grant the additional “CreateBucket” permissions. So Customer Managed policies are any IAM policies that do not follow a pre-defined AWS Managed policy.


There are a number of ways to create a Customer Managed policy. These being the following: aws_iam18

  • Copy an AWS Managed policy. This is what we just covered, where an existing AWS Managed policy is used and then edited to create new Customer Managed policy.
  • The Policy Generator. This allows you to create a Customer Managed policy by selecting options from a series of dropdown boxes.
  • And you can create your own policy. If you are proficient in JSON and the syntax of IAM policy writing, then you can create your own policies from scratch or paste in a JSON policy from another source.

Lastly, there are Inline Policies: A Managed Policy could be attached to multiple users, groups, and roles, Inline Policies cannot. An Inline Policy is directly embedded into a specific User, Group, or Role, and as a result, it is not available to be used by multiple identities.

When the policy is being created, it is then associated to your IAM object. As a result, Inline policies do not show up under the Policies list with IAM, as they are not publicly available for other Users, Groups, or Roles to use with your account like Managed Policies are. Inline policies are typically used when you don’t want to run the risk of the permissions being used in the policy for any other identity.

When the User, Group, or Role is deleted, Inline policy is also deleted, as this is the only place where the policy exists.

Multiple IAM policies

With the ability to attach multiple Managed and Inline policies to an identity object in IAM, what happens when there are conflicting permissions assigned to the same User for example?

The rules for reviewing for permissions is very simple and can be summarized as follows: By default, all access to a resource is denied. Access will only be allowed if an explicit “Allow” has been specified within a policy associated with an identity. If a single “Deny” exists within any policy associated to the same identity against the same resource, then that “Deny” will override any previous “Allow” that may exist for the same resource and action.

An explicit “Deny” will always take precedence over an explicit “Allow”.