Prove that explicit IAM Deny wins
📑 On this page
Part 108 of AWS from Zero. This lesson changes or inspects one IAM concept so the permission model stays understandable.
What we are learning
An applicable explicit deny overrides allows from identity policies and resource policies.
Before you run it
aws sts get-caller-identity
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
USER_NAME="aws-zero-learner"
GROUP_NAME="aws-zero-readers"
ROLE_NAME="aws-zero-demo-role"IAM is global rather than regional. Use a sandbox account and a delegated administrator identity, never root access keys.
The command
cat > explicit-deny.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{"Effect": "Allow", "Action": "s3:*", "Resource": "*"},
{"Effect": "Deny", "Action": "s3:DeleteObject", "Resource": "arn:aws:s3:::example/*"}
]
}
EOF
aws iam simulate-custom-policy \
--policy-input-list file://explicit-deny.json \
--action-names s3:GetObject s3:DeleteObject \
--resource-arns arn:aws:s3:::example/report.txtIAM writes can take a short time to propagate. Inspect the resource after every change.
Inspect the result
aws iam simulate-custom-policy \
--policy-input-list file://explicit-deny.json \
--action-names s3:GetObject s3:DeleteObject \
--resource-arns arn:aws:s3:::example/report.txt \
--query "EvaluationResults[].{Action:EvalActionName,Decision:EvalDecision}" \
--output tableGetObject should be allowed and DeleteObject explicitly denied.
One tiny variation
sed '/"Effect": "Deny"/d' explicit-deny.jsonDo not use this invalid edit as a policy; it simply highlights that statement structure matters.
Common mistake
Permission simulation is valuable but cannot reproduce every service-specific or organization context. Confirm with controlled integration tests.
Cleanup
rm explicit-deny.jsonOnly a local simulation policy was created.
Next, we will learn Simulate an IAM principal policy.