36

I have a user foo with the following privileges (it's not a member of any group):

{
  "Statement": [
    {
      "Sid": "Stmt1308813201865",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bar"
    }
  ]
}

That user however seem unable to upload or do much of anything until I grant full access to authenticated users (which might apply to anyone). This still doesn't let the user change permission as is throwing an error after an upload when it tries to do do key.set_acl('public-read').

Ideally this user would have full access to the bar bucket and nothing else, what am I doing wrong?

Steffen Opel
  • 63,899
  • 11
  • 192
  • 211
Kit Sunde
  • 35,972
  • 25
  • 125
  • 179

9 Answers9

44

You need to grant s3:ListBucket permission to the bucket itself. Try the policy below.

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "S3:*",
      "Resource": "arn:aws:s3:::bar/*",
      "Condition": {}
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::bar",
      "Condition": {}
    }
  ]
}
Steffen Opel
  • 63,899
  • 11
  • 192
  • 211
cloudberryman
  • 4,598
  • 2
  • 27
  • 14
  • 4
    Some nuance: It seems that `bar/*` is needed to access objects inside the `bar` bucket, whereas `bar` is needed to list/modify the bucket itself. – Tim has moved to Codidact Feb 24 '13 at 02:30
  • Using Cyberduck to access S3 with the above permission didn't seem to work. It may be that Cyberduck needs ListAllMyBuckets as mentioned by @Suman. However if you use the command line tool from [timkay.com](http://www.timkay.com/aws/), this works perfectly. – Thanh Nguyen Mar 12 '13 at 07:40
  • 7
    Thanks a million. I F$%#@^ING hate s3 with its cumbersome policies. Just wasted 2 hours till I finally found the solution. – Nimo Oct 09 '14 at 23:22
  • 9
    It works in Cyberduck if you set "Path" under "More Options" to the bucket name. Then you don't need to add ListAllMyBuckets. – Joar Leth Sep 18 '15 at 08:23
  • Would just like to confirm what @JoarLeth said: if you set the path in cyberduck connection options, then you don't need a ListAllMyBuckets permission – WickyNilliams Jun 16 '16 at 21:41
21

The selected answer didn't work for me, but this one did:

{
  "Statement": [
    {
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ]
    }
  ],
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:ListAllMyBuckets",
      "Resource": "arn:aws:s3:::*"
    }
  ]
}

Credit: http://mikeferrier.com/2011/10/27/granting-access-to-a-single-s3-bucket-using-amazon-iam/

Suman
  • 9,221
  • 5
  • 49
  • 62
8

Are you aware of the AWS Policy Generator?

Ryan Parman
  • 6,855
  • 1
  • 29
  • 43
4

There is an official AWS documentation at Writing IAM Policies: How to Grant Access to an Amazon S3 Bucket

Just copy and paste the appropriate rule and change the "Resource" key to your bucket's ARN in all Statements.

For programamtic access the policy should be:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": ["s3:ListBucket"],
            "Resource": ["arn:aws:s3:::bar"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:DeleteObject"
            ],
            "Resource": ["arn:aws:s3:::bar/*"]
        }
    ]
}

And for console access access should be:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "arn:aws:s3:::bar*"
        },
        {
            "Effect": "Allow",
            "Action": ["s3:ListBucket"],
            "Resource": ["arn:aws:s3:::bar"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:DeleteObject"
            ],
            "Resource": ["arn:aws:s3:::bar/*"]
        }
    ]
}
Marcio Mazzucato
  • 8,841
  • 9
  • 64
  • 79
0

That works for me:

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:ListBucketMultipartUploads",
                "s3:ListBucketVersions"
            ],
            "Resource": "arn:aws:s3:::bucket_name_here"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:*Object*",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": "arn:aws:s3:::bucket_name_here/*"
        }
    ]
}
void
  • 1,343
  • 11
  • 26
0

If you've been pulling your hair out because you cannot figure out why Cyberduck is not being able to set object ACLs but it works with another client (like Panic Transmit) here is the solution:

You need to add s3:GetBucketAcl to your Action list, eg:

{
    "Statement": [
        {
            "Sid": "Stmt1",
            "Action": [
                "s3:GetBucketAcl",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::your-bucket-name"
        }
    ]
}

Of course you don't need to do this if you are less restrictive with s3:* but I think this is good to know.

daniel
  • 63
  • 1
  • 7
0

@cloudberryman's answer is correct but I like to make things as short as possible. This answer can be reduced to:

{  
   "Statement":[  
      {  
         "Effect":"Allow",
         "Action":"S3:*",
         "Resource":[  
            "arn:aws:s3:::bar",
            "arn:aws:s3:::bar/*"
         ]
      }
   ]
}
Sam Rueby
  • 5,914
  • 6
  • 36
  • 52
  • 1
    But your answer is not equivalent to cloudberryman. Your example provides FULL access to the bucket AND the bucket contents, whereas his only allows list on the bucket but full access to the contents. In your case, the privileges permit the bucket itself to be deleted, which might be more than most people want to grant. – Larry Jun 14 '20 at 15:26
0
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                        "s3:GetBucketLocation",
                        "s3:ListAllMyBuckets"
                      ],
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::YOUR-BUCKET",
                "arn:aws:s3:::YOUR-BUCKET/*"
            ]
        }
    ]
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Rishikesh
  • 1
  • 2
0

Another way I was recently able to get this to work was using Amazon's documentation. The key for me was to point the IAM User to the specific bucket NOT the S3 console. Per the documentation, "Warning: After you change these permissions, the user gets an Access Denied error when they access the main Amazon S3 console. The main console link is similar to the following:

https://s3.console.aws.amazon.com/s3/home

Instead, the user must access the bucket using a direct console link to the bucket, similar to the following:

https://s3.console.aws.amazon.com/s3/buckets/awsexamplebucket/"

My policy is below:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "Stmt1589486662000",
        "Effect": "Allow",
        "Action": [
            "s3:*"
        ],
        "Resource": [
            "arn:aws:s3:::AWSEXAMPLEBUCKET",
            "arn:aws:s3:::AWSEXAMPLEBUCKET/*"
        ]
    }
]
}
JJAN
  • 777
  • 1
  • 7
  • 13