IAM Fundamentals: Users, Groups, Roles, and Policies
Overview
AWS Identity and Access Management (IAM) is the foundational service for controlling access to AWS resources. It enables you to manage authentication (who can sign in) and authorization (what permissions they have) for your AWS account.
IAM is a global service - it's not region-specific. When you create an IAM user or role, it's available across all AWS regions. Understanding IAM is critical for the SAA-C03 exam, as security accounts for 30% of the exam content, and IAM questions appear in nearly every domain.
Key Principle
IAM follows the principle of least privilege - grant only the permissions required to perform a task, nothing more. This is the most important security concept you need to understand for the exam.
IAM questions appear in nearly every exam domain - expect 8-10 questions on IAM alone. Focus on understanding when to use roles vs users, and how policy evaluation works.
Architecture Diagram
The following diagram illustrates the core components of AWS IAM and how they interact:

Key Concepts
IAM Users
IAM Users
An IAM user represents a person or application that interacts with AWS. Each user has a unique identity within your AWS account.
User Credentials:
- Console password - For AWS Management Console access
- Access keys - For programmatic access (CLI, SDK, API)
- Consists of Access Key ID + Secret Access Key
- Maximum of 2 access keys per user
Important Characteristics:
- Users are created with no permissions by default
- Each user can belong to multiple groups (up to 10)
- Permissions can be assigned directly or through groups
- Users can have both console and programmatic access
- ARN format:
arn:aws:iam::account-id:user/username
IAM Groups
IAM Groups
An IAM group is a collection of IAM users. Groups simplify permission management by allowing you to assign policies to multiple users at once.
Key Characteristics:
- Groups contain users only - you cannot nest groups within groups
- A user can belong to multiple groups (up to 10)
- Groups don't have credentials - they're purely for organizing users
- When a policy is attached to a group, all members inherit those permissions
- Groups do NOT have their own identity - they cannot be referenced as a principal
IAM Roles
IAM Roles
An IAM role is an identity with specific permissions that can be assumed by trusted entities. Unlike users, roles don't have permanent credentials - they provide temporary security credentials.
Who Can Assume Roles:
- IAM users (same or different account)
- AWS services (EC2, Lambda, etc.)
- External users via federation (SAML, OIDC)
- Applications
Role Components:
- Trust Policy - Defines who can assume the role
- Permissions Policy - Defines what the role can do
Common IAM Role Use Cases
| Use Case | Description | Example |
|---|---|---|
| EC2 Instance Role | Allow EC2 instances to access other AWS services | EC2 reading from S3 bucket |
| Cross-Account Access | Allow users from Account B to access Account A resources | Shared S3 bucket access |
| Federation | Allow external identity providers to grant AWS access | Corporate AD users accessing AWS |
| Service-Linked Role | Predefined role for specific AWS services | Auto Scaling managing EC2 |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}IAM Policies
IAM Policies
Policies are JSON documents that define permissions. They specify what actions are allowed or denied on which resources.
Policy Types:
- Identity-Based - Attached to users, groups, or roles
- Resource-Based - Attached directly to resources (S3, SQS, etc.)
- Permissions Boundary - Sets maximum permissions for users/roles
- Service Control Policy (SCP) - Organization-level guardrails
- Session Policy - Limits permissions for assumed role sessions
IAM Policy Types Comparison
| Type | Attached To | Use Case |
|---|---|---|
| Identity-Based | Users, Groups, Roles | Define what an identity can do |
| Resource-Based | Resources (S3, SQS) | Define who can access the resource |
| Permissions Boundary | Users, Roles | Set maximum permissions |
| Service Control Policy | AWS Organizations | Set guardrails for accounts |
| Session Policy | Temporary sessions | Limit assumed role permissions |
How It Works
Policy Document Structure
Every IAM policy follows this JSON structure:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3ReadAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "192.168.1.0/24"
}
}
}
]
}Policy Elements Explained
| Element | Required | Description |
|---|---|---|
| Version | Yes | Always use 2012-10-17 |
| Statement | Yes | Array of permission statements |
| Sid | No | Statement identifier (for documentation) |
| Effect | Yes | Allow or Deny |
| Principal | Conditional | Who the policy applies to (resource-based only) |
| Action | Yes | List of actions (e.g., s3:GetObject) |
| Resource | Yes | ARN of resources the actions apply to |
| Condition | No | Conditions that must be met |
Policy Evaluation Logic
When a request is made, AWS evaluates all applicable policies:

Policy Evaluation Rules
- Explicit Deny always wins over any Allow
- Implicit Deny is the default when no policy matches
- Policies are evaluated using logical OR (any Allow grants access)
- Within Organizations: SCPs further restrict effective permissions
Policy Evaluation Flow Diagram

Managed vs. Inline Policies
Managed vs Inline Policies
| Aspect | Managed Policies | Inline Policies |
|---|---|---|
| Reusability | Can attach to multiple identities | One-to-one relationship |
| Maintenance | Update once, applies everywhere | Must update each identity |
| Versioning | Supports up to 5 versions | No versioning |
| Deletion | Exists independently | Deleted with identity |
| AWS Provided | Yes (AWS managed policies) | No |
| Recommended | Yes (preferred approach) | Only for strict 1:1 relationships |
Use Cases
Use Case 1: Development Team Access
Scenario: A team of 5 developers needs read/write access to a specific S3 bucket and read-only access to DynamoDB.
Solution:
- Create an IAM group called
Developers - Attach two managed policies to the group
- Add all 5 developers to the group
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::dev-bucket",
"arn:aws:s3:::dev-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan"
],
"Resource": "arn:aws:dynamodb:*:*:table/dev-table"
}
]
}Use Case 2: EC2 Instance Accessing S3
Scenario: An EC2 instance running an application needs to upload files to S3.
Solution:
- Create an IAM role for EC2
- Attach a policy granting S3 write access
- Attach the role to the EC2 instance (Instance Profile)
Why Role over Access Keys?
- No credentials stored on the instance
- Credentials are automatically rotated by AWS
- Permissions can be changed without modifying the application
- Much more secure and is the recommended approach
Use Case 3: Cross-Account Access
Scenario: Account B users need to access an S3 bucket in Account A.
Solution:
- In Account A: Create a role with trust policy allowing Account B
- In Account A: Attach S3 access policy to the role
- In Account B: Grant users permission to assume the role
Best Practices
IAM Best Practices
- Follow Least Privilege - Start with minimum permissions, add as needed
- Use Roles Instead of Access Keys - Roles provide temporary, auto-rotating credentials
- Enable MFA for Privileged Users - Require MFA for console access and sensitive operations
- Use Groups for Permission Management - Never attach policies directly to users
- Regularly Review and Audit - Use IAM Credential Report and Access Advisor
- Use AWS Managed Policies When Possible - Automatically updated by AWS
Common Exam Scenarios
Exam Scenarios and Solutions
| Scenario | Solution | Why |
|---|---|---|
| Application on EC2 needs DynamoDB access | Create IAM role, attach to EC2 | Roles provide temporary credentials, more secure than access keys |
| User needs admin access only during emergencies | Create role with admin permissions, user assumes role when needed | Separation of duties, auditable |
| External contractors need temporary AWS access | Use IAM roles with federation or IAM Identity Center | No permanent IAM users for temporary staff |
| Prevent accidental S3 bucket deletion | Use SCP to deny s3:DeleteBucket at organization level | SCPs provide guardrails across accounts |
| Application needs to call AWS APIs | Use IAM role (if on AWS) or IAM user with access keys (if external) | Roles preferred; access keys only when necessary |
Common Pitfalls
Pitfall 1: Using Root Account for Daily Tasks
Mistake: Using the root account email/password for regular operations.
Why it's dangerous:
- Root has unlimited access that cannot be restricted
- Cannot be restricted by IAM policies
- No audit trail for specific actions
Correct Approach:
- Create IAM users for all operations
- Enable MFA on root account
- Use root only for account-level tasks (billing, closing account)
Pitfall 2: Embedding Access Keys in Code
Mistake: Hardcoding access keys in application code or config files.
Why it's dangerous:
- Keys can be exposed in version control
- Difficult to rotate
- No automatic expiration
Correct Approach:
- Use IAM roles for AWS resources
- Use environment variables or AWS Secrets Manager
- Rotate keys regularly if they must be used
Pitfall 3: Overly Permissive Policies
Mistake: Using "Action": "*" and "Resource": "*" for convenience.
Why it's dangerous:
- Violates least privilege principle
- Increases blast radius of compromised credentials
- Makes compliance and auditing difficult
Correct Approach:
- Specify exact actions needed
- Limit to specific resources using ARNs
- Use conditions to further restrict access
Test Your Knowledge
What is the maximum number of access keys an IAM user can have?
Which statement about IAM groups is TRUE?
An application running on EC2 needs to access S3. What is the BEST approach?
Related Services
Quick Reference
ARN Format
arn:aws:iam::account-id:user/user-name
arn:aws:iam::account-id:group/group-name
arn:aws:iam::account-id:role/role-name
arn:aws:iam::account-id:policy/policy-nameCommon IAM Actions
Common IAM Actions
| Action | Description |
|---|---|
| iam:CreateUser | Create an IAM user |
| iam:AttachUserPolicy | Attach managed policy to user |
| iam:CreateRole | Create an IAM role |
| sts:AssumeRole | Assume an IAM role |
| iam:PassRole | Pass a role to a service |
IAM Limits
IAM Service Limits
| Resource | Default Limit |
|---|---|
| Users per account | 5,000 |
| Groups per account | 300 |
| Roles per account | 1,000 |
| Managed policies per account | 1,500 |
| Groups per user | 10 |
| Access keys per user | 2 |
