S3 bucket policy – Action does not apply to any resource in statement

Background

In this post, I will address a common question about how to write an AWS Identity and Access Management (IAM) policy to grant read-write access to an Amazon S3 bucket. Doing so helps you control who can access your data stored in S3.

In my program, I tried to list the objects under a bucket

AWSCredentials awsCredentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretKey);
AmazonS3 s3client = new AmazonS3Client(awsCredentials);
ObjectListing objectListing = s3client.listObjects(bucketName, namespace + "/" + playerId + "/");

However, I received the following error from AWS

<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>2608DA4E3B4BC07C</RequestId><HostId>JlHSUCO6gGBdzHoRZzRst6sa78a42KtP1L8hmpWJ+fMFfQzpvcwUBU52P3jYffCQMXp8EeGf6O0=</HostId></Error>

This type of error usually means you do not have a valid S3 Bucket Policy in place.

Solution

You can use the AWS Policy Generator to generate a Bucket Policy. There are several examples online and Amazon has some examples
http://awspolicygen.s3.amazonaws.com/policygen.html

  • Select “S3 Bucket Policy”
  • Set the “Effect” to “Allow”
  • Under “Actions” check off “GetObject”
  • Set the Amazon Resouce Name (ARN) to “arn:aws:s3:::<bucket_name>/<key_name>“, in this case the Bucket name is bucket01 the key is usually set to *
  • Press “Add Statement”

  • Press Generate Policy. This will generate the policy you will need to add to your bucket
  • Copy the policy into your clipboard

  • Open your bucket in the AWS Management Console: http://aws.amazon.com/console/
  • Go to Amazon S3=>The bucket (in my case it’s “posttestasset”)=>Permissions=>Bucket Policy
  • Paste the policy json into the text-area and click “Save”

New Problem

It throws me error “Action does not apply to any resource(s) in statement”

The root cause is the wrong resource defined in the json policy file

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

Root cause

  • s3:GetObject applies to the objects in the bucket so the Resource is correct: “Resource”: “arn:aws:s3:::posttestasset/*”.
  • s3:ListBucket applies to the Bucket itself and so the Resource should be “Resource”: “arn:aws:s3:::posttestasset”

The correct policy should look like

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

Once I fixed that, the bucket policy can be saved correctly

(Visited 326 times, 4 visits today)

Leave a Reply