Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Bucket Policy Error: Policy has invalid action

I have a very basic goal: to share all content of my bucket to a list of specific users, read only. This used to work with a tool called s3cmd. All I need to do was to add a user (identified by email) to the Access Control List with Read Permission, and they could list or download data smoothly.

But recently, this suddenly did not work anymore. The system just denies any attempt to access my bucket.

I then started thinking of editing the bucket policy. Here is the draft of my policy, generated by the Policy Generator (sensitive information is anonymized):

    {
      "Id": "Policy123456789",
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "Stmt1512705836469",
          "Action": [
            "s3:GetObject",
            "s3:ListBucket",
            "s3:ListObjects"
          ],
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::mybucketname",
          "Principal": {
            "AWS": [
              "arn:aws:iam::anotheruserid:user/admin"
            ]
          }
        }
      ]
    }

When I click save, I get a "Policy has invalid action" error. I then tried to remove "ListObjects" so the policy becomes

    {
      "Id": "Policy123456789",
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "Stmt1512705836469",
          "Action": [
            "s3:GetObject",
            "s3:ListBucket"
          ],
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::mybucketname",
          "Principal": {
            "AWS": [
              "arn:aws:iam::anotheruserid:user/admin"
            ]
          }
        }
      ]
    }

and got another error message "Action does not apply to any resource(s) in statement".

These two errors do not make sense to me. Please correct me if I am wrong. If I am not in the right direction, please help me.

BTW: I tried to follow the tutorial at http://docs.aws.amazon.com/AmazonS3/latest/dev/example-walkthroughs-managing-access-example2.html but wasn't successful. By using the following bucket policy:

    {
       "Version": "2012-10-17",
       "Statement": [
          {
             "Sid": "Example permissions",
             "Effect": "Allow",
             "Principal": {
                "AWS": "arn:aws:iam::AccountB-ID:root"
             },
             "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket"
             ],
             "Resource": [
                "arn:aws:s3:::examplebucket"
             ]
          }
       ]
    }

I got an error message when using awscli of AccountB to execute "aws s3 ls s3://examplebucket".
The error message was "An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied".

This confuses me. If I add ListObjects, I got an "invalid" error.
If I remove the "ListObjects", another user could not read my bucket content.

What should I do?

like image 679
fanchyna Avatar asked Dec 08 '17 04:12

fanchyna


People also ask

Why am I getting the error invalid principal in policy when I try to update my Amazon S3 bucket policy?

You receive the "Error: Invalid principal in policy" message when the value of a Principal in your bucket policy is not valid. To resolve this error, confirm the following: Your bucket policy uses supported values for a Principal element. The Principal value is formatted correctly.

Why is my S3 bucket Access Denied?

If you're getting Access Denied errors on public read requests that are allowed, check the bucket's Amazon S3 Block Public Access settings. Review the S3 Block Public Access settings at both the account and bucket level. These settings can override permissions that allow public read access.


2 Answers

I suspect that the Policy Editor has become smarter when it comes to operations that operate on buckets as opposed to within buckets.

Also, ListObjects seems to be upsetting it, so leave it out.

This policy allows the contents of a bucket to be listed and objects retrieved:

{
    "Id": "Policy1",
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ],
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/user-name"
            }
        }
    ]
}

ListBucket operates on the Bucket.

GetObject operates on the contents of a bucket.

It could be written as two separate statements within the policy (one on the bucket, one on the contents of the bucket), but it's often easier to write it as above.

like image 92
John Rotenstein Avatar answered Sep 23 '22 11:09

John Rotenstein


There are two parts to granting bucket access to a user in another account.

  1. Set the correct policy on the bucket.
  2. Allow the IAM user in the other account to perform the necessary operations on the bucket.

This does seem redundant, but both are required.

Additionally, the ListObjects action is deceiving, especially as the awspolicygen tool also lists it as a permission. However in the documentation about S3 permissions you'll find that ListObjects is in fact an operation controlled by the ListBucket permission.

In the second example that you provide I suspect the reason you were unsuccessful was because the requesting user may not have the ListBucket privilege for your bucket. Additionally, I do believe the GetBucketLocation is not strictly required for your scenario, however if you want them to get items from the bucket you would need to grant GetObject privileges.

like image 30
JinnKo Avatar answered Sep 19 '22 11:09

JinnKo