The way we create buckets in our org and ensure sane ACLs around it is by providing an automated tool (that internally uses Terraform) to provision an S3 bucket. So say when a user requests for a new bucket, named testBucket we create a bucket named testBucket and also create an IAM user by the name testBucket-user. The automation ensures that the testBucket-user's policies are such that the only allowed actions to this user are :


and the only allowed resource on which the above actions are allowed is the testBucket bucket.

Similarly, the automation also ensures that the automation puts bucket policies to ensure that the only actions allowed on it are the above 3 actions and only by the user testBucket-user

However, on demand (& if business justified) we do make changes to the created bucket policies as and when needed. So recently there was one such requirement, where a certain bucket needed to have a folder in it that was meant to hold all publicly intended images.

Now there were 2 options we had in order to provision the above requirement:

  1. Modify the bucket policy to allow principal:* for the folder in the bucket thus allowing all objects in that folder in the bucket to be by default public.
  2. To modify and give PutObjectACL permissions to the IAM user that has access to that bucket and let the dev manage which objects in the folder can be or can not be public.

As the security team we were more convinced of the first option just because it looked more logical. The problem with the first option however was the fact that now any object (publicly intended or even otherwise) in this folder would be by default public.

I wonder what does the community think here around it? AWS/IAM experts, what would be your choice of the two options above and why ?


I don't consider myself an expert of S3, but I think the first option makes more sense for several reasons. The most important one is that a developer will inevitably set the wrong ACL at some point and allow public access. Not out of malice, not out of laziness, but out of ignorance (e.g. what is the developer turnover on your company?, because that is how fast knowledge about this things go away).

So, a very important point is that you can actually do both (bucket policy + IAM), and I have the feeling this is the recommended secure approach. Users will only be able to do only the operations that are an intersection of the permissions assigned via bucket policy and IAM. What I like about this is that it provides a boundary to what is possible, but applied to the bucket itself. My suggestion would be to keep the bucket locked, but only allow public access to the folder, and maybe allow PutObjectACL on the objects in the public folder.

On a slight tangent but very relevant, you could use cloudfront, so the name of your S3 bucket is never revealed. On top of that you can only allow cloudfront to access the public folder. In this way the bucket remains locked down, and cloudfront is restricted only to the public folder.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.