Skip to content

Cloud IAM Policies Deep Dive — Policy Evaluation & Condition Keys

DodaTech Updated 2026-06-24 5 min read

In this tutorial, you'll learn about Cloud IAM Policies Deep Dive. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Cloud IAM policy evaluation determines whether an API request is allowed or denied by combining identity-based, resource-based, and permissions boundary policies across AWS, Azure, and GCP with explicit deny taking precedence over allow.

What You Will Learn

How each cloud provider evaluates IAM policies, how condition keys restrict permissions based on request context, and how to use policy analysis tools to audit effective permissions.

Why It Matters

IAM policy logic is the most misunderstood area of Cloud Security. Complex policies with multiple statements, condition keys, and permission boundaries can produce unexpected results that either block legitimate users or grant unintended access.

Real-World Use

DodaTech's security team uses AWS IAM Access Analyzer to validate every new policy before deployment. A recent validation caught a policy with a condition key that matched the wrong IP range, preventing unintended public access to a production database.

Policy Evaluation Flow

flowchart TD
  Request[API Request\nPrincipal, Action, Resource, Context] --> DenyCheck{Explicit Deny?}
  DenyCheck -->|Yes| Deny[Deny Request]
  DenyCheck -->|No| AllowCheck{Explicit Allow?}
  AllowCheck -->|No| Deny
  AllowCheck -->|Yes| BoundaryCheck{Permissions Boundary?\nAWS / Org Policies}
  BoundaryCheck -->|No| Allow[Allow Request]
  BoundaryCheck -->|Yes| InScope{Within Boundary?}
  InScope -->|Yes| Allow
  InScope -->|No| Deny
  
  style DenyCheck fill:#e00,color:#fff
  style AllowCheck fill:#390,color:#fff

AWS IAM Policy Evaluation

AWS policies follow a strict evaluation order: explicit deny wins, then explicit allow, with permissions boundaries acting as a ceiling on what can be granted.

# Create a policy with a condition key restricting to VPC endpoint
aws iam create-policy \
  --policy-name vpc-only-access \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-secure-bucket/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceVpce": "vpce-12345678]
        }
      }
    }]
  }'

# Attach a permissions boundary to an IAM role
aws iam put-role-permissions-boundary \
  --role-name developer-role \
  --permissions-boundary arn:aws:iam::123456789012:policy/developer-boundary

# Validate a policy before deployment
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:user/test-user \
  --action-names s3:PutObject dynamodb:GetItem \
  --resource-arns arn:aws:s3:::my-bucket/key \
  --output table
# Output:
# --------------------------------------------
# | EvaluationResult                        |
# +-----------+----------------------------+
# | s3:PutObject  | allowed               |
# | dynamodb:GetItem | explicitDeny       |
# +-----------+----------------------------+

Azure RBAC Policy Evaluation

Azure uses role assignments with a deny assignments feature that takes precedence over role-based allow.

# Create a custom role with data actions
az role definition create \
  --role-definition '{
    "Name": "Database Reader",
    "Description": "Read data from specific SQL databases",
    "Actions": ["Microsoft.Sql/servers/databases/read"],
    "DataActions": ["Microsoft.Sql/servers/databases/data/read"],
    "AssignableScopes": ["/subscriptions/.../resourceGroups/prod-rg"]
  }'

# Assign the role with condition
az role assignment create \
  --assignee user@dodatech.com \
  --role "Database Reader" \
  --scope "/subscriptions/.../resourceGroups/prod-rg" \
  --condition "((!(ActionMatches{'Microsoft.Sql/servers/databases/data/read'}))) OR (@Resource[Microsoft.Sql/servers/databases:name] StringEquals 'prod-db')"

# Get effective permissions for a user
az role assignment list \
  --assignee user@dodatech.com \
  --include-inherited \
  --query "[].{Role:roleDefinitionName, Scope:scope}" \
  --output table
# Output:
# Role              Scope
# Database Reader   /subscriptions/.../resourceGroups/prod-rg
# Reader            /subscriptions/...

GCP IAM Policy Evaluation

GCP evaluates policies hierarchically from the organization level down to the resource. Conditions narrow the scope of role grants.

# Set an organization policy with a condition
gcloud organizations add-iam-policy-binding 123456789012 \
  --member="group:security-team@dodatech.com" \
  --role="roles/compute.securityAdmin" \
  --condition='expression=resource.matchTag("env","prod"),title=prod-only'

# Use IAM Conditions to restrict access by IP
gcloud projects add-iam-policy-binding my-project \
  --member="user:dev@dodatech.com" \
  --role="roles/storage.objectViewer" \
  --condition='expression=request.ip.matches("10.0.0.0/8"),title=vpn-only'

# Verify effective access
gcloud policy-intelligence query-activity \
  --project=my-project \
  --activity-type=iam.policy.grant \
  --query="principalEmail:dev@dodatech.com"
# Output:
# {
#   "activities": [{
#     "activityType": "iam.policy.grant", "#     "eventTime": "2026-06-24T10:00:00Z"", "#     "principalEmail": "dev"@dodatech".com"",
#     "role": "roles/storage.objectViewer]
#   }]
# }

Condition Key Comparison

Condition keys restrict permissions based on time, IP, VPC endpoint, MFA status, or resource tags. Use them to implement just-in-time access and network-based restrictions.

Common Mistakes

  1. Misunderstanding explicit deny precedence: An explicit deny in any policy always wins, even if another policy allows the same action. Never use explicit deny as an allow with exceptions.
  2. Overly broad condition key values: A condition on aws:SourceIp with a 0.0.0.0/0 range is equivalent to having no condition at all. Be specific.
  3. Not testing policies before deployment: A single typo in a condition key name results in the condition being ignored. Always use policy simulators.
  4. Ignoring permissions boundaries in AWS: A permissions boundary limits the maximum permissions a role can have. If you use them, ensure your allow policies stay within the boundary.
  5. Complex multiple-statement policies: Policies with many statements are hard to audit. Keep each policy focused on a single purpose.

Practice Questions

  1. What is the evaluation order of AWS IAM policies?
  2. How do Azure deny assignments differ from role assignments?
  3. What is the role of IAM Conditions in GCP?
  4. Why does an explicit deny override all allow statements?
  5. How can you test IAM policy changes before applying them?

Challenge

Design a set of IAM policies for a sensitive data processing workflow. The data scientists need read-only access to a specific S3 bucket (or GCS bucket / Blob container) but only during business hours (9 AM - 5 PM) and only from the corporate VPN IP range. Use condition keys to enforce both time and IP restrictions. Write the policies for all three clouds and validate them using each provider's policy simulator.

FAQ

How does AWS IAM policy evaluation work?

AWS evaluates all applicable policies in order: explicit deny (immediate deny), then explicit allow. If neither matches, the default is deny.

What is an IAM permissions boundary in AWS?

A permissions boundary sets the maximum permissions an IAM role can receive. It acts as a ceiling on what can be granted by allow policies.

How do Azure RBAC conditions work?

RBAC conditions use expressions to add checks that must be satisfied for the role assignment to take effect.

What are GCP IAM Conditions?

Conditions in GCP allow you to specify attributes like IP range, time, or resource tags that must match for the IAM role binding to apply.

What happens if two AWS policies contradict each other?

An explicit deny always wins. If one policy allows access and another denies it, the result is deny.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro