DEV Community

Shieldly
Shieldly

Posted on • Originally published at shieldly.io

AWS IAM NotAction vs Deny: The Misread Statement That Grants Everything

Originally published at shieldly.io/blog.

NotAction is one of the most misunderstood IAM elements. Its name suggests denial but it does not deny anything. When paired with Effect: Allow, it grants access to every action in all of AWS except the ones you listed.

What NotAction Actually Means

NotAction inverts the Action element. Instead of listing what a statement covers, you list what it excludes — and the statement covers everything else.

{
  "Effect": "Allow",
  "NotAction": ["iam:*", "sts:*"],
  "Resource": "*"
}
Enter fullscreen mode Exit fullscreen mode

This allows every action across every AWS service except IAM and STS. That includes s3:DeleteObject, ec2:RunInstances, rds:CreateDBSnapshot, lambda:InvokeFunction, and everything else. The author almost certainly meant to restrict IAM access — they accidentally granted everything else.

The One Legitimate Use Case

NotAction with Effect: Deny is the one safe pattern. It is commonly used in Service Control Policies to create a "deny all except break-glass" control:

{
  "Effect": "Deny",
  "NotAction": [
    "iam:CreateLoginProfile",
    "sts:AssumeRole"
  ],
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:PrincipalArn": "arn:aws:iam::123456789012:role/BreakGlassRole"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This denies everything except the listed break-glass actions, for everyone except the break-glass role.

How to Rewrite the Dangerous Pattern

If you wrote NotAction + Effect: Allow trying to deny specific actions, replace it:

Instead of this (grants everything except IAM):

{
  "Effect": "Allow",
  "NotAction": "iam:*",
  "Resource": "*"
}
Enter fullscreen mode Exit fullscreen mode

Write this (allows only what you need):

{
  "Effect": "Allow",
  "Action": ["s3:GetObject", "s3:PutObject"],
  "Resource": "arn:aws:s3:::my-bucket/*"
}
Enter fullscreen mode Exit fullscreen mode

Then add an explicit Deny for anything you want blocked:

{
  "Effect": "Deny",
  "Action": "iam:*",
  "Resource": "*"
}
Enter fullscreen mode Exit fullscreen mode

Effect: Deny with an explicit action list is not the same as NotAction Allow — the former creates a hard deny, the latter creates a broad allow. They are opposite things.


Catch IAM statement mistakes automatically — paste a policy into Shieldly's free AI-Powered analysis. No signup, no credit card.

Launch offer: code 90Off2M — 90% off first 2 months. Pro from $1.90/mo. shieldly.io/pricing

Top comments (0)