AWS Managed Policies are an anti-pattern


RSS feed

AWS Managed Policies are IAM policies provided by AWS to grant privileges for commomn use cases. An example of an AWS Managed Policy is AmazonS3FullAccess. This post will describe why you should avoid these.

What are AWS Managed Policies?

You can identify the AWS Managed Policies in the web console because they have an orange AWS icon next to them. In this picture, all of the policies except MyPolicy are AWS Managed policies.

Screenshot of console showing AWS Managed policies

From the command-line, you can run this command to list all policies, including both ones you created and AWS Managed:

aws iam list-policies --no-only-attached

The output will contain elements like this:

  "PolicyName": "CloudWatchEventsFullAccess",
  "CreateDate": "2016-01-14T18:37:08Z",
  "AttachmentCount": 0,
  "IsAttachable": true,
  "DefaultVersionId": "v1",
  "Path": "/",
  "Arn": "arn:aws:iam::aws:policy/CloudWatchEventsFullAccess",
  "UpdateDate": "2016-01-14T18:37:08Z"

You can identify AWS Managed policies because the ARN begin with arn:aws:iam::aws:policy whereas the ones you create will look like arn:aws:iam::123456789012:policy where it contains your Account ID as opposed to :aws:.

There are currently 399 AWS Managed policies. There is no difference between the "Job function" policies and other "AWS managed" policies as far as I know. Policies can change over time, and although 230 (57%) have never changed, 6 have changed over 10 times:

Policy nameCurrent version

The oldest policy is AdministratorAccess from 2015-02-06, which is simply * on *. There are 58 others released on that day that haven't changed since, which makes sense as the AWS Managed Policy feature was announced a few days later.

What's wrong with AWS Managed Policies?

AWS Managed Policies were made for common use cases, which means they almost always fall into two categories: They provide too much access, or not enough. This is why I call them an anti-pattern, because they are a common response to a recurring problem that does not solve it as well as you would like.

Too much access

AmazonS3FullAccess is a common example of a policy that provides too much access. This policy is often granted when a services need to read files from one S3 bucket and write files to the same or a different bucket. Immediately, you should recognize that this access should instead be locked down to only one or two buckets in order to implement a strategy of Least Privilege. The service also does not need to be able to list all of the buckets in the account because your code should know what buckets it will be working with. By granting s3:*, this policy grants 70 actions in total.

Not enough access

The other problem with AWS Managed Policies is they don't grant enough access. The SecurityAudit policy is one of the most annoying offenders of this. Despite having been updated as recently as May 15, 2018, this policy still does not grant any insight into the use of GuardDuty, Organizations, or many other services. It gives insight into only 64 of the 139 current IAM privilege services. Even within the services it covers, it is missing Describe calls that are needed to look for misconfigurations.


A problem with some of these policies is they are not kept up-to-date, which is one of the main things that attracted people to these in the first place. In addition to SecurityAudit not keeping up with services, this problem extends to other policies. For example, the policy AmazonZocaloFullAccess grants access to zocalo:*, but that's not an IAM privilege anymore. In 2015, Zocalo was renamed to WorkDocs, so that policy should be using workdocs:* instead to match its earlier functionality.

IAM is hard

Even AWS get's IAM wrong sometimes. Recently, they deprecated the AWS Managed Policy AmazonElasticTranscoderFullAccess because it granted iam:PutRolePolicy which can be used for privilege escalation, as described here. They also previously advocated a policy for enforcing MFA that I discovered could be bypassed without MFA, and myself and Duo Security worked with AWS to fix, as described here.

What should you do?

The AWS Managed policies are a good starting point to help you figure out what the names of the privileges are that you might want to use, but it's better to use the AWS Policy Generator. You may know the specific API calls your code makes, so you can look at my post AWS IAM vs API vs CloudTrail for help in converting the API names to IAM names in the cases where these differ.

Most people tend to over-provision privileges in the hopes of going back later to reduce these. To help with that strategy, you can use the open-source CloudTracker that I built with Duo Security, which is built around the concept of looking at the current privileges granted to users and roles and comparing those against the privileges that have actually been used, as seen in the CloudTrail logs. An alterantive strategy, with less granularity, is used by Netflix and their RepoKid tool that uses Access Advisor to reduce privileges at the IAM service level, as opposed to the Action level.

You also want to watch out for possible IAM privilege escalation possibilities. Generically, these can usually be identified by any ability to change IAM privileges (ie. being granted any actions other than List, Describe, or Get). To detect existing admins in your AWS accounts, or users and roles that can escalate their privileges to become admins, you can use CloudMapper (again a tool I built with Duo Security) and its find_admins command. NCC Group also recently came out with a tool called PMapper that can be used to graph out privilege escalations.

As you get more fine-grained with the privileges you grant, instead of simply using *, you may find your policies exceed AWS's limits, such as the 2,048 character limit on IAM user inline policies, or 6,144 on your own managed policies. To help with that, you can try using Netflix's policyuniverse (helpful in a number of IAM releated situations), or more likely you'll need to break the policy up into multiple policies.

In addition to the Actions you grant, you should focus on the Resources these actions are granted access to. You should also add restrictions by Conditions. For help with restricting Condition resources, see my post Defensive options when using AWS IAM roles

If you're looking for help with your AWS security, reach out to me!