Secure services and resources with AWS Identity and Access Management (Part 2)

If you would like to read the other parts in this article series please go to:


In this multi-part article, we’re discussing how to use AWS Identity and Access Management (IAM) to create and manage users and groups and assign permissions to them so as to granularly control how they can access your AWS resources. In Part 1, we talked about IAM basics: how it works, users and groups, authentication and credentials. We then introduced the concept of IAM policies.

IAM policies and permissions

In the context of IAM, policies and permissions are inextricably entwined. You have to create an IAM policy in order to set the permissions. Permissions can be assigned to:

  • Users
  • Groups
  • Roles
  • Resources

Resources are AWS services or products that integrate with AWS. These include S3 Storage, Amazon Glacier, SNS (Simple Notification Service), SQS (Simple Queue Service), AWS KMS (Key Management Service), and Amazon VPC (Virtual Private Cloud) Endpoint feature.

Types of policies: inline and managed

There are two different types of policies that can be applied to users, groups and roles: inline policies and managed policies. In turn, there are two different types of managed policies: AWS managed policies and customer managed policies. You can use both types of policies together, but knowing which is which can get a little confusing, so let’s sort out the differences.

The big difference is that managed policies are standalone; that is, you can assign one managed policy to multiple users, groups or roles. Inline policies are embedded into a single user, group or role. Another difference is that inline policies can be assigned to users, groups, roles or resources. Managed policies cannot be assigned to resources, only to users, groups or roles.

A managed policy can be assigned to one or more users, groups or roles. Managed polices that are created and managed by AWS are called AWS managed policies and they are easier to use, so it’s recommended that you use this type when possible. In addition, AWS automatically updates the AWS managed policies (for example, to add permissions for new services). Customer managed policies, on the other hand, are custom policies that you create and manage yourself. This makes for more work for you, but it also has the advantage of giving you more control over the policies than you have with the ones that are created and managed by AWS.

Managed policies have several advantages, in that they can be reused so efficiency is increased; you create a set of policies and assign them to whichever entities you want to have them. Since they can be assigned to multiple entities, you can make a single change to the policy and it’s automatically applied to all of those entities, whereas with inline policies you could have to change the policy on each individual entity. A big advantage is versioning. When you change a managed policy, it creates a new version of that policy but the old versions are still stored so that you can revert to a previous versions if you need to.

Finally, you can give other users the authority to assign policies to entities without making them full administrators so they aren’t able to change the permissions in the policies. You can do this on a per-policy basis, so that a user can assign certain policies but not others.

Inline policies are attached to a particular user, group, role or resource and you create and manage them yourself. There are no AWS managed inline policies. The inline policy is an inherent part of the entity. You can embed the policy at the time you create the entity, or you can create and embed the policy later. If you delete the entity, the policy is deleted, as well. The entity-policy relationship is thus simpler and more straight-forward with inline policies. This prevents the policy permissions from ever being mistakenly assigned to the wrong entities. However, you lose the ability to revert to older versions or delegate limited admin authority to other users.

Types of permissions: User-based and resource-based

There are two different ways that you can assign permissions, depending on the type of entity to which they are attached. User-based permissions are attached to user-based entities; that is, they’re attached to a user, a group or a role. These permissions would define which actions that user (or those users in a group, or those users in a role) are allowed to perform. Resource-based permissions are attached to a resource (as described above).

To further complicate matters, different resources support different types of permissions. Don’t get resource-based and resource-level permissions mixed up; they aren’t the same thing. Some resources support action-level permissions, which means you can specify individual actions. Some support resource-level permissions, which means you can specify individual resources in the policy. Some support resource-level permissions for some actions but not for others. Some support resource-level permissions only for some APIs and not for others. Some also support tag-based permissions, which let you create resource-level permissions via tags attached to the resource. Resource-based permissions are supported only by S3, Glacier, SNS, SQS, and AWS KMS.

IT pros with experience in Windows access controls know that things can be sticky when multiple sets of permissions combine. Just as those who access a file across a Windows network have their ultimate permissions determined by both the share permissions and the file (NTFS) permissions, when you’re working with IAM a user’s ultimate permissions can be based on both the user-based permissions that are assigned to that user’s account (or a group or role to which the user belongs) and the resource-based permissions that are assigned to the resource on which the user is attempting to perform some action. When the resource is Amazon S3 storage, the plot thickens even more.

In addition to user-based and resource-based permissions, S3 also supports S3 ACLs (Access Control Lists). Every bucket and object in S3 has an ACL, and ACLs are separate from IAM policies. ACLs grant users access through access policies, which are resource-based. ACLs only allow you to grant access; they can’t be used to deny access. You can’t use ACLs to grant permissions to other users in your AWS account, either – only to other AWS accounts. By default, only the AWS account that creates the bucket in S3 can access it.

Creating the policy document

The policy document defines permissions by defining the actions that can be taken by a user, for which AWS resources. For example, if you wanted to give a user access to viewing the items in a bucket in the Amazon S3 storage service, the action is ListBucket and the resource is the particular S3 bucket(s) that the user will be able to use this action for.

You can set either allow or deny permissions. This is called the “effect.” Note that as a best security practice, by default users will not have access to perform any action on any resources unless you explicitly assign them those permissions. Thus you usually wouldn’t need to set “deny” permissions. However, this could be useful if you want to set “allow” permissions for a group but then “deny” for one or more specific users who are in that group.

To create policy documents, you use JSON, which is the JavaScript Object Notation data-interchange format that is based on JavaScript, but easier for humans to read and write. You can find out more about JSON and a simple tutorial for how to use JSON here.

You can find out more about the syntax of the IAM policy language as expressed in JSON and some basic rules for writing JSON script for IAM policies here.

Note that an IAM policy can include multiple statements, but the size of IAM policies is limited. The limitation depends on the particular entity (user, role, or group) the policy is applied to. These limitations are as follows for inline policies:

  • User policy: maximum size is 2048 characters
  • Group policy: maximum size is 5120 characters
  • Role policy: maximum size is 10,240 characters

A user, group or role can have up to two managed policies assigned to it, with a maximum size of 5120 characters each.

There are a number of APIs that are used to control create, update or delete IAM policies. These include:

  • CreatePolicy
  • CreatePolicyVersion
  • DeletePolicy
  • DeletePolicyVersion
  • SetDefaultPolicyVersion

To give a user permission to create, update or delete policies and policy versions or set a default version, you would create a policy document to do so. There are many other APIs for granting a user the ability to attach and detach user, group or role policies. When you want to control access to specific managed policies, you use the ARN (Amazon Resource Name) of the policy, in the Resource or Condition element of the policy.

You can find sample policies that grant these types of permissions here.


In this, Part 2 of our series on AWS identity and access management with IAM, we delved into the world of IAM policies and ACLs and how they are used to control access as well as how they interact. In Part 3, we’ll look at how you working with managed policies using the AWS Management Console and the AWS command line interface.

If you would like to read the other parts in this article series please go to:

About The Author

Leave a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top