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

amazon s3amazon-iam

I have the following IAM policy for a user

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

The goal is to let the user upload files to the bucket, but not overwrite or delete. It's for backup. I started out with ListBucket and PutObject, but added * as it didn't work. Not even * lets the user upload files, just getting Access Denied.

When I try the Simulator, it returns Denied - Implicitly denied (no matching statements found). for ListBucket, which seems odd since I've implicitly allowed that.

I've tried both Cyberduck and 3Hub as S3 clients.

Any idea what's wrong?

Best Answer

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/*"
      ]
    }
  ]
}
Related Topic