Accepted answer

There are two things to note:

  • Where to assign permissions for access to Amazon S3
  • Which permissions to assign

Where to assign permissions for access to Amazon S3

Objects in Amazon S3 are private by default. There are three ways to assign permission to access objects:

  • Object ACLs (Access Control Lists): These are permissions on the objects themselves
  • Bucket Policies: This is a set of rules applied to the bucket as a whole, but it can also specify permissions related to a subset of a bucket (eg a particular path within the bucket)
  • IAM Policies that are applied to IAM Users, Groups or Roles: These permissions apply specifically to those entities

If your intention is to keep the content of the S3 bucket private but allow access to a specific user, then you should assign permissions to the IAM User (as you have done). It also means that you do not require a Bucket Policy since granting access via any one of the above methods is sufficient.

See documentation: Guidelines for Using the Available Access Policy Options

Also a CORS Policy is only required if a HTML page served from one domain is referring to content from another domain. It is quite possible that you do not require the CORS Policy -- do some testing to confirm whether this is the case.

Which permissions to assign

This is always confusing... Some permissions are associated with the Bucket, while some permissions are associated with the contents of the Bucket.

The following permissions from your policy should be at the Bucket level (arn:aws:s3:::MyBucket):

  • s3:CreateBucket
  • s3:DeleteBucket
  • s3:DeleteBucketPolicy
  • s3:GetBucketPolicy
  • s3:GetLifecycleConfiguration
  • s3:ListBucket
  • s3:ListBucketMultipartUploads
  • s3:PutBucketPolicy
  • s3:PutLifecycleConfiguration

Other API calls (eg GetObject) should be at the object-level (eg arn:aws:s3:::MyBucket/*).

See: Specifying Permissions in a Policy

Therefore, the policy associated with your IAM User should look more like this:

    "Version": "2012-10-17",
    "Statement": [
            "Sid": "Stmt1",
            "Effect": "Allow",
            "Action": [
            "Resource": [
            "Sid": "Stmt2",
            "Effect": "Allow",
            "Action": [
            "Resource": [

This grants GetObject permission to objects within the bucket, rather than on the bucket itself.


Just if some body will face with the same problem - be sure that all files was uploaded to bucket, because if you use "Add files" button it does not upload nested folders. Better use "drag and drop".

Related Query

More Query from same tag