Is there an S3 policy for limiting access to only see/access one bucket?

Solution 1:

I've been trying this for a while and finally came up with a working solution. You must use different "Resources" depending on the kind of action you're performing. Also I included some missing actions in the previous answer (like DeleteObject) and restricting some more (like PutBucketAcl).

The following IAM policy is working for me now:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads"
      ],
      "Resource": "arn:aws:s3:::itnighq",
      "Condition": {}
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:AbortMultipartUpload",
        "s3:DeleteObject",
        "s3:DeleteObjectVersion",
        "s3:GetObject",
        "s3:GetObjectAcl",
        "s3:GetObjectVersion",
        "s3:GetObjectVersionAcl",
        "s3:PutObject",
        "s3:PutObjectAcl",
        "s3:PutObjectVersionAcl"
      ],
      "Resource": "arn:aws:s3:::itnighq/*",
      "Condition": {}
    },
    {
      "Effect": "Allow",
      "Action": "s3:ListAllMyBuckets",
      "Resource": "*",
      "Condition": {}
    }
  ]
}

The actions regarding a bucket and those regarding objects must have different arn.

Solution 2:

Our use case: Provide backup space for clients of our cloud application that can be accessed by the clients directly using common S3 tools. Of course, no client should see what other clients have.

As cloudberryman explained, "You can either list all buckets or none.", so we have to come up with a work around. Background:

Granting ListAllMyBuckets rights to the user is needed so that AWS S3 console or S3Fox connect without an error message. But ListAllMyBuckets lists all buckets, regardles of the resources assigned (actually, only arn:...:::* works). That's a serious bug, if you ask me. Btw. denying ListBucket for all buckets does not prevent them from being listed, as ListBucket grants rights to list the bucket's content.

There are 3 possiblities I considered as work around. I chose the last one.

(1) use cryptic bucket names, e.g. GUIDs

Advantage: easy to set up

Disadvantage: difficult to manage, especially for the client. (imagine to find a specific GUID amoung thousands of others.) Also shows of the number of buckets = number of clients using the backup service.

(2) use one bucket with client specific folders

This is how Amazon suggests by their S3/IAM examples to provide space to access only by certain users or user groups. See: AWS Example IAM Policies

Advantage: fairly easy to set up, goes with AWS ideas

Disadvantage: forces to make the existance of all buckets public, so the client can find their "home" bucket. AWS accounting provides statistics of bucket usage, but not of folder usage, which makes it difficult to calculate cost by client.

(3) don't grant access right for ListAllMyBuckets

Advantage: you get what you want: clients can't see other client's buckets

Disadvantage: the client can't see his or her own bucket. S3Browser comes with a nice "cannot do" message and asks for the bucket name to enter. S3Fox throws an error message when connecting to the root, but allows direct navigation to the client's bucket if the bucket name is known. Amazon S3 console does not work at all.

Hope this helped to handle S3 IAM as you need it.

Solution 3:

It is not possible to provide access to the S3 Console without granting the ListAllMyBuckets permission.

In my case (and perhaps yours as well, future reader) an acceptable alternative is to redirect users on sign in directly to the bucket you would like them to see.

To accomplish this, append the following to your IAM sign in url: /s3/?bucket=bucket-name

Full Sign-in URL (replace your-alias and bucket-name):

https://your-alias.signin.aws.amazon.com/console/s3/?bucket=bucket-name

IAM Policy (replace bucket-name):

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::bucket-name",
                "arn:aws:s3:::bucket-name/*"
            ]
        }
    ]
}

For more information on how to create bucket specific permissions for users, read this blog: http://mikeferrier.com/2011/10/27/granting-access-to-a-single-s3-bucket-using-amazon-iam/