Writing custom IAM policies can be difficult, especially when job function utilizes bunch of services. AWS manages several IAM policies for particular job functions (such as data scientist), which are a great help, but what if we want to restrict access to certain services all together, or certain actions, or even specific buckets?
A common pattern in lake house architecture is to have an S3 bucket of raw data, a process to tokenize/scrub the data of sensitive information, and then a “cleansed” bucket with cleansed data that can be used in analyses. The AWS-managed DataScientist job role policy is complex, and we’d prefer to use that as our base policy but put additional restrictions on it. The question became, can we simply attach an additional policy to a role and have it override some of the settings in the AWS-managed policy? As it turns out, we can.
The first question we had was, can we make restrictions tighter than an AWS-managed policy by adding one of our own? Here’s what I did. I first created a user, with only AmazonS3FullAccess, which allowed me to access all objects in all buckets. I then created the following policy and attached it as an inline policy to my test user.
I repeated this experiment, but this time creating and attaching the a customer-managed policy. The result was the same—the user could list the bucket’s objects when my custom policy was not attached, and could not list the objects when the policy was attached.
The second question we had was whether or not we could loosen restrictions in an IAM-managed policy by attaching one of our own. To test this, I used the same user as above, but removed all policies, and then added AmazonS3ReadOnlyAccess. Then, I confirmed a folder could not be created:
I then created a policy which allowed PutObject, attached it to the user, and confirmed I could now create a folder:
So again, a customer managed policy can override an AWS-managed policy.
This isn’t surprising, since explicit permissions overrule implicit permissions. One final question we wanted to test was what happens with two explicit permissions—one allow and one deny for the same action. I created two policies–one which explicitly denied listing buckets, and one which explicitly allowed listing of buckets–and attached them to the same user one at a time. After confirming they worked as intended when attached individually.
When attached together, the explicit deny overrides the explicit allow.
Customer-managed policies can be used to override actions when implicitly allowed or denied in AWS-managed policies. This means we can make use of the complex AWS-managed IAM policies and still have the ability to make some modifications when needed.
AWS describes the order of evaluation at https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html. The results here are in line with the logic described—we could allow an action which wasn’t explicitly denied, but an explicit deny took precedence over an explicit allow.
Creating folders and listing objects are easy tests, but they’re not the full story. It would merit some deeper investigation into individual actions before concluding all actions behave the same way. Also, this emphasizes the need for specifically and carefully defining the actions you want to allow or deny.