Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby S3 "Access Denied" error when calling upload_file with ACL

Tags:

ruby

amazon-s3

I'm trying to write a Ruby script that uploads a file to AWS and makes the file publicly available. I've done the following:

s3 = Aws::S3::Resource.new(
    credentials: Aws::Credentials.new(KEY, SECRET),
    region:'us-west-2'
)
obj = s3.bucket('stg-db').object('key')
obj.upload_file(filename)

This seems to work fine, except that the file isn't publicly available, and I can't get a public URL for it. But when I log into S3, I can see my file just fine.

To make it publicly available, I changed the last line to

obj.upload_file(filename, acl: 'public-read')

But I'm getting an access denied error when I do this. Is there some permission setting I am missing on my S3 bucket that is causing problems, or am I calling this incorrectly somehow?

like image 703
Dennis Avatar asked Aug 31 '15 20:08

Dennis


1 Answers

After spending more time than I would like to admit playing around with S3 bucket policies, I figured out how to make it work.

I highly recommend these three AWS resources:

  1. Example Bucket Policies
  2. Policy Generator
  3. IAM Policy Elements Reference

I created a policy that allows a particular user to have Object Upload, Object ACL, and Object Delete permissions for my bucket. Here's the JSON:

{
"Version": "2012-10-17",
"Id": "Policy1441134540846",
"Statement": [
    {
        "Sid": "Stmt1441134537688",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::MY_USER_ID:user/[email protected]"
        },
        "Action": [
            "s3:DeleteObject",
            "s3:PutObjectAcl",
            "s3:PutObject"
        ],
        "Resource": "arn:aws:s3:::MY_BUCKET/*"
    }
]
}

A few tips:

  • The reference in bullet 3 above is helpful in understanding the "Principal" part of the JSON. Just create a user in IAM, and fill the appropriate info out.
  • The Resource part can be a little finicky. Depending on the permissions you're granting, you need to think about whether you should be specifying the objects in the bucket (hence the "/*" after MY_BUCKET) or the bucket itself. If you start getting errors when you try to save the bucket (something along the lines of "Action does not apply to any resource(s) in statement..." you're probably specifying the wrong resource.
  • One last thing you might try it just opening up your permissions to everyone (specifying Principal as "*") until you can get the functionality going. Then whittle down your access list by changing the Principal once you've got things going.
like image 138
Dennis Avatar answered Oct 08 '22 17:10

Dennis