By Ian Mckay, Cloud Lead at Kablamo

IAM 10th Anniversary

This is our third blog post celebrating AWS Identity and Access Management (IAM)‘s 10th anniversary, where you’ll hear about the top recommendations on IAM from AWS Heroes and AWS Partner Network (APN) Ambassadors.

In Part 1 of the series, Rowan Udell covered how to balance developer innovation with the principle of least privilege and elaborated on IAM resource IDs. In Part 2, Ben Bridts showed how the IAM visual editor makes policy creation easier and explained the benefits of using federation over IAM users.

I am the Cloud Lead at Kablamo, an AWS Advanced Consulting Partner that delivers human-centered, cloud-based software so clients can make efficient, end-to-end use of the cloud. My focus is cloud architecture, CI/CD, and security, but I am always trying out the latest AWS services.

I built and maintain both the Former2 and Console Recorder for AWS projects, which help developers author infrastructure as code (IaC) templates such as AWS CloudFormation from existing resources, or while in the AWS Management Console.

For this post, I’d like to talk about two powerful ways that you can limit access to Amazon Web Services (AWS).

Set the Boundaries

In mid-2018, AWS released an advanced feature for IAM called permissions boundaries, which is used to restrict the maximum permissions that an IAM user or role can be granted through an identity-based policy.

For example, if a permissions boundary is set on an IAM user, the effective permissions that user has will always be the intersection of the permissions boundary and the user’s IAM policies. If you’re like me and have struggled with delegating permissions within large organizations, you’ll quickly understand how useful having these permissions boundaries can be.

Here’s an example of how this works in practice:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "SimpleUserPermissions", "Effect": "Allow", "Action": [ "s3:*" ], "Resource": "*" } ]

The preceding policy is a simple example of the permissions a user might have. In this case, users can only perform Amazon Simple Storage Service (Amazon S3) actions.

Let’s say this policy was created with the name SimpleUserPolicy. Within this account, there is a person assigned to administer the creation of users. The policy assigned to their IAM user is as follows:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "SimpleUserPermissions", "Effect": "Allow", "Action": [ "s3:*" ], "Resource": "*" }, { "Sid": "CreateOrChangeUser", "Effect": "Allow", "Action": [ "iam:CreateUser", "iam:DeleteUserPolicy", "iam:AttachUserPolicy", "iam:DetachUserPolicy", "iam:PutUserPermissionsBoundary", "iam:PutUserPolicy" ], "Resource": "*", "Condition": { "StringEquals": { "iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/SimpleUserPolicy" } } }, { "Sid": "IAMPermissions", "Effect": "Allow", "Action": [ "iam:Get*", "iam:List*", "iam:Simulate*", "iam:DeleteUser", "iam:UpdateUser", "iam:CreateAccessKey", "iam:CreateLoginProfile" ], "Resource": "*" } ]

This policy grants the IAM user the same permissions as the other users (with the SimpleUserPermissions statement), as well as the ability to browse through and update user details (with the IAMPermissions statement).

The policy also grants the ability to create users or change their assigned policies, with the CreateOrChangeUser statement. Crucially, this statement has a condition that applies a permissions boundary on the create/update process. This means, for example, that if this user creates a new user then it must be assigned the SimpleUserPolicy permissions boundary, or the CreateUser call will fail.

With this, you can limit the created user’s permissions so it can only perform the actions that are allowed by its identity-based policy and the permissions boundary that was set for the IAM user administrator. You can find more details about this in the permissions boundaries documentation.

Who, What, When?

One of the more powerful features of IAM policies is their ability to conditionally provide access to resources. This can help teams to separate their workload from other workloads or prevent unwanted actions.

I use a variety of conditions in the IAM policies I write (where doing so makes sense) and often aggregate multiple conditions in a single statement to achieve least privilege, which Rowan talks about in Part 1 of this series. Here are some examples.

Tag-Based Access (Attribute-Based Access Control)

You can use tags to give access to AWS resources. The following policy grants access to perform the DeleteVolume, ModifyVolume, and ModifyVolumeAttribute actions for Amazon Elastic Block Store (EBS) volumes, as long as they have the Department tag set to Finance.

This is an easy way to separate different parts of the business within the same account. Remember, a few services do not support tagging, and account-wide limits still apply to everyone.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DeleteVolume", "ec2:ModifyVolume", "ec2:ModifyVolumeAttribute" ], "Resource": "arn:aws:ec2:*:*:volume/*", "Condition": { "StringEquals": { "aws:ResourceTag/Department": "Finance" } } } ]

Timeframe Restrictions

The following policy grants users access to perform the S3 DeleteObject action only within the timeframe shown. This is useful when users (for example, contractors) are permitted to have access only during certain periods.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:DeleteObject" ], "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "DateGreaterThan": { "aws:CurrentTime": "2021-04-01T00:00:00Z" }, "DateLessThan": { "aws:CurrentTime": "2021-05-31T23:59:59Z" } } } ]

IP-Based Restrictions

The following policy grants users access to perform the S3 DeleteObject action only when the request is made from the IP addresses specified. This can help restrict calls to occur only from within a corporate network, as an extra layer of security.

Note that calls made by AWS services, such as by CloudFormation when it creates resources, cannot be restricted in this way. However, the call to create the stack could be restricted.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:DeleteObject" ], "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "IpAddress": { "aws:SourceIp": [ "" ] } } } ]

The preceding conditions, and many more found on the AWS global condition context keys reference page, help you provide fine-grained access that can help your environment to remain secure and locked down to only the intended audience.


Using permissions boundaries and conditions is an effective way to limit access. By letting you set the maximum permissions for a user or role, permissions boundaries can be used for situations like granting someone limited permissions management abilities.

Conditions enable you to specify when a policy statement is enforced, providing fine-grained access through variables such as tag value, time, and IP address. Using these IAM features will help you in your pursuit of least privilege on AWS.

Stay tuned for Part 4 of our blog series, where we conclude with Mark Nunnikhoven on the topic of understanding what permissions are available and “who did what?”

Be sure to check out the other posts in our IAM 10th anniversary series on the APN Blog:

The content and opinions in this blog are those of the third-party author and AWS is not responsible for the content or accuracy of this post.


Kablamo – AWS Partner Spotlight

Kablamo is an AWS Advanced Consulting Partner that delivers human-centered, cloud-based software so clients can make efficient, end-to-end use of the cloud.

Contact Kablamo | Partner Overview

*Already worked with Kablamo? Rate the Partner

*To review an AWS Partner, you must be a customer that has worked with them directly on a project.