AWS IAM Policy Evaluation Logic: How Are Allow and Deny Decisions Made?
IAM policies are evaluated in order: Explicit Deny > Explicit Allow > Implicit Deny. Learn JSON policy writing, permissions boundaries, and SCP essentials for SAA-C03.
Related Exam Domains
- Domain 1: Design Secure Architectures
Key Takeaway
IAM policy evaluation follows "Explicit Deny > Explicit Allow > Implicit Deny" order. Any explicit Deny in any policy overrides all Allow statements. All actions not explicitly mentioned in policies are denied by default.
Exam Tip
Exam Essential: Explicit Deny always wins! Identity policy + Resource policy = Union, Identity policy + Permissions boundary = Intersection
What is IAM Policy Evaluation Logic?
When a request comes to AWS, IAM evaluates all applicable policies to determine whether to allow or deny the request. Understanding this process helps solve complex permission issues.
3-Step Evaluation Process
1. Authentication
└─ Verify the principal (user/role) making the request
2. Request Context Processing
└─ Determine which policies apply
3. Policy Evaluation
└─ Evaluate all policy types for final decision
Explicit Deny vs Explicit Allow vs Implicit Deny
This is the most important concept in IAM policy evaluation.
| Type | Description | Priority |
|---|---|---|
| Explicit Deny | "Effect": "Deny" in policy | 🥇 Highest |
| Explicit Allow | "Effect": "Allow" in policy | 🥈 Second |
| Implicit Deny | Not mentioned in policy | 🥉 Default |
Evaluation Priority
1. Is there an explicit Deny? → If yes, deny immediately (evaluation ends)
2. Is there an explicit Allow? → If yes, allow
3. Neither exists → Implicit deny (default behavior)
Exam Tip
Golden Rule: A single explicit Deny overrides any number of Allow statements.
Example: The Power of Explicit Deny
// Policy A: Allow all S3 actions
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
// Policy B: Deny S3 deletion
{
"Effect": "Deny",
"Action": "s3:DeleteObject",
"Resource": "*"
}
Result: S3 deletion is denied (Policy B's explicit Deny overrides Policy A's Allow)
IAM Policy JSON Structure
Basic Policy Structure
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "StatementId",
"Effect": "Allow | Deny",
"Action": "service:Action",
"Resource": "arn:aws:...",
"Condition": { ... }
}
]
}
Element Descriptions
| Element | Required | Description |
|---|---|---|
| Version | Recommended | Policy language version (use "2012-10-17") |
| Statement | Required | Array of permission rules |
| Sid | Optional | Statement identifier |
| Effect | Required | Allow or Deny |
| Action | Required | AWS API actions to allow/deny |
| Resource | Required* | Resource ARNs the policy applies to |
| Condition | Optional | Conditions for policy application |
| Principal | Resource policies only | Policy target (account, user, role) |
Practical Example: S3 Bucket Read-Only Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3ReadOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
Wildcard Usage
| Pattern | Meaning |
|---|---|
s3:* | All S3 actions |
s3:Get* | All S3 actions starting with Get |
arn:aws:s3:::* | All S3 buckets |
arn:aws:s3:::my-bucket/* | All objects in my-bucket |
Policy Type Evaluation
Identity Policy + Resource Policy (Same Account)
Evaluated as Union: OK if allowed by either one
Effective permissions = Identity policy ∪ Resource policy
Example:
- Identity policy: Allow S3 read
- Resource policy: Allow S3 write
- Result: Both read and write allowed
Identity Policy + Permissions Boundary
Evaluated as Intersection: Must be allowed by both
Effective permissions = Identity policy ∩ Permissions boundary
Example:
- Identity policy: Allow S3, EC2, RDS
- Permissions boundary: Allow S3, EC2 only
- Result: Only S3, EC2 allowed (RDS blocked)
Identity Policy + SCP + RCP (Organizations)
Triple Intersection: All three policies must allow
Effective permissions = Identity policy ∩ SCP ∩ RCP
Exam Tip
Exam Point: SCP does NOT apply to the Management Account!
Using Conditions
Conditions allow policies to apply only in specific situations.
Commonly Used Condition Keys
| Condition Key | Description | Example |
|---|---|---|
aws:SourceIp | Request IP address | Allow only from specific IPs |
aws:CurrentTime | Current time | Allow only during business hours |
aws:MultiFactorAuthPresent | MFA authentication status | Allow only with MFA |
aws:PrincipalTag | Principal tags | Only users with specific tags |
s3:prefix | S3 object prefix | Allow access to specific folders only |
Example: Allow Only from Specific IP
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "203.0.113.0/24"
}
}
}
]
}
Example: Allow Delete Only with MFA
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
NotAction, NotResource, NotPrincipal
Not* elements mean "everything except this."
NotAction Example: Allow Everything Except IAM
{
"Effect": "Allow",
"NotAction": "iam:*",
"Resource": "*"
}
Meaning: Allow all AWS services except IAM
Exam Tip
Caution: NotAction is NOT the same as Deny! It means "apply this Effect to everything except the specified actions."
Mutually Exclusive Elements
Cannot be used together in the same Statement:
Action↔NotActionResource↔NotResourcePrincipal↔NotPrincipal
Policy Evaluation Flowchart
Request received
│
▼
Explicit Deny exists? ──Yes──► Deny (end)
│
No
▼
SCP allows? ──No──► Deny (end)
│
Yes (or no SCP)
▼
Permissions boundary allows? ──No──► Deny (end)
│
Yes (or no boundary)
▼
Identity or resource policy allows?
│
├──Yes──► Allow
│
└──No───► Deny (implicit deny)
SAA-C03 Exam Focus Points
- ✅ Evaluation priority: Explicit Deny > Explicit Allow > Implicit Deny
- ✅ Policy combination rules: Identity + Resource = Union, Identity + Boundary = Intersection
- ✅ SCP limitation: Does NOT apply to Management Account
- ✅ Condition usage: IP, MFA, time-based conditional access
- ✅ NotAction vs Deny: NotAction is "exclude," not deny
Exam Tip
Sample Exam Question: "An IAM user has full S3 access, but the permissions boundary only allows S3 read. Can the user delete S3 objects?" → Answer: No (Intersection with permissions boundary = read only)
Frequently Asked Questions
Q: How are multiple policies evaluated?
All policies are combined and evaluated together. Policies attached to users, group policies, resource policies - all relevant policies are collected and evaluated. However, any explicit Deny anywhere results in final denial.
Q: What's the difference between NotAction and Deny?
NotAction applies the Effect to "everything except the specified actions." For example, "Effect": "Allow", "NotAction": "iam:*" means "allow everything except IAM." It doesn't deny IAM itself.
Q: Where can I use the policy simulator?
You can use IAM Policy Simulator in the AWS Console. It lets you test policy evaluation results without sending actual requests, useful for debugging.
Q: Why should I use Version "2012-10-17"?
The older version "2008-10-17" doesn't support policy variables like ${aws:username}. Always use the latest version "2012-10-17".
Q: Is Principal: "*" in resource policies safe?
Very dangerous. It can allow access to all AWS accounts, even anonymous users. Always restrict to specific accounts or users, or add Condition constraints.
Q: When should I use permissions boundaries?
Primarily for delegating permissions. For example, when giving developers IAM user creation rights but limiting the maximum permissions those created users can have.
Related Posts
- IAM Basics: Users, Groups, Roles, Policies
- IAM Roles vs Users: When to Use What
- AWS Organizations & SCP Guide