How do I set AWS IAM permissions to “Deny all of wildcard X except Y”?

Viewed 1887

When managing other people's AWS accounts, I try to give users as open permissions as possible within reason.

Therefore I grant "Allow" to "ec2:*" but then limit them from doing dangerous actions with deny statements like "Deny ec2:*Vpn*" or "Deny ec2:Create*"

However, suppose I find an action that I don't want to deny, such as "ec2:DescribeVpnGateways". How do I omit this one statement and only this one statement from my "Deny" statement?

Note: "Deny ec2:*Vpn*" counts as an explicit deny, so any attempts to "Deny ec2:*Vpn*" and "Allow ec2:DescribeVpnGateways" simultaneously will result in the "Deny" rule overriding the "Allow" rule.

Note2: There exists an element of IAM Policies called "NotAction". This allows you to Deny all actions except for the one specified. If I were to use a "Deny: NotAction: ec2:DescribeVpnGateways" statement, this would deny every single AWS action except for "ec2:DescribeVpnGateways", which is much more destructive than what we are intending.

Note3: AWS does not allow you to combine "Action" and "NotAction" fields in the same policy statement.. It be really cool if we could and just use the intersection between both fields.

Does there even exist a means to solve this problem? Do I need to refactor my IAM to only give my users approved permissions up front instead of first giving them all permissions and denying them later?

1 Answers

Per AWS documentation, an explicit DENY will always override an explicit ALLOW. This is true regardless of whether the DENY and ALLOW are in different statements on the same policy, or in different policies attached to the same user/role.

The preferable approach is to explicitly allow the actions you want them to be able to take. Otherwise, when AWS implements new actions down the road, your user will be able to take those actions (even if they're very dangerous) since they're not in your DENY statement. As an example, imagine that AWS adds an ec2:DeleteAllInstances action at some point; since your statement doesn't explicitly deny this action, and you've allowed ec2:*, your users will be able to delete all instances.

EC2 is tough because there's a ton of different actions, but it really is much safer to explicitly state which actions should be allowed.

Related