How to let user upload files to S3 bucket, but not overwrite or delete?

Solution 1:

When crafting Amazon IAM policies for Amazon S3, you need to be aware of the difference between Operations on the Service (e.g. ListAllMyBuckets), Operations on Buckets (e.g. ListBucket) and Operations on Objects (e.g. GetObject).

In particular, the Resource specification of your policy needs to address the appropriate target entities according to the following patterns (see e.g. the various Example Policies for Amazon S3):

  • Operations on Service - arn:aws:s3:::*
  • Operations on Buckets - arn:aws:s3:::<bucket>
  • Operations on Objects - arn:aws:s3:::<bucket>/<object>

Solution

You are encountering Access Denied, because you've specified a bucket level resource for PutObject, which requires an object level resource specification like arn:aws:s3:::<bucket>/* - accordingly, the following policy should cover your sample use case:

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