Fatskills
Practice. Master. Repeat.
Study Guide: TECH **AWS IAM Policy Types: Identity-based, Resource-based, Permission Boundaries**
Source: https://www.fatskills.com/aws-certified-solutions-architect-associate/chapter/tech-aws-iam-policy-types-identity-based-resource-based-permission-boundaries

TECH **AWS IAM Policy Types: Identity-based, Resource-based, Permission Boundaries**

By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.

⏱️ ~9 min read

AWS IAM Policy Types: Identity-based, Resource-based, Permission Boundaries

A Hyper-Practical, Zero-Fluff Study Guide for AWS SAA-C03


1. What This Is & Why It Matters

You’re a cloud engineer at a fintech startup. Your team just migrated a legacy monolith to AWS, and now every developer, CI/CD pipeline, and microservice needs access to S3, DynamoDB, and Lambda—but no one should have admin rights. Your CISO demands least privilege, your DevOps lead wants automated deployments, and your CFO is watching costs like a hawk.

IAM Policy Types are the tools you’ll use to: - Grant permissions (e.g., "Allow this Lambda function to read from S3").
- Restrict permissions (e.g., "No one can delete production databases").
- Delegate permissions safely (e.g., "Let developers manage their own IAM roles, but only within a boundary").

If you ignore this:
- Your S3 bucket gets publicly exposed (hello, data breach).
- Your CI/CD pipeline fails silently because the IAM role lacks permissions.
- Your developers accidentally delete production resources (RIP, weekend plans).

If you master this:
- You automate secure access without manual ticketing.
- You audit permissions in minutes (not days).
- You pass the AWS SAA exam with confidence.


2. Core Concepts & Components


? Identity-based Policies

  • Definition: JSON documents attached to IAM users, groups, or roles that define what they can do.
  • Production Insight:
  • Always attach policies to roles, not users (avoid "IAM user sprawl").
  • Use managed policies (e.g., AmazonS3ReadOnlyAccess) for common tasks—don’t reinvent the wheel.
  • Example:
    json
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::my-bucket/*"
    }
    ]
    }

? Resource-based Policies

  • Definition: JSON documents attached to AWS resources (e.g., S3 buckets, SQS queues) that define who can access them.
  • Production Insight:
  • S3 bucket policies are the most common (e.g., "Allow cross-account access").
  • Lambda resource policies control who can invoke the function.
  • Example (S3 Bucket Policy):
    json
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": "arn:aws:iam::123456789012:root"
    },
    "Action": "s3:*",
    "Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"]
    }
    ]
    }

? Permission Boundaries

  • Definition: A maximum permission limit for an IAM entity (user/role). The entity can’t exceed this boundary, even if its identity-based policies allow it.
  • Production Insight:
  • Use for delegating IAM administration (e.g., "Let developers create roles, but only with read-only access").
  • Prevents privilege escalation (e.g., "No one can attach AdministratorAccess to a role").
  • Example:
    json
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": ["s3:*", "dynamodb:*"],
    "Resource": "*"
    }
    ]
    }

    (If attached as a boundary, the role can’t do anything outside S3/DynamoDB.)

? Inline vs. Managed Policies

  • Inline Policy: Embedded directly in a user/role (hard to manage at scale).
  • Managed Policy: Standalone, reusable (AWS-managed or customer-managed).
  • Production Insight:
  • Use managed policies for common permissions (e.g., AmazonEC2FullAccess).
  • Use inline policies for one-off, highly specific permissions.

? Policy Evaluation Logic

  • How AWS decides "Allow" or "Deny":
  • Explicit Deny (highest priority) → Deny.
  • Explicit AllowAllow.
  • Default DenyDeny.
  • Production Insight:
  • Deny rules override Allow rules (e.g., a boundary can block an identity policy).
  • Resource policies are evaluated separately (e.g., an S3 bucket policy can override an IAM role).

? Trust Policies (for IAM Roles)

  • Definition: JSON document that defines who can assume the role (e.g., an EC2 instance, Lambda function, or another AWS account).
  • Production Insight:
  • Always restrict trust policies (e.g., "Principal": { "Service": "lambda.amazonaws.com" }).
  • Never use "Principal": "*" (this allows any AWS account to assume the role).
  • Example:
    json
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "Service": "lambda.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
    }
    ]
    }


3. Step-by-Step Hands-On: Secure an S3 Bucket with All 3 Policy Types


Prerequisites

  • AWS account with admin IAM permissions.
  • AWS CLI installed (aws --version).
  • A test S3 bucket (my-secure-bucket-123).

Step 1: Create an IAM Role with an Identity-based Policy

Goal: Allow a Lambda function to read from S3.


# Create a trust policy (lambda-trust-policy.json)
cat > lambda-trust-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
} ] } EOF # Create the role aws iam create-role --role-name LambdaS3ReadRole --assume-role-policy-document file://lambda-trust-policy.json # Attach an identity-based policy (S3 read-only) aws iam attach-role-policy --role-name LambdaS3ReadRole --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

Verify:


aws iam list-attached-role-policies --role-name LambdaS3ReadRole

(Should show AmazonS3ReadOnlyAccess.)


Step 2: Add a Resource-based Policy to the S3 Bucket

Goal: Allow cross-account access (e.g., 123456789012 can read the bucket).


# Create a bucket policy (bucket-policy.json)
cat > bucket-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-secure-bucket-123/*"
} ] } EOF # Apply the policy aws s3api put-bucket-policy --bucket my-secure-bucket-123 --policy file://bucket-policy.json

Verify:


aws s3api get-bucket-policy --bucket my-secure-bucket-123

(Should show the policy.)


Step 3: Apply a Permission Boundary to Restrict the Role

Goal: Ensure the Lambda role can only access S3 (no DynamoDB, EC2, etc.).


# Create a boundary policy (boundary-policy.json)
cat > boundary-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
} ] } EOF # Create the boundary aws iam create-policy --policy-name S3OnlyBoundary --policy-document file://boundary-policy.json # Attach the boundary to the role aws iam put-role-permissions-boundary --role-name LambdaS3ReadRole --permissions-boundary arn:aws:iam::YOUR_ACCOUNT_ID:policy/S3OnlyBoundary

Verify:


aws iam get-role --role-name LambdaS3ReadRole

(Check PermissionsBoundary in the output.)


Step 4: Test the Setup

Goal: Confirm the Lambda role can only read S3 (not delete objects or access other services).


# Assume the role (simulate Lambda)
CREDS=$(aws sts assume-role --role-arn arn:aws:iam::YOUR_ACCOUNT_ID:role/LambdaS3ReadRole --role-session-name TestSession)
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r .Credentials.AccessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r .Credentials.SecretAccessKey)
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r .Credentials.SessionToken)

# Test S3 access (should work)
aws s3 ls s3://my-secure-bucket-123/

# Test DynamoDB access (should fail)
aws dynamodb list-tables

(Expected: AccessDeniedException for DynamoDB.)


4. ? Production-Ready Best Practices


Security

  • Least Privilege: Start with deny-all, then add permissions as needed.
  • Avoid * in Resources: Use specific ARNs (e.g., arn:aws:s3:::my-bucket/*).
  • Rotate Credentials: Use IAM roles for EC2/Lambda (no long-term keys).
  • Enable IAM Access Analyzer: Detects unintended resource access.

Cost Optimization

  • Managed Policies: Use AWS-managed policies (e.g., AmazonS3ReadOnlyAccess) to avoid reinventing the wheel.
  • Permission Boundaries: Reduce over-provisioning by restricting max permissions.

Reliability & Maintainability

  • Tagging: Tag IAM roles/policies for cost allocation (e.g., Environment=Prod).
  • Naming Conventions: Prefix roles with their purpose (e.g., Lambda-S3-Read-Role).
  • Versioning: Use policy versions to roll back changes.

Observability

  • CloudTrail: Log all IAM API calls (CreateRole, AttachPolicy).
  • IAM Access Advisor: Identify unused permissions.
  • AWS Config: Track IAM policy changes.


5. ⚠️ Common Mistakes & Traps

Mistake Symptom Fix/Prevention
Using Principal: "*" in trust policies Any AWS account can assume the role. Restrict to specific services/accounts (e.g., "Service": "lambda.amazonaws.com").
Not setting permission boundaries Developers attach AdministratorAccess to roles. Enforce boundaries for all IAM entities.
Overusing inline policies Hard to audit/manage at scale. Use managed policies for common permissions.
Ignoring resource policies S3 buckets get public access. Always set explicit Deny for public access.
Not testing policies Lambda fails silently due to missing permissions. Use aws iam simulate-principal-policy to test.


6. ? Exam/Certification Focus


Typical Question Patterns

  1. "Which policy type allows cross-account access?"
  2. Answer: Resource-based policies (e.g., S3 bucket policy).
  3. Trap: Identity-based policies only work within the same account.

  4. "How do you restrict a role to only S3 access?"

  5. Answer: Use a permission boundary.
  6. Trap: Identity-based policies alone can’t enforce max limits.

  7. "What happens if an identity policy allows S3 access but a boundary denies it?"

  8. Answer: Deny wins (boundary overrides identity policy).
  9. Trap: Many assume identity policies take precedence.

Key Distinctions

Concept Identity-based Resource-based Permission Boundary
Attached to User/Role/Group Resource (S3, SQS) User/Role
Use Case "What can this role do?" "Who can access this bucket?" "What’s the max this role can do?"
Cross-Account? ❌ No ✅ Yes ❌ No

Scenario-Based Question

"You need to allow a Lambda function in Account A to read from an S3 bucket in Account B. What’s the most secure way?"
- Answer:
1. Account B: Add a resource-based policy to the S3 bucket allowing Account A’s Lambda role.
2. Account A: Attach an identity-based policy to the Lambda role granting s3:GetObject.
- Why? Resource policies enable cross-account access, and identity policies enforce least privilege.


7. ? Hands-On Challenge

Challenge:
Create an IAM role for an EC2 instance that: 1. Can only read from a specific S3 bucket (my-app-logs).
2. Has a permission boundary restricting it to S3 only.
3. Uses a trust policy allowing only EC2 to assume it.

Solution:


# 1. Create trust policy (ec2-trust-policy.json)
cat > ec2-trust-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
} ] } EOF # 2. Create the role aws iam create-role --role-name EC2S3ReadRole --assume-role-policy-document file://ec2-trust-policy.json # 3. Create an identity policy (s3-read-policy.json) cat > s3-read-policy.json <<EOF { "Version": "2012-10-17", "Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-app-logs/*"
} ] } EOF # 4. Attach the identity policy aws iam put-role-policy --role-name EC2S3ReadRole --policy-name S3ReadPolicy --policy-document file://s3-read-policy.json # 5. Create a boundary policy (s3-only-boundary.json) cat > s3-only-boundary.json <<EOF { "Version": "2012-10-17", "Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
} ] } EOF # 6. Create and attach the boundary aws iam create-policy --policy-name S3OnlyBoundary --policy-document file://s3-only-boundary.json aws iam put-role-permissions-boundary --role-name EC2S3ReadRole --permissions-boundary arn:aws:iam::YOUR_ACCOUNT_ID:policy/S3OnlyBoundary

Why it works:
- The trust policy restricts role assumption to EC2.
- The identity policy grants only s3:GetObject.
- The boundary ensures the role can’t do anything outside S3.


8. ? Rapid-Reference Crib Sheet

Command/Concept Example/Notes
Create IAM Role aws iam create-role --role-name MyRole --assume-role-policy-document file://trust-policy.json
Attach Identity Policy aws iam attach-role-policy --role-name MyRole --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
Put Bucket Policy aws s3api put-bucket-policy --bucket my-bucket --policy file://bucket-policy.json
Set Permission Boundary aws iam put-role-permissions-boundary --role-name MyRole --permissions-boundary arn:aws:iam::123456789012:policy/MyBoundary
Test Policy aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::123456789012:role/MyRole --action-names s3:GetObject --resource-arns arn:aws:s3:::my-bucket/*
⚠️ Default Deny If no policy allows an action, AWS denies it.
⚠️ Explicit Deny > Allow A Deny in any policy (identity/resource/boundary) overrides an Allow.
⚠️ Resource Policies Enable Cross-Account Access Identity policies alone can’t grant cross-account permissions.


9. ? Where to Go Next

  1. AWS IAM Policy Documentation – Official guide.
  2. IAM Policy Simulator – Test policies before applying.
  3. AWS IAM Best Practices – Security hardening.
  4. AWS Well-Architected Framework (Security Pillar) – Production-grade IAM strategies.


ADVERTISEMENT