Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Denied when uploading files to Amazon using Paperclip and IAM policies

I am unable to get an upload working with Paperclip using an S3 IAM policy. I'm even having issues with direct jQuery uploads (no Paperclip). My scenario is as follows, I have an application that will have many sites. Each site will have it's own bucket and should only be able to access their own bucket, nobody else's. The IAM Example Policies documentation explains exactly what I want to do under "Example: Allow each IAM user access to a folder in a bucket". I have an IAM group set up for the application and have one user per site within the group. These IAM users belong to the group. The policy on the group is as follows:

{
   "Version":"2012-10-17",
   "Statement":[{
         "Effect":"Allow",
         "Action":[
            "s3:PutObject",
            "s3:GetObject",
            "s3:GetObjectVersion",
            "s3:DeleteObject",
            "s3:DeleteObjectVersion"
         ],
         "Resource":"arn:aws:s3:::my-app/${aws:username}/*"
      }
   ]
}

Here is my CORS configuration on the bucket, for dev of course, it will get locked down later:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Here are my Paperclip settings:

has_attached_file :background_image,
                  storage: :s3,
                  s3_credentials: {
                    access_key_id: "xxx",
                    secret_access_key: "xxx"
                  },
                  bucket: "my-app",
                  s3_permissions: "public-read",
                  path: "/background_images/:id/:filename"

I was previously working with policies directly on the bucket, which did work but wasn't as flexible as I need it to be when I move into a production environment with many "sites". As far as I can tell I've followed the documentation exactly yet anything I do results in 'Access Denied'. At this point I'm not even sure if my issue is with my IAM policy or my Paperclip configuration.

edit: clarification.

edit 2: FINAL SOLUTION

Here is my final IAM policy based on this article:

{
 "Version":"2012-10-17",
 "Statement": [
   {
     "Sid": "AllowUserToSeeBucketListInTheConsole",
     "Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::*"]
   },
  {
     "Sid": "AllowRootAndHomeListingOfCompanyBucket",
     "Action": ["s3:ListBucket"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::my-app"],
     "Condition":{"StringEquals":{"s3:prefix":["","home/"],"s3:delimiter":["/"]}}
    },
   {
     "Sid": "AllowListingOfUserFolder",
     "Action": ["s3:ListBucket"],
     "Effect": "Allow",
     "Resource": ["arn:aws:s3:::estimator-app"],
     "Condition":{"StringLike":{"s3:prefix":["home/${aws:username}/*"]}}
   },
   {
     "Sid": "AllowAllS3ActionsInUserFolder",
     "Effect": "Allow",
     "Action": ["s3:*"],
     "Resource": ["arn:aws:s3:::my-app/home/${aws:username}/*"]
   }
 ]
}

And my updated Paperclip settings:

has_attached_file :background_image,
                    storage: :s3,
                    s3_credentials: {
                      access_key_id: "xxx",
                      secret_access_key: "xxx"
                    },
                    bucket: "estimator-app",
                    s3_permissions: "public-read",
                    path: "/home/my_s3_username/background_images/:id/:filename"

It was important to include the username in the Paperclip path. I was assuming Amazon would infer that from the credentials but that's not the case.

like image 913
Ryan Arneson Avatar asked Oct 04 '13 15:10

Ryan Arneson


1 Answers

Because you're trying to set permissions on the objects you upload, you also need to give your IAM users the s3:PutObjectAcl permission.

like image 51
dcro Avatar answered Sep 21 '22 03:09

dcro