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

105,667

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/

Solution 4

Try this policy. also take into account that there no way to let the user list only selected bucket. You can either list all buckets or none.

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:GetObjectAcl",
                "s3:PutObjectAcl",
                "s3:ListBucket",
                "s3:GetBucketAcl",
                "s3:PutBucketAcl",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::your_bucket_here/*",
            "Condition": {}
        },
        {
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*",
            "Condition": {}
        }
    ]
}

Solution 5

There is a great way to allow users to access a specific bucket without comprising knowledge of other buckets. A group policy that is like the one below will allow users to only see "bucket a". The only catch is that the user will only ever be able to access the bucket if they connect to the given bucket endpoint. For the example below that would be bucket-a.s3.amazonaws.com. The bucket may also have to have "Authenticated Users" allowed for this to occur.

{
    "Statement": [
     {
         "Sid": "<EXAMPLE_SID>",
         "Action": [
           "s3:ListBucket",
           "s3:GetBucketLocation"
          ],
         "Effect": "Allow",
         "Resource": [
           "arn:aws:s3:::bucket-a"
         ]
     },
     {
      "Sid": "<EXAMPLE_SID>",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::bucket-a/*"
      ]
     }
   ]
}

This method was tested with Cyberduck on Mac OS/X and using the s3cmd package

./s3cmd ls s3://bucket-a --access_key=ACCESS_KEY --secret_key=SECRET_KEY --bucket-locat
ion=ap-southeast-2
Share:
105,667
Alex
Author by

Alex

Updated on December 05, 2021

Comments

  • Alex
    Alex over 2 years

    I have a simple bucket that looks like images.mysite.com on my S3 and other buckets containing backups, etc.

    I want to allow a specific user to be able to access the images.mysite.com bucket in order to upload images. However, I DO NOT want him to see any of the other buckets; not even that they exist.

    I could not make a policy that does this; every time I try something restrictive, it ends up blocking the listing of any buckets.

  • Mike Repass
    Mike Repass almost 12 years
    This is a great answer, thank you. It might be worth noting that the implication of the s3:ListAllMyBuckets permission is that the recipient of this policy can see all of your (root's) buckets. There is no data disclosure directly, but there might be sensitivity/confusion around bucket names. It is feasible to remove this particular permission and things should still work (although "s3cmd ls" etc will not return the target bucket).
  • metdos
    metdos over 11 years
    This does not prevent the user to see other bucket names !
  • Michael Yagudaev
    Michael Yagudaev over 11 years
    It works great! I had to do change action to be s3:* to get it to work for me. I also had "Resource": ["arn:aws:s3:::your_bucket_here", "arn:aws:s3:::your_bucket_here/*"], but this might not be needed.
  • fnkr
    fnkr about 11 years
    I wanted go get a policy that only allows uploading (in my case via the S3-PHP-API) so PutObject and PutObjectAcl was enough for me. I also wanted to allow the upload permission only to a specific bucket and folder so I set resource to arn:aws:s3:::BUCKET/FOLDER/*. Working perfect for me.
  • MZB
    MZB almost 11 years
    +1 I simplified the action in the second statement (which allows access to the bucket content) to "Action": "s3:*". The s3:ListAllMyBuckets section may not be required in all circumstances - jgit, for example, doesn't need it.
  • O.O
    O.O about 10 years
    @metdos you can prevent users to see other bucket names by removing the last policy.
  • Joshua Kolden
    Joshua Kolden about 10 years
    @HendraUzia No it doesn't. Removing that policy causes the console to list no buckets at all.
  • jwadsack
    jwadsack about 10 years
    In order to see the list of buckets in the console (and therefore use the console for bucket access) you must grant ListAllMyBuckets and GetBucketLocation for all S3 buckets ("arn:aws:s3:::*" will work rather than "*" for the resource). As stated in this AWS blog post "as an aside, you currently can't selectively filter out certain buckets, so users must have permission to list all buckets for console access."
  • djburdick
    djburdick over 9 years
    Note: change "itnighq" to your bucket name. I didn't catch that at first look. Otherwise works well for me.
  • peter n
    peter n about 9 years
    Worked great for me, remember to add the "Version" string in the root JSON object, else it wont validate: docs.aws.amazon.com/IAM/latest/UserGuide/…
  • bradw2k
    bradw2k about 9 years
    Both s3:ListAllMyBuckets and s3:GetBucketLocation are required on resource arn:aws:s3:::* in order for end users to use the client program ExpanDrive (which has a nice interface that treats S3 as a drive on PC or Mac). Some other client programs, such as CyberDuck, seem to be fine with only s3:ListAllMyBuckets on arn:aws:s3:::*.
  • MaximeBernard
    MaximeBernard over 8 years
    AWS responding: This policy contains the following error: The policy must contain a valid version string
  • jjanczyszyn
    jjanczyszyn over 8 years
    that's right - I corrected my response -><br/> there are only two possible values here: <br/>*2012-10-17* and 2008-10-17. <br/>Further reference can be found here: <br/>docs.aws.amazon.com/IAM/latest/UserGuide/…
  • MaximeBernard
    MaximeBernard over 8 years
    Any idea about the (listing included) meaning how to list only the bucket the user is allowed to get in? So far (and according to all other answers), it seems like AWS won't let you do that.
  • Jamie Popkin
    Jamie Popkin over 7 years
    This works well. Would be optimal if users couldn't explore outside the bucket view.... But I'll take it. Thanks @BFar.
  • Andy Fusniak
    Andy Fusniak about 7 years
    Also, for Solution (1) if you want to use web hosting with a bucket then the bucket name must match the domain name.
  • AndreKR
    AndreKR about 7 years
    This is horrible advice. It's dangerous and specifically what the OP didn't want. See the answers by Andreas Stankewitz and BFar for feasible workarounds.
  • Ondrej Galbavý
    Ondrej Galbavý over 6 years
    You should explicitly grant access to resources. When you default grant access to all resources, you can accidentally omit resources you want to keep private. Also granting access to all S3 actions means user can make resources public or setup static hosting or do other harmful things.
  • Dave Gregory
    Dave Gregory over 6 years
    s3:* grants access to do anything, including delete a bucket. Sure you want that?
  • Saurabh
    Saurabh almost 6 years
    I think this is the only feasible solution in 2018 also.
  • Steve Horvath
    Steve Horvath about 5 years
    This is the ONE CORRECT answer, all the others will list every bucket - that should be hidden as per the original request.
  • dzhg
    dzhg about 5 years
    Exactly what I need. Thanks.
  • Rishikesh Chandra
    Rishikesh Chandra over 4 years
    I can still see the list of all buckets. Not working :(
  • Rishikesh Chandra
    Rishikesh Chandra over 4 years
    I can still see the list of all buckets. Not working :(
  • Yevgeniy Afanasyev
    Yevgeniy Afanasyev almost 3 years
    This policy contains the following error: A managed policy must have a version string For more information about the IAM policy grammar, see AWS IAM Policies
  • Jrm_FRL
    Jrm_FRL over 2 years
    This answer does not fill the questioner's need. Don't understand why it has so many upvotes.