Tuesday, October 7, 2025

IAM Roles vs Resource Based Policies | Deep Dive.

Intro:

  •     This topic remains one of the most fundamental, yet confusing to users of AWS Identity and Access Management (IAM).
  •     Understanding the difference between IAM roles (with trust policies) and resource-based policies is essential for designing secure and scalable Multi-Account Architectures.(aws organization Management)
  •     Resource-Based Policies:  Defines the effect (Action) that is allowed or Denied  in the tag resources (eg. S3 Bucket,SNS Topic, SQS, etc)

Scope:

  •         The Two Permission Models in AWS,
  •         IAM Role – Trust Policy and Permission Policy,
  •         Resource-Based Policies,
  •         Key Difference in Flow,
  •         The Combined Evaluation Logic,
  •         Common Scenarios,
  •        twtechExample: Cross-Account S3 Access Two Ways,
  •         Combining Both Approaches,
  •         Comparison Summary,
  •         Best Practices.

1. The Two Permission Models in AWS

AWS uses two main policy attachment models:

Type

Attached To

Defines

Example Services

Identity-based policy

IAM user, group, or role

What the identity can do on resources

iam:*, s3:GetObject, kms:Encrypt

Resource-based policy

AWS resource itself

Who can access the resource, and under what conditions

S3, SNS, SQS, Lambda, KMS, Secrets Manager, EventBridge


 2. IAM Role – Trust Policy and Permission Policy

IAM Role = Two Policy Layers

  1. Trust Policy (Who can assume the role?)
    • Defines which principals can call sts:AssumeRole.
  2. Permissions Policy (What can the role do once assumed?)
    • Defines what actions the assumed role can perform.

twtech-Example:

# Trust policy (who can assume this role)

{

  "Version": "2012-10-17",

  "Statement": [{

    "Effect": "Allow",

    "Principal": { "AWS": "arn:aws:iam::twtechAccountID:role/twtechCrossAccountRole" },

    "Action": "sts:AssumeRole"

  }]

}

# Permissions policy (what the role can do)

{

  "Version": "2012-10-17",

  "Statement": [{

    "Effect": "Allow",

    "Action": "s3:ListBucket",

    "Resource": "arn:aws:s3:::twtechLogbucket"

  }]

}


# Therefore:

  • The trust policy:  controls who gets in.
  • The permissions policy: controls what they can do once in.

3. Resource-Based Policies

A resource-based policy is attached directly to the resource and can specify external principals — users or roles from other accounts.

# twtech Example: S3 Bucket Policy for twtechSpringAppServer

{

  "Version": "2012-10-17",

  "Statement": [{

    "Effect": "Allow",

    "Principal": { "AWS": "arn:aws:iam::twtechAccountID:role/twtechSpringAppServerRole" },

    "Action": "s3:GetObject",

    "Resource": "arn:aws:s3:::twtechReplicationBucket/*"

  }]

}


# This lets twtechSpringAppServerRole in another account directly access the bucket without assuming a new role.

 4. Key Difference in Flow

Let’s compare what happens when a cross-account user tries to access something.

Step

IAM Role (Cross-Account AssumeRole)

Resource Policy (Direct Access)

1

Principal calls sts:AssumeRole on target account’s role

Principal directly calls s3:GetObject (or similar)

2

Target account’s trust policy checked

Resource policy’s Principal checked

3

If allowed, temporary credentials issued

IAM evaluates if the principal matches the condition

4

Temporary credentials used to call AWS services

Resource-based policy and principal’s identity-based policy both checked

Who owns permission logic?

The target role’s trust + permission policy

The resource’s policy

Example use case

Delegation, cross-account service access

Sharing resources (S3, KMS, EventBridge, etc.)

 5. The Combined Evaluation Logic

When a resource-based policy is used, AWS evaluates both sides:

NB:

Access is granted only if both the principal’s identity-based policy AND the resource’s policy allow the action.

Therefore, an S3 bucket with a resource policy and an IAM role in another account:

Is Allowed only if:

  • The role’s identity-based policy allows s3:GetObject
  • The bucket’s resource-based policy allows that principal (via Principal or aws:PrincipalOrgID)

Otherwise:
Denied

 6. Common Scenarios

Scenario A Cross-Account Access via AssumeRole

When to use:

  • twtech wants to delegate broad access between accounts (e.g., CI/CD pipelines, automation).
  • The principal in Account A temporarily assumes a role in Account B.

Pros: (Benefits)

  • Centralized permissions in IAM.
  • Works for any AWS service.

Cons: (Limitations)

  • Requires sts:AssumeRole calls.
  • Adds operational complexity (temporary credentials, session chaining limits).

Scenario B Resource-Based Access

When to use:

  • twtech needs to share a single resource across accounts or the org (e.g., S3 bucket, KMS key).
  • The service supports resource-based policies.

Pros: (Benefits)

  • Simpler for single resources.
  • No STS assume-role step.
  • Can combine with aws:PrincipalOrgID.

Cons: (Limitations)

  • Harder to audit when many principals are involved.
  • Limited to certain services.

7. twtechExample: Cross-Account S3 Access Two Ways

A. Using IAM Role

  1. twtechDevAccount  creates a role with:
    • Trust policy allowing twtechDevAccount 
    • Permissions to access the bucket.
  2. twtechProdAccount  assumes the role via sts:AssumeRole.

Flow:
User → AssumeRole (twtechProdAccount ) → Access S3 with temporary creds

B. Using Resource Policy

# twtechProdAccount's bucket policy:

{

  "Version": "2012-10-17",

  "Statement": [{

    "Effect": "Allow",

    "Principal": { "AWS": "arn:aws:iam::twtechAccountID:role/twtechWebAppServerRole" },

    "Action": "s3:GetObject",

    "Resource": "arn:aws:s3:::twtechSharedOrgBucket/*",

    "Condition": {

      "StringEquals": { "aws:PrincipalOrgID": "twtechOrgID" }

    }

  }]

}

# Now Account twtechDevAccount's role can directly call S3 APIs — no AssumeRole step.

 8. Combining Both Approaches

# In real-world AWS Organizations, twtech should be able to use both:

  • IAM Roles for delegation (CI/CD, automation).
  • Resource Policies for shared services (S3 logging, KMS encryption).

Example:

  • CloudTrail (who did what/SecurityFerensics) in every account writes logs to a central S3 bucket.
  • That bucket’s resource policy uses aws:PrincipalOrgID to limit access to Org members.
  • The central security account uses IAM roles to read and analyze those logs.

 9. Comparison  Summary

Feature

IAM Role (Trust Policy)

Resource-Based Policy

Attached To

IAM role

Resource (S3, KMS, etc.)

Specifies Who

Can assume the role

Can access the resource

How Access Happens

STS temporary credentials

Direct API call

Use Case

Delegated access

Shared resources

Supports Conditions

Yes

Yes

Cross-Account Support

Yes

Yes

Supports aws:PrincipalOrgID

Indirectly (via policy)

Directly

 10. Best Practices

  • twtech prefers resource-based policies for services that support them (S3, KMS, etc.)
  • Use aws:PrincipalOrgID to restrict org-wide access cleanly.
  • Use IAM roles for delegation between trusted accounts or automation pipelines.
  • Audit and visualize permissions regularly using IAM Access Analyzer.
  • Avoid "Principal": "*" unless combined with restrictive conditions.
  • Deny public access explicitly in S3 and KMS policies.

No comments:

Post a Comment

Amazon EventBridge | Overview.

Amazon EventBridge - Overview. Scope: Intro, Core Concepts, Key Benefits, Link to official documentation, Insights. Intro: Amazon EventBridg...