Alexandre Thenorio
Alexandre Thenorio

Reputation: 2418

How to deny s3 bucket access for an AWS account

I have an AWS account with ID 11111 and I would like to deny access to certain parts of an s3 bucket to the same account the bucket belongs to, even if the role accessing that object has full s3 access.

It is my understanding that setting a DENY rule on a s3 bucket policy should do that, so I tried the s3 policy below

{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::111111:root" }, "Action": [ "s3:PutObject", "s3:GetObjectVersion", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::mybucket/production/*" ] } ] }

However an ec2 machine in the same account as the s3 bucket with an iam role to allow full access to the bucket (s3:*) is still able to write/read to mybucket/production/*

Am I missing something? Shouldn't the DENY bucket rule take precedence? How does one handle this situation? I want to avoid having to remove the full access from the ec2 role but rather be able to deny on top of that.

Upvotes: 3

Views: 1916

Answers (4)

sudo
sudo

Reputation: 2327

I believe the following is going on here:

  1. The account 111111 owns the S3 bucket and the IAM entity (in this case an IAM role).

  2. Since, the request is being made from an IAM role in the same account (bucket owner), S3 will only check the "User Context".

  3. While evaluating the "User Context", S3 will take into account:

    • Policies attached to the IAM role
    • Bucket policy
    • Bucket and Object ACL (if any)
  4. The request is allowed via the IAM role's permission policy and there is no explicit Deny for the IAM Role because the Principal in the bucket policy is actually for the "Root User" and NOT covering the IAM entities in 111111 account since both accounts (bucket owner and 111111) are same.

I tested this and using the similar policy my Root user cannot delete or upload objects into the bucket. However, root can gain access by deleting the bucket policy.

As @John Hanley mentioned, you can use the IAM role's as a principal to deny access in production "folder" but as the role has S3fullaccess, it can delete the bucket policy, so I'd recommend to deny that capability also.

Upvotes: 1

bdrx
bdrx

Reputation: 943

I ran into this same problem and have not yet determined why just denying the root principal doesn't work. I have, however, found a solution which is to add a condition to the statement that compares against the userid field as seen in this knowledge center guide: https://aws.amazon.com/premiumsupport/knowledge-center/explicit-deny-principal-elements-s3/

You first have to determine the magical unique id of the IAM user.
Then add a statement to the policy that specifies the wildcard principal * and adds a condition to filter by the "aws:userid" field of the request like (replace AROAID2GEXAMPLEROLEID with the determined unique id):

{
   "Sid": "",
   "Effect": "Deny",
   "Principal": "*",
   "Action": [
      "s3:PutObject",
      "s3:GetObjectVersion",
      "s3:GetObject",
      "s3:DeleteObject"
   ]
   "Resource": [
      "arn:aws:s3:::mybucket/production/*"
   ],
   "Condition": {
      "StringLike": {
         "aws:userid": [
            "AROAID2GEXAMPLEROLEID:*",
            "111111"
         ]
      }
   }
}

Amazon supports partial wildcards for the actions and arns in the resource field. I don't know why Amazon makes this so complicated instead of just adding support for a partial wildcards in the principle field to allow simple straight forward configuration like

"Principal": {
   "AWS": "arn:aws:iam::111111:*"
},

Upvotes: 0

Asdfg
Asdfg

Reputation: 12213

See if this works. Since you are giving full access, you need to explicitly deny access. Below policy says deny access if user is not alloweduser or role is not allowedrole. This should also prevent non-authorized users/roles to delete bucket policy. I have not tested it yet.

{
                "Id": "DenyAllAllowOnlyOne",
                "Statement": [
                        {
                                "Action": "s3:*",
                                "Effect": "Deny",
                                "NotPrincipal": {
                                        "AWS": [
                                    "arn:aws:iam::111111:user/alloweduser",
                                    "arn:aws:iam::111111:role/allowedrole"

                                        ]
                                },
                                "Resource": [
                                        "arn:aws:s3:::mybucket/production",
                                        "arn:aws:s3:::mybucket/production/*"
                                ]
                        }
                ],
                "Version": "2012-10-17"
        }

Upvotes: 0

John Hanley
John Hanley

Reputation: 81356

I have not actually tested this.

Your S3 policy is limiting access for IAM users. Your goal is to limit access for services and / or roles that services assume.

To deny access to all EC2 instances, add another rule and specify the principal as (or add to your existing Principal entries):

"Principal": {"Service": "ec2.amazonaws.com"}

To limit access to a specific role that EC2 assumes:

"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:role/role-name" }

Upvotes: 0

Related Questions