Repository: aws/aws-cli

Issue:
Put - Access Denied with s3:PutObject policy
I have the following policy for my instance role:

``` json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::foo/bar/*"
      ],
      "Effect": "Allow"
    }
  ]
}
```

If I try to

```
aws --region=eu-west-1 s3 cp --acl public-read ./baz s3://mybucket/foo/bar/baz
```

Then I get:

```
upload failed: ./baz to s3://mybucket/foo/bar/baz A client error (AccessDenied) occurred when calling the PutObject operation: Access Denied
```

If I change the policy to allow `s3:*` rather than just `PutObject`, the it works. It doesn't work if I add `ListObject`.

Any ideas?

```
aws-cli/1.3.4
boto==2.9.6
botocore==0.38.0
```



Discussion:
I think this might be our bug. I wasn't aware of the need for a `PutObjectAcl` role. It might be helpful if the [documentation](http://docs.aws.amazon.com/cli/latest/reference/s3/cp.html) said which were needed.

This appears to work:

``` json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": [
        "arn:aws:s3:::foo/bar/*"
      ],
      "Effect": "Allow"
    }
  ]
}
```

Well, I'll reopen this issue for thought because the error message was unhelpful. It could have told me that it was doing a `PutObjectAcl` or something when it failed.

+1

I had the same problem and I solved it adding `PutObjectAcl`. The error message isn't helpful.

+1

Thanks for this issue! That solved it for me as well. A better error message would be helpful, though.

I think our best bet here would be to update our documentation.  Part of the problem from the CLI side is that we don't actually know why the request failed.  The error message we display is take directly from the XML response returned by S3:

```
<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>id</RequestId>
  <HostId>id</HostId>
</Error>
```

So this could fail because of the missing `PutObjectAcl`, or could be that the resource you're trying to upload to isn't specified in the `"Resource"` in your policy.  The CLI can't know for sure.

Leaving this open and tagging as documentation so we'll get all the s3 docs updated with the appropriate policies needed.

+1 of PutObjectAcl being the culprit of much pain in my deployment as well

+1

+1

To summarize, this issue happens when you try to set an ACL on an object via the `--acl` argument:

```
Given:

            "Action": [
                "s3:PutObject"
            ],

# This works:
$ aws s3 cp /tmp/foo s3://bucket/

# This fails:
$ aws s3 cp /tmp/foo s3:/bucket/ --acl public-read
upload failed: ../../../../../../../tmp/foo to s3://bucket/foo A client error (AccessDenied) occurred when calling the PutObject operation: Access Denied

```

Given my [previous comment](https://github.com/aws/aws-cli/issues/813#issuecomment-69804892), I'd propose updating the documentation for `--acl` to mention that you need `"s3:PutObjectAcl"` set if you're setting this param.

Thoughts? cc @kyleknap @mtdowling @rayluo @JordonPhillips 


Resolving patch:
diff --git a/awscli/customizations/s3/subcommands.py b/awscli/customizations/s3/subcommands.py
--- a/awscli/customizations/s3/subcommands.py
+++ b/awscli/customizations/s3/subcommands.py
@@ -122,7 +122,10 @@
                    'bucket-owner-full-control', 'log-delivery-write'],
        'help_text': (
            "Sets the ACL for the object when the command is "
-           "performed.  Only accepts values of ``private``, ``public-read``, "
+           "performed.  If you use this parameter you must have the "
+           '"s3:PutObjectAcl" permission included in the list of actions '
+           "for your IAM policy. "
+           "Only accepts values of ``private``, ``public-read``, "
            "``public-read-write``, ``authenticated-read``, "
            "``bucket-owner-read``, ``bucket-owner-full-control`` and "
            "``log-delivery-write``.")}


Test patch: