EC2, S3 & IAM Policy Evaluation
22 min
AWS IAM (Identity and Access Management) controls who can do what
across every AWS service. Its evaluation logic follows one precise
rule: by default, everything is denied; an Allow statement grants
access; but an explicit Deny ALWAYS wins, overriding any Allow
granted anywhere else. This absolute-priority deny is what lets a
narrow security rule (e.g. "deny if outside the corporate VPN")
reliably override broader permissions granted by other policies,
without needing to know or edit every other policy that might apply.
def evaluate_policies(policies, action):
decision = "deny"
for policy in policies:
if policy["action"] == action:
if policy["effect"] == "deny":
return "deny"
if policy["effect"] == "allow":
decision = "allow"
return decision
This is exactly why security teams reach for a narrow explicit Deny to lock something down FAST -- they don't need to hunt down and edit every Allow statement scattered across a dozen other IAM policies that might grant the same action; one Deny statement anywhere wins outright.
Write `evaluate_policies(policies, action)`: `policies` is a list of `{'effect': 'allow'|'deny', 'action': action_name}` dicts. Any matching `'deny'` immediately wins (return `'deny'` right away). Otherwise, return `'allow'` if at least one matching `'allow'` was found, else `'deny'` (default deny).
AWS IAM's evaluation logic is: default deny, any matching Allow grants access, but an explicit Deny ALWAYS overrides any Allow. Why give Deny that absolute priority?
You can evaluate a set of IAM-style policies with explicit-deny-wins semantics, the real access control model AWS uses across every service.