logo
Menu
Comprehensive Guide of AWS IAM Policy evaluation logic

Comprehensive Guide of AWS IAM Policy evaluation logic

AWS IAM Policy evaluation logic guide

Published Feb 29, 2024
Hello Everyone,
In this article, we are going to completely understand the AWS IAM Policy evaluation logic.
Identity and Access Management (IAM) in AWS controls access for users, groups and roles allowing interaction with AWS resources and services. This access is governed by policies that define permissions through allow and deny statements.
When an authenticated principal attempts accessing some AWS resource, the authorization logic kicks in to evaluate relevant policies before determining whether to permit or deny access. Properly grasping this evaluation logic is critical for securing your AWS environments.
This comprehensive, guide aims to provide an in-depth analysis of the intricate AWS IAM policy evaluation mechanisms through a diverse set of practical examples and best practice recommendations.
AWS_IAM

Core Concepts - Principals, Actions, Effect and Precedence

Let's starts by covering some fundamentals around IAM policy grammar and structural elements. This forms the baseline we build upon for digging into allow/deny scenarios.

IAM Principals

A principal entity in AWS IAM represents a user, machine or process that can be granted permissions to interact with resources. Common types of principals include:
  • IAM Users: Individual personnel accessing AWS, such as developers, admins etc.
  • IAM Groups: A collection of IAM users. Permissions granted at group level automatically apply for member users.
  • IAM Roles: Identity assigned to AWS entities like EC2 instance. Temporary access permissions tied specifically to the role.
There are additional kinds of principals like SAML federated users, identity pools etc. But the above three represent the major categories seen commonly across customer environments.

Policy Actions

Actions designated in a policy refer to specific API operations that can be performed. Here are some examples:
  • EC2:TerminateInstances: Permissions to shut down EC2 virtual machines
  • S3:GetObject: Access rights to retrieve objects from Amazon S3 storage buckets
  • IAM:PassRole: Ability to delegate permissions further to other entities
As visible these actions document very granular capabilities, allowing constructing least privilege access levels. They map to distinct API calls supported by each AWS service.
Wildcards and prefixes are also supported. s3:\* provides permissions for ALL S3 actions, while sts:AssumeRole is a specific individual operation under the STS global prefix.

Effect: Allow Versus Deny

The Effect parameter is mandatory in any policy statement. This specifies whether the statement results in an explicit Allow or an explicit Deny.
  • Allow: Makes the specified actions permitted, subject to conditions
  • Deny: Unerringly restricts the specified actions unconditionally
By default, anything NOT explicitly allowed is implicitly denied by AWS. We will analyze allow/deny evaluation flows next.

Precedence: Which Policy Wins?

In complex multi-account AWS environments you can have multiple IAM policies applying simultaneously. The precedence order dictates which policy takes ultimate priority during evaluation.
  1. Explicit Deny: Any explicit deny statement wins above all else
  2. Explicit Allow: The allows in other policies then take effect
  3. Default Deny: Anything left unspecified after the above steps is denied
This order of deny superseding allow establishes the strict access controls clouds are renowned for. We will see examples of this next.
Now that we have refreshed basics around IAM policy anatomy, let's move on to...

AWS Policy Grammar, Syntax and Vocabulary

IAM policies use declarative JSON-based access control language describing identity permissions. Let's take a closer look at how these structured policy documents are written.

IAM Policy JSON Structure

Here is an example illustrating schema of AWS IAM policies:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow"|"Deny",
"Action": "servicename:operation",
"Resource": "resourceARN"
},
{
"Effect": "Allow"|"Deny",
"Action": ["service1:action1", "service2:action2"],
"Resource": "*"
}
]
}
Essential elements of note:
  • Version: Indicates policy language format date, typically 2012-10-17
  • Statement: Container for individual access control permissions. A policy has one or more statements.
  • Effect: Allow or deny directive as described previously.
  • Action: Specific service capabilities allowed/denied. Use wildcards to permit blanket access.
  • Resource: Particular entity being accessed. * provides unlimited access.
Additionally, Conditions can be specified to restrict policy applications only if certain criteria are met. For example allowing actions only from specific source IP range.
Now that you understand the JSON structure of IAM policies, let's analyze how wildcards can simplify policy writing.

Using Wildcards for Simplifying Overly Verbose Permissions

Specifying identity policies can frequently entail granting a broad set of access across multiple resources and services.
Manually enumerating every individual action would result in complex, large policies. Instead wildcards provide easier mechanisms to deliver wide-ranging permissions through a concise policy document.
Here are some common examples of wildcards usage:

Service-Wide Access

If you want to enable ALL capabilities of a particular service, use the :\* action. For example granting permissions for entire S3 service:
1
"Action": "s3:*"

All Services in an Account

The :\* action can also be qualified by global ARN namespace to allow all actions across ALL services in account:
1
"Action": “arn:aws:*:*”

All Resources

Instead of specifying individual resource ARNs, the * wildcard opens access for user to ALL resources:
1
"Resource": "*"
These simplified constructs enable delivering expansive access without verbose policy documents explicitly listing every minor capability per service.
We will leverage wildcards in subsequent examples demonstrating allow/deny policy evaluation logic flows.
Up next we will explore the hierarchy and order of evaluation across different policy types.

Hierarchical Priority Order of Evaluation in AWS

AWS applies a precise sequence when processing policies to arrive at the final allow or deny decision. Policies higher up in hierarchy take precedence, and deny statements override any allows.
Let’s analyze how the waterfall flows top-down, with policies indexed by order of priority:

1. Organization SCPs

Service Control Policies (SCPs) applied at AWS Organizations level take highest priority. These provide guard-rails and boundaries for the entire organization multi-account structure.
If the SCP has an explicit deny, the request is automatically rejected regardless of other allows downstream. We will see examples of SCPs overruling identity policies.

2. IAM Inline Policies

Inline policies directly embedded into IAM identities are next evaluated if no SCP deny happened.
These policies attach to the user/group/role and can allow or deny respective resource access. Inline policies take precedence over managed policies.

3. IAM Managed Policies

Pre-defined managed policies that administrators attach to multiple IAM identities are considered after inline policies. These are standalone policies that can be re-used across groups/users/roles.

4. Permission Boundaries

Permission boundaries are advanced IAM constructs that behave like containers. Identities like users/roles can only access permissions within their boundary.
This allows additional access controls above identity/resource policies. Boundaries wrap identities.

5. Session Policies

Temporary session policies passed programmatically at run-time apply additional inline permissions for the user’s active session.
These provide dynamic controls only for the current session’s lifetime beyond the static identity inline/managed policies.

6. Resource Policies

Where applicable, resource-based policies directly attached to the resource in question are evaluated last.
These resource policies may themselves allow or deny access to resource irrespective of identity permissions.
Now that we have clarity on policy evaluation order, let’s analyze some examples of how allows and denies play out.

Walkthrough of Policy Evaluation Scenarios

We will now dissect some multi-layered scenarios across accounts, groups, resources and federated identities to demonstrate nuances around allow and deny across policy types.

SCP Blocking All S3 Deletion Attempts Organization-Wide

AmazeOnCloud Corp has a multi-account AWS environment used by marketing, R&D and IT teams.
The centralized security team wants to fully restrict S3 bucket deletion across all departments. They setup following SCP:
1
2
3
4
5
6
7
8
9
10
11
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyBucketDeletion",
"Effect": "Deny",
"Action": "s3:DeleteBucket",
"Resource": "*"
}
]
}
What happens when...
Marketng user John issues s3:DeleteBucket API call
Although John has s3:* permissions from his group’s IAM policy that allows full S3 access, the DELETE action is denied from SCP.
John lacks ability to override parent SCP blocking delete capabilities organization-wide.
Outcome: AccessDenied
As you can see, SCP deny statements provide overriding guard-rails that downstream IAM permissions cannot bypass due to higher precedence.
Let's extend this scenario...

SCP Restrictions Paired With Session Policy Allow

The security team retains the DeleteBucket blocking SCP to avoid catastrophic accidents across the organization.
However the R&D team needs to iterate on development code requiring ability to recreate S3 buckets repeatedly. So the policy is tweaked to allow deletes but only for a special category of “dev” buckets while retaining general protection:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyBucketDeletionExceptDevOnes",
"Effect": "Deny",
"Action": "s3:DeleteBucket",
"Resource": "*",
"Condition" : {
"StringNotLike" : {"s3:prefix" : ["dev-"]}
}
}
]
}
What happens when...
R&D engineer Jane issues s3:DeleteBucket against a dev- project bucket with an ACTIVE session policy explicitly allowing s3:DeleteBucket?
Jane’s session policy allows DELETE. SCP deny is overridden for “dev-” buckets based on conditional logic. Jane can delete this dev bucket despite base SCP blocking capability for standard buckets.
Outcome: Allow
This demonstrates session policies providing run-time permissions that can override identity-level denies like SCP for specialized use-cases.
Now that you have seen SCPs in action and pairing with session policies, let's analyze...

Permission Boundaries Impact When Resource Policy Allows

Ashoka leads application migration initiative onto AWS infrastructure. Her users need permissions to launch and configure EC2 instances hosting these apps.
However Ashoka wants to enforce least-privilege so users get ONLY capability to start new instances but cannot tamper configuration or terminate existing ones. This will be delivered through permission boundary:
Ashoka’s Permission Boundary
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:RunInstances",
"ec2:StartInstances"
],
"Resource": "*"
}
]
}
Separately the AWS infrastructure team has an EC2 resource policy to allow ALL users ability to STOP instances for cost optimization efforts:
Infra Team EC2 Resource Policy
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"Version": "2012-10-17",
"Id": "EC2CostPolicy",
"Statement": [
{
"Sid": "SaveMoneyByStoppingEC2",
"Effect": "Allow",
"Principal": "*",
"Action":"ec2:StopInstances",
"Resource": "*"
}
]
}
What happens when...
Application team member Raj tries to STOP an EC2 instance to scale down capacity?
Despite resource policy explicitly allowing ec2:StopInstances...Raj is DENIED since his permission boundary overrides downstream allows. Boundary limits Raj only to Run/Start actions.
Outcome: DeniedDueToPermissionBoundary
As observed, although multiple identity and resource policies might allow an action - a permission boundary can impose greater constraints restricting user access.
Up next let's explore...

Tag-Based Identity Policies Overruling S3 Denies

AOC enterprise leverages IAM identity policies extensively to govern AWS access.
Sandbox policy testing groups have broad access. Production environment groups are tightly controlled. This is delivered through group policy conditions checking resource tags:
Sandbox Group Policy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SandboxAccess",
"Effect": "Allow",
"Action": [
"s3:*",
"ec2:*"
],
"Resource": "*",
"Condition": {
"StringEquals": {"aws:ResourceTag/Environment": "Sandbox"}
}
}
]
}
Production Group Policy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ProductionAccess",
"Effect": "Deny",
"Action": "s3:*",
"Resource": "*",
"Condition": {
"StringEquals": {"aws:ResourceTag/Environment": "Production"}
}
}
]
}
What happens when...
Alice from sandbox team tries to DELETE an S3 object tagged as sandbox environment?
Although production policy DENIES all S3 capabilities, Alice has ALLOW permission granted explicitly based on tag value check. Her access overrides baseline production identity deny.
Outcome: AllowedBySandboxPolicy
This demonstrates how identity and resource policies can interact, with most specific allows superseding any broad denies.
We have now analyzed a range of multi-layered scenarios across accounts, groups and permissions. Now let's shift gears to troubleshooting problems and resolutions.

Diagnosing and Fixing "Access Denied" Errors

Despite carefully structuring IAM policies, users may unexpectedly encounter AccessDenied errors preventing legitimate access. How do we methodically troubleshoot authorization failures?
Follow these steps to diagnose blocked access:

1. Verify User Identity

Check principal attempting access matches expected personnel or system entity requiring capability.
Confirm it IS the intended authorized party making the request rather than unauthorized malacious actor.

2. Review CloudTrail Logs

Scan CloudTrail event history for the "Access Denied" event. Identify:
  • Identity ARNdenied
  • Action attempted
  • Resources/conditions related to call
  • Policy that issued deny

3. Replicate API call

Replay the same raw API call with debugging. Analyze response fields and flags for further clues.

4. Analyze Applicable Policies

Based on identity and action context, inspect policies in the potential evaluation path. Scan for unintended deny statements incorrectly blocking activities.

5. Check Dependencies

Review components policy depends on like permissions sets, roles, external federated profiles etc. Any broken access could cause ripple denial.
Still stuck after exhaustive analysis? Time to DIRECTLY test by attempting access using AWS CLI tools while assuming the role/policy that's denying access.
1
2
3
$ aws sts assume-role \\
--role-arn [role-ARN]
--role-session-name testsession
The assume-role command lets you mimic session conditions and attempt access under identical context. Directly test capabilities using CLI until issue is further isolated.
Using this trobleshooting approach helps methodically narrow down the specific policy statement or component responsible for unexpected denials. You can then refine the policies till access aligns with least-privilege permissions needed.
We will now shift gears to our final section around recommendations for effectively managing IAM policies.

Best Practices Guide for IAM Policies

Let's conclude by distiling down key best practices based on all we have covered regarding permissions policies:

Principle of Least Privilege

Grant ONLY essential minimum capabilities required for users, groups or roles to fulfill their duties. Limit all other access. Start narrow, expand later if needed.

Validate Policies Before Deployment

Visualize and test policies ahead of production rollout using IAM policy simulator. Confirm intended allows and denies to avoid surprises.

Embed Policy Documents Where Possible

Inline embed policies directly into user, group and role definitions instead of relying extensively on shared managed policies. Avoid detachment from auditing.

Enforce Policy Conditions

Restrict all permissions through judicious conditions checks beyond coarse identity filtering. Rating environmental data like user tags, source IPs drastically hardens access.

Monitor Policy Versions

Version policies for change tracking. Assign descriptitive identifiers to policy versions to simplify rollbacks. Backups up versioned policies before modifications.

Rotate Credentials

Require IAM users to rotate access keys/certificates periodically. Minimizes risk from compromised stale credentials. High security environments can leverage automatic rotation mechanisms.
Adhering to these leading practices will assist keeping your AWS permissions model robust and resilient as environments scale and evolve.

Conclusion

In this extensive deep dive, we traversed the intricacies around AWS IAM policy evaluation flows. Through multiple practical examples across accounts, groups and federated identities you should now feel comfortable tackling nuanced allow/deny scenarios. We wrapped up with troubleshooting access errors and policy management best practices.
IAM permissions form the bedrock of the shared responsibility model for securing AWS cloud environments. Mastering policy evaluation logic is an indispensable skill every aspiring cloud security expert needs in their arsenal!
Happy upskilling.