6

I've tried pretty much every possible bucket policy. Also tried adding a policy to the user, but I get Access Denied every time I try to download an object from s3 bucket using the AWS Console.

Bucket Policy:

{
    "Version": "2012-10-17",
    "Id": "MyPolicy",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::12345678901011:user/my-username"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::my-bucket/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "XX.XXX.XXX.XXX/24",
                        "XXX.XXX.XXX.XXX/24"
                    ]
                }
            }
        }
    ]
}

That doesn't work so I tried adding a policy to my-username:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "StmtXXXXXXXXXX",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ]
        }
    ]
}
Scott Decker
  • 4,229
  • 7
  • 24
  • 39
  • 1
    Can you list the objects via the console, but just not download them? How were the objects originally loaded into the bucket? Were they copied there via the CLI? – John Rotenstein Aug 16 '17 at 04:56
  • @JohnRotenstein process: application PUTs an object in the bucket. I refresh the console and I see it appear. I select it and click "Download". I get put on an ugly page that says Access Denied. If I upload an object manually thru the console, I can then immediately download it. – Scott Decker Aug 16 '17 at 05:43

2 Answers2

16

As strange as it sounds, it is possible to upload an object to Amazon S3 that the account owning the bucket cannot access.

When an object is uploaded to Amazon S3 (PutObject), it is possible to specify an Access Control List (ACL). Possible values are:

  • private
  • public-read
  • public-read-write
  • authenticated-read
  • aws-exec-read
  • bucket-owner-read
  • bucket-owner-full-control

You should normally upload objects with the bucket-owner-full-control ACL. This allows the owner of the bucket access to the object and permission to control the object (eg delete it).

If this permission is not supplied, then they cannot access nor modify the object.

I know that it contradicts the way you'd think buckets should work, but it's true!

How to fix it:

  • Re-upload the objects with bucket-owner-full-control ACL, or
  • The original uploader can loop through the objects and do an in-place CopyObject with a new ACL. This changes the permissions without having to re-upload.

UPDATE: In November 2021, a new feature was released: Amazon S3 Object Ownership can now disable access control lists to simplify access management for data in S3. This avoids the need to specify object ownership and fixes most problems with object ownership.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • 2
    Shouldn't there be a way for me to have a bucket or user policy that just says "regardless of how uploaded, this user has permissions to download anything from this bucket"? – Scott Decker Aug 16 '17 at 18:16
  • If the objects were uploaded without Bucket Owner permissions, it's not possible. I know -- it's strange! – John Rotenstein Aug 16 '17 at 18:25
  • Thanks! I found these articles to be helpful: http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html and http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html. In the end I just did a restRequest.AddHeader("x-amz-acl", "bucket-owner-full-control") and that solved it. – Scott Decker Aug 17 '17 at 20:16
  • Is it possible to upload several ACL records here? For example, I want to make the object public-read ad well as bucket-owner-full-control. – Thunder Cat King May 07 '19 at 15:40
  • @BritGwaltney No, it seems you can only specify one ACL. For details of what they define, see: [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) For details of ownership, see: [Amazon S3 Bucket and Object Ownership](https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-overview.html#about-resource-owner) – John Rotenstein May 07 '19 at 20:49
  • @JohnRotenstein This is very helpful, I'm still facing this permission issue from other account uploads even with `bucket-owner-full-control` applied if the GetObject is taking place through S3 static website (http) calls. Any help is much appreciated... my question .... https://stackoverflow.com/questions/72036463/s3-website-cross-account-permissions-not-working – Rino Bino Apr 28 '22 at 18:31
  • @RinoBino You might want to [Disable ACLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) on the bucket, which will remove the need to specify an ACL. – John Rotenstein Apr 28 '22 at 21:57
  • @JohnRotenstein yep that works fine, but many S3 clients (including Ansible and Aptly - both I'm using) cannot push objects to S3 without ACL set (throws AccessControlListNotSupported error response from API when doing PutObject). This is because disabled ACL's is relatively new and not all the client SDK's are updated. Appreciate the help, if you have any other ideas or could check out my question it would mean the world to me. Totally stuck. – Rino Bino Apr 28 '22 at 22:26
  • @RinoBino Feel free to create a new Question with full details and somebody should be able to assist. Include the interesting details you mentioned above. – John Rotenstein Apr 28 '22 at 22:39
  • @JohnRotenstein Oh trust me I did hehe, link was in my original comment above :) https://stackoverflow.com/questions/72036463/s3-website-cross-account-permissions-not-working – Rino Bino Apr 28 '22 at 23:11
2

You can solve it by using : http://docs.aws.amazon.com/cli/latest/reference/s3api/put-object-acl.html

put-object-acl : This has to be done by original uploader.

But is definitely faster than copying data again.

I had TB's of data to deal with.

aws s3api put-bucket-acl --bucket $foldername --key $i --grant-full-control uri=http://acs.amazonaws.com/groups/global/AllUsers
t j
  • 7,026
  • 12
  • 46
  • 66
Palak Sukant
  • 123
  • 2
  • 9