not_actions vs explicit deny & allow statements in an IAM policy

Viewed 244

Policy 1:

data "aws_iam_policy_document" "kms_policy" {
  statement {
    sid = "AllowEKSKMSAccess"
    actions = [
      "kms:*"
    ]
    not_actions = [
      "kms:Delete*",
      "kms:ScheduleKeyDeletion",
      "kms:Revoke*",
      "kms:Disable*",
    ]
    resources = ["*"]
  }
}

Policy 2:

data "aws_iam_policy_document" "kms_policy" {
  statement {
    sid = "AllowEKSKMSAccess"
    effect = "Allow"
    actions = [
      "kms:*"
    ]
    resources = ["*"]
  }

  statement {
    sid = "DenyEKSKMSDeletion"
    effect = "Deny"
    actions = [
      "kms:Delete*",
      "kms:ScheduleKeyDeletion",
      "kms:Revoke*",
      "kms:Disable*",
    ]
    resources = ["*"]
  }
}

I want to prevent 4 actions from within the role associated with a managed EKS node group.

Is policy 1 or policy 2 the preferred policy?

Is it better to have explicit deny statements (along with allow statements) in the same policy?

2 Answers

Is policy 1 or policy 2 the preferred policy?

Policy 2.

Is it better to have explicit deny statements (along with allow statements) in the same policy?

Yes - if you want to deny any IAM actions, always prefer explicit deny policies.

An explicit deny in any policy overrides any allows.

As long as the original deny policy is protected from changes, any new policies added that attempt to allow the unwanted actions will not work.

However, when using not_actions with the allow effect, any new policies added to allow the unwanted actions will actually reverse the effect of the original policy & will allow the undesired actions. With no explicit deny, there is nothing stopping someone else from adding an explicit allow (most of the time).

The 2nd policy is always preferred.

I only use not_actions when I want to deny a lot of things to make the resulting IAM policy smaller, as I know it is guaranteed to be future proof if the policy is well-secured.

None, create IAM Policies:

  • with Allow effect where you have the list of precise Actions, because you can always allow more than you should with wildcard *, don't be lazy especially when you have AWS tools like IAM Policy Simulator
  • with explicit ARNs for Resources (at least precise the account), avoid [*]

Since you are using Terraform, you have tools like Checkov for analyzing your code and giving you best practice tips.

Related