The foundation of AWS security. Control who can access what in your AWS account. Every real AWS project uses IAM — learn it once, use it everywhere.
AWS IAM (Identity and Access Management) is a free AWS service that lets you securely control access to AWS services and resources. Using IAM, you create users, assign permissions, and define exactly what each person or application can and cannot do.
These are the 9 terms you must know cold before any AWS interview. Every IAM concept builds on these.
A Policy is a JSON document with 5 key fields: Effect (Allow/Deny), Action (what operation), Resource (which AWS resource), Principal (who), and Condition (when/how). Every permission in AWS is defined through a policy.
{ "Version": "2012-10-17", // always use this version "Statement": [ { "Effect": "Allow", // Allow or Deny "Action": [ "s3:GetObject", // read a file "s3:PutObject" // upload a file ], "Resource": "arn:aws:s3:::my-bucket/*" // which S3 bucket } ] } // Real example: Lambda reads from one S3 bucket only { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::raw-data-bucket/*" }, { "Effect": "Deny", // explicitly block delete "Action": "s3:DeleteObject", "Resource": "*" } ] }
| Policy Type | Who Creates It | When to Use |
|---|---|---|
| AWS Managed Policy | AWS creates and maintains | Quick start — use predefined policies like AmazonS3ReadOnlyAccess |
| Customer Managed Policy | You create in your account | Custom business rules — most used in real projects |
| Inline Policy | You create, attached to one identity only | One-off permissions for a specific user/role — not reusable |
| Permission Boundary | You create as a guardrail | Limit max permissions a developer can grant to any role |
| Session Policy | Passed during AssumeRole | Temporarily restrict permissions for a specific session |
There are 3 different ways to get access to AWS resources. As a fresher, understanding when to use which is what interviewers test. Each has a completely different use case.
ravi.user and accesses S3 buckets and EC2 instances to do his daily work.HR-Reports-Role to access the HR S3 folder. When someone leaves the team, you just remove them from the role — no individual policy updates needed.GlueServiceRole which has S3 read/write permissions. No human logs in — it's fully automated.| Access Type | Who Uses It? | Credentials | Duration | Best Use Case |
|---|---|---|---|---|
| User-Based | Human developers, analysts | Password + Access Keys | Long-term | Daily console work, CLI usage |
| Role-Based | Humans via Assume Role | Temporary (STS) | Short-term | Teams, cross-account, elevated access |
| Service-to-Service | AWS Services (Glue, Lambda) | Temporary via Role | Short-term | Glue→S3, Lambda→DynamoDB, EC2→S3 |
| Factor | User-Based | Role-Based ✅ Recommended |
|---|---|---|
| Permissions attached to | Individual user directly | Role — shared by all who assume it |
| Team management | Update each user individually | Update the role once — all users get it |
| Security | Long-term credentials — risk if leaked | Temporary credentials — auto-expire |
| Cross-account access | Very complex | Built-in with Trust Policy |
| AWS services (Lambda etc) | Cannot use user credentials | Services assume roles natively |
| Scalability | Gets messy with 50+ users | Scales to thousands of users easily |
| Best for | Individual devs, small teams | Teams, applications, AWS services |
// This Trust Policy allows Lambda service to assume this role // Without this, Lambda cannot use the role — security by design { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" // Lambda can assume this role }, "Action": "sts:AssumeRole" } ] } // Trust Policy for cross-account access // Allow another AWS account (123456789012) to assume this role { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:root" }, "Action": "sts:AssumeRole" } ] }
// Step 1: Create GlueServiceRole with Trust Policy for Glue { "Principal": { "Service": "glue.amazonaws.com" }, "Action": "sts:AssumeRole" } // Step 2: Attach Permission Policy — read from raw, write to clean { "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject", "s3:ListBucket"], "Resource": "arn:aws:s3:::raw-data-bucket/*" }, { "Effect": "Allow", "Action": ["s3:PutObject", "s3:DeleteObject"], "Resource": "arn:aws:s3:::clean-data-bucket/*" } ] } // Step 3: Assign GlueServiceRole to your Glue Job — done! // Glue now has S3 access with zero human credentials involved.
// Create Group: DataEngineers // Attach ONE policy to the group — all 15 engineers inherit it { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*", // full S3 access "glue:*", // full Glue access "athena:*", // full Athena access "cloudwatch:GetMetric*" // read-only CloudWatch ], "Resource": "*" } ] } // New engineer joins? Add them to DataEngineers group — instant access. // Engineer leaves? Remove from group — access revoked immediately.