Access S3 object via cloudfront as a specific IAM user


When adding my s3 bucket policy, i set the principal to be the ARN of a specific IAM user i created. I read in the docs that it was best practice to not use the root IAM user, but instead create a user that i would use to access all AWS services. The issue is, whatever i PUT into the bucket as that user , i am unable to GET using a cloudfront distribution i created (s3 denies me access to the objects). I want to be able to GET the object back to the client using cloudfront. So my question is, how do i make it that s3 sees that the cloudfront distribution is owned by the same user that PUT the object in the bucket. How do i link the user and the cloudfront distribution.

PS: i used s3 presigned URLs to PUT the objects in the bucket and used signedURLs to GET the objects from s3 using cloudfront

  • The user that is doing the PUT is from the same AWS account of the S3 bucket? If you are doing a signed url GET to the S3 object and you are using cloudfront, what is the endpoint/fqdn that you are using to craft the signed url?

4 Answers
Accepted Answer

Apparently, the issue was from how i was naming the object in the bucket. I added a timestamp in ISO8601 format to each objects' name when creating the s3 presignedUrl for the PUT request. So when cloudfront tries to access it, it changes the some of those weird characters in the date string, and as a result, s3 denies access. Because the object cloudfront is trying to access doesn't exist. Thanks for the help

answered a year ago

I'm not sure, but you need asterisk after bucket name in Resource section as bellow.

"Resource": "arn:aws:s3:::S3 bucket/*"
answered a year ago
  • i did that. It got removed when posting the comment


It does not matter who puts the object in the bucket. What matter is who has GET access to the object. If I understand your question, you want to be able to restrict access to your S3 bucket so that objects can be accessed only through your Amazon CloudFront distribution. If that's your intention, here is how to achieve that:

answered a year ago
  • I already did that. But i am unable to access the object PUT by that user. The only way i can get access to an object in the bucket using cloudfront, is id i upload that object directly from the s3 console. Once i try to do that outside the console (programmatically) i am denied access. Here's a snippet of my bucket policy in case i am doing anything wrong: { "Version": "2012-10-17", "Id": "Policy1638646826561", "Statement": [ { "Sid": "Stmt1638646778880", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam:: non root IAM user" }, "Action": [ "s3:DeleteObject", "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::S3 bucket/" }, { "Sid": "Stmt1638646824013", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity someOAI" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::S3 bucket/" } ] }


The bucket policy snippet you provided allows ANYONE with the cloudfront distribution to READ specific objects from the specified bucket.

The part of the bucket policy restricting s3 actions to a non root IAM user only applies from the console, CLI or API calls made to S3 service. You probably want to update it to something like

    "Action": [

Note: There is no link between CloudFront access (using OAI) and the IAM user.

You mentioned using a presigned URL to restrict who can access the file - here are a couple of other things to look out for:

  • ensure that you create the presigned URL using your non root IAM user - that is the context in which it is created and it 'inherits' the security policy of that user
  • when creating a distribution and selecting the S3 origin with a bucket - select “Forward all query params, cache based on all” on the Query String Forwarding and Caching part, as S3 signed URLs utilize query parameters for the signature
  • you may need to update the CloudFront distribution so that the origin S3 url contains the correct region, for example if you simply select a bucket it will be something like however the S3 signed URL is actually something like, so manually update the origin as required
profile picture
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions