AWS bucket policy statements priority order

3.6k Views Asked by At

I'm trying to restrict users access to my bucket using my bucket policy. I have a set of users, all of them have an S3FullAccess policy. I can't change anything in the IAM. I have only access to my bucket policy. So I want to control the user's access using the bucket policy. I'm splitting the users into 3 categories.

  1. Admin access to my bucket (All access to my bucket)
  2. User with limited access to my bucket (like get-bucket-policy, get-bucket-location)
  3. No access to my bucket. (No access to my bucket)

The below policy is the one I tried, but it is not working.

{
    "Version": "2012-10-17",
    "Id": "PolicyTesting",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<<account_id>>:user/users_with_limited_access"
            },
            "Action": [
                "s3:GetBucketPolicy",
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<<my_bucket_name>>",
                "arn:aws:s3:::<<my_bucket_name>>/*"
            ]
        },
        {
            "Sid": "1",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": "arn:aws:iam::<<account_id>>:user/admin_users"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::<<my_bucket_name>>",
                "arn:aws:s3:::<<my_bucket_name>>/*"
            ]
        }
    ]
}

I tried the above policy, but only the admin users alone can access the bucket. The users with limited access unable to perform their granted actions like get-bucket-policy, get-bucket-location.They are getting an Access Denied exception. Help me to resolve this.

2

There are 2 best solutions below

2
On

There is no priority order in AWS IAM policies. Please refer to the policy evaluation logic here.

The AWS enforcement code evaluates all policies within the account that apply to the request. If the code finds even one explicit deny that applies, the code returns a final decision of Deny.

Your current policy Deny all users except admin-users any S3 actions. Hence users_with_limited_access is unable to perform granted actions.

Please update your policy with the appropriate Principal(as per comments in your question) and refer to the updated policy below to make it work.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:user/s3-limited-access-user"
            },
            "Action": [
                "s3:GetBucketPolicy",
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::example-bucket",
                "arn:aws:s3:::example-bucket/*"
            ]
        },
        {
            "Sid": "2",
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:user/s3-no-access-user"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::example-bucket",
                "arn:aws:s3:::example-bucket/*"
            ]
        },
        {
            "Sid": "3",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:user/admin-user"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::example-bucket",
                "arn:aws:s3:::example-bucket/*"
            ]
        }
    ]
}
0
On

You should be very careful with NotPrincipal. It is the best practice to avoid using it all together. Most of the time it is very easy to achieve the same functionality (policy semantics) without using the "dangerous" NotPrincipal.

I think you are better off creating specific IAM roles and assign them to the corresponding user groups you want to allow accessing the S3 bucket. After that block all other access to the bucket with an explicit Deny for "Principal" : "*" and aws:userId or aws:PrincipalArn.

Have a look at this article for more details https://levelup.gitconnected.com/how-i-locked-the-whole-company-out-of-an-amazon-s3-bucket-1781de51e4be

Best, Stefan