A cloud security engineer running a quarterly access review pulls up a role tied to a backup Lambda function. The policy looks right at first glance: two actions, s3:GetObject and s3:PutObject, nothing broader. Someone clearly tried to do this properly. Then the Resource line reads "*", and the review stops being routine. That role can touch every object in every bucket in the account, not the one backup bucket it was written for. Nobody meant for that to be true. The policy just never said otherwise.
IAM doesn't grant anything by default. Every request starts denied, and it stays denied unless something explicitly allows it: an identity policy, a resource policy, or both. Scoping actions without scoping resources is the most common way "least privilege" quietly isn't: the action list narrows what the role can do, but a wildcard resource means it can do it everywhere that action exists. The fix is mechanical once you know to look for it: resource ARNs scoped as specifically as the actions sitting next to them, not the other way around.
The part that actually matters during an incident is what happens when two policies disagree. An explicit Deny beats every Allow in the evaluation, no matter which policy it's written in and no matter how permissive the other one is: an identity policy granting AdministratorAccess loses to a single explicit Deny sitting in a permissions boundary or a service control policy. That's not a technicality, it's the one lever that actually works as a hard backstop. If there's an action or a resource prefix that must never be reachable no matter what some future policy grants, an explicit Deny is the only thing that survives a mistake made later by someone who didn't know it existed. A permissions boundary uses that same mechanic proactively: it doesn't grant a single permission on its own, it just caps what an identity policy is allowed to grant, which is exactly what stops a wildcard resource like the one above from ever mattering in production if the boundary was set correctly when the role was created.
None of this shows up until someone goes looking, which is what makes access reviews the place mistakes like this actually get caught instead of exploited. Knowing to check the resource field, not just the action list, and knowing that Deny always wins, is the difference between a review that rubber-stamps a policy because the action names sound right and one that catches the gap before someone else finds it first. The Cloud Security Engineer Handbook works through IAM policy evaluation, permissions boundaries and incident response across both AWS and Azure end to end, which is the actual depth behind catching this kind of thing on sight instead of after it's been used: https://resources.codelivly.com/product/the-cloud-security-engineers-handbook/
Top comments (0)