skip to Main Content

I have an IAM user created with a policy for my bucket. With "public block access" enabled I can interact with the bucket as expected through this user.

Now I need to make a single public read-only folder using bucket policies, but I am not having any luck. I created the below policy which should

  • Disable all access to all principles
  • Enable all access for my IAM user
  • Enable read-only access to specific folders for all users.
{
  "Id": "Policy1676746531922",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1676745894018",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": "arn:aws:s3:::bucket/*",
      "Principal": "*"
    },
    {
      "Sid": "Stmt1676746261470",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucket/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::000000000:user/bucket-user"
        ]
      }
    },
    {
      "Sid": "Stmt1676746523001",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucket/read-only-folder",
      "Principal": "*"
    }
  ]
}

I guess you cannot layer up access in this way, but I am unsure how to construct what I need. If I go with a single read policy to open up one folder, I still seem to be able to access all other folders publically too:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket-name/public/*"
        }
    ]
}

I can access "/public" but can still access "/private" too.

I need a way first to lock down the entire bucket and then open up the folders I want to provide access for?

2

Answers


  1. Chosen as BEST ANSWER

    Buckets are "locked down" by default. There is no need to deny access to a bucket explicitly.

    Amazon suggests all new buckets are created with ACL disabled. This means that the bucket owner owns all files and file versions within a bucket by default.

    Access is granted to other users via bucket policies and user/IAM policies.

    In this use case, I want the bucket to be private apart from one file. We also have one IAM user who should have access to modify files within the bucket.

    Bucket Policy

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "GrantOperationAccessToIamUser",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::8000000000000:user/bucket-user"
                },
                "Action": [
                    "s3:GetBucketLocation",
                    "s3:ListBucket"
                ],
                "Resource": "arn:aws:s3:::bucket-name"
            },
            {
                "Sid": "GrantGetAccessToIamUser",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::8000000000000:user/bucket-user"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::bucket-name/*"
            }
        ]
    }
    

    In order to allow public read access to one folder (in this case the folder name is "public"), you can add the following:

    {
        "Sid": "AddPublicAccess",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:GetObject",
        "Resource":"arn:aws:s3:::bucket-name/public/*"
    }
    

    IAM User Inline Policy

    Finally the IAM user needs an inline policy attached to allow write access to the bucket:

    {
       "Version": "2012-10-17",
       "Statement": [
          {
             "Sid": "PermissionForObjectOperations",
             "Effect": "Allow",
             "Action": [
                "s3:PutObject"
             ],
             "Resource": [
                "arn:aws:s3:::bucket-name/*"
             ]
          }
       ]
    }
    

  2. Your policy is failing because Deny always overrides an Allow.

    The first statement in the policy will Deny access to the bucket for everyone (including you!).

    Your second policy on arn:aws:s3:::bucket-name/public/* is the correct way to go. It will only grant anonymous access to that particular folder.

    If you are able to access other folders, then either there are other policies that exist, or you are using "authenticated access" using your own AWS credentials. Make sure when you test it that you are putting a URL into a web browser that simply looks like: https://bucket-name.ap-southeast-2.s3.amazonaws.com/foo.txt

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search