AWS IAM Explained: Users, Policies, Groups, Roles and Access Control
When working with AWS, one of the most important concepts to understand is IAM — Identity and Access Management.
AWS provides services such as S3, EC2, DynamoDB and Lambda, but simply having an AWS account does not mean every person or application should have access to everything.
For example:
- A developer may need to read objects from S3.
- A DevOps engineer may need to restart EC2 instances.
- A finance employee may need access to billing information.
- An application may need temporary access to another AWS service.
This is where AWS IAM comes into the picture.
The fundamental question IAM helps answer is:
Who wants to perform what action on which resource?
Your notes describe this as:
Identity X
↓
wants to perform
↓
Action Y
↓
on
↓
Resource Z
For example:
User: Shrayansh
Action: S3:GetObject
Resource: bucket-prod/*
This basic model is introduced on page 1 of the provided material.
1. What Is AWS IAM?
IAM stands for Identity and Access Management.
IAM allows you to control:
- Who can access AWS
- What they can do
- Which resources they can access
- Whether access is temporary or long-lived
For example, imagine an AWS account containing:
AWS Account
│
├── S3
├── EC2
├── DynamoDB
├── Lambda
└── Other AWS Services
You may have several people working with these resources:
Developer
DevOps Engineer
Finance Employee
Administrator
Giving everyone full access would be dangerous.
Instead, IAM allows you to create separate identities and give them only the permissions they require.
The source material explains that a single Root User is not sufficient for a real organization because different team members require different permissions.
2. Why Can’t We Just Use the Root User?
When an AWS account is created, there is a Root User.
The Root User has extremely powerful access to the AWS account.
The provided notes emphasize that the Root User can perform highly privileged operations, including potentially deleting the account, which makes sharing Root credentials across a team risky.
Imagine a company with this team:
AWS Account
│
┌────────────────┼────────────────┐
│ │ │
Developer DevOps Finance
The requirements might be:
Developer
→ Debug application
→ Read S3
→ Cannot delete database
DevOps
→ Manage EC2
→ Manage Load Balancers
Finance
→ Read billing information
If everyone uses the same Root credentials, there is no meaningful separation of permissions or accountability.
IAM solves this by allowing multiple identities with different permissions.
3. The Four Important IAM Concepts
The main concepts covered in the material are:
IAM
│
├── User
├── Policy
├── Group
└── Role
Each has a different purpose.
Let’s understand them one by one.
4. IAM User
An IAM User represents an identity that needs AWS access.
According to the notes, a User can represent:
- A human
- A long-lived program
An IAM User has an ARN (Amazon Resource Name) and can have credentials such as:
- Username/password for console access
- Access Key ID and Secret Access Key for programmatic access
For example:
IAM User
│
├── Username
├── Password
├── Access Key ID
├── Secret Access Key
└── ARN
5. Creating an IAM User
The document demonstrates creating an IAM User through the AWS Console.
The basic flow shown is:
IAM
↓
Users
↓
Create User
↓
Provide Username
↓
Set permissions
The screenshots in pages 4–7 demonstrate the creation process and enabling console access.
For example:
Username:
Shrayansh
Then console access can be enabled and a password configured.
6. What Happens If We Create a User Without Permissions?
This is one of the most useful demonstrations in the document.
After creating the user, the user attempts to access AWS services.
The result is:
Access Denied
Why?
Because the user has not yet been granted the required permissions.
The document demonstrates that the newly created user sees Access Denied, including when attempting to access S3.
This gives us an important IAM concept:
Creating an identity and granting permissions are two different things.
7. What Is an IAM Policy?
Now we have a user.
But AWS still needs to know:
What is this user allowed to do?
That’s the job of an IAM Policy.
A policy describes permissions.
A simplified policy can answer:
Who?
What action?
Which resource?
Allow or deny?
The document explains that after authentication identifies the user, the policy determines whether the requested operation is allowed.
8. Basic IAM Policy Structure
An IAM policy is written in JSON.
For example, the document uses a policy similar to:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-prod/*"
}
]
}
Let’s understand each field.
Version
"Version": "2012-10-17"
This identifies the policy language version used in the policy example.
Effect
"Effect": "Allow"
Specifies whether the statement allows or denies an action.
Action
"Action": "s3:GetObject"
Specifies the AWS API operation.
Resource
"Resource": "arn:aws:s3:::bucket-prod/*"
Specifies the resource to which the permission applies.
These components are illustrated on page 11 of the source.
9. The Most Important IAM Question
Whenever you see an IAM policy, break it into:
WHO?
WHAT?
WHICH RESOURCE?
For example:
WHO
↓
User-1
WHAT
↓
s3:GetObject
WHICH
↓
bucket-prod/*
This simple approach makes IAM policies much easier to understand.
10. Identity-Based Policies
An Identity-Based Policy is attached to an IAM identity.
The source describes this as a policy attached to an IAM entity such as:
- User
- Group
- Role
For example:
User
│
│ attached
↓
Policy
The policy can say:
Allow:
s3:GetObject
Resource:
bucket-prod/*
The diagram and policy example in the document illustrate this relationship.
11. Resource-Based Policies
A Resource-Based Policy is attached directly to a resource.
For example:
User
↓
Access
↓
S3 Bucket
↑
│
Policy attached
The source demonstrates this using an S3 bucket policy.
A resource-based policy contains a Principal, which identifies who is allowed or denied access.
The document notes that the Principal can represent things such as:
- User
- Role
- AWS account
- AWS service
12. Identity-Based vs Resource-Based Policy
The easiest way to remember the difference is:
Identity-Based Policy
USER
↓
POLICY
The policy is attached to the identity.
Resource-Based Policy
RESOURCE
↓
POLICY
The policy is attached to the resource.
For example:
Identity-based:
Shrayansh
↓
Policy
↓
S3:GetObject
Whereas:
Resource-based:
S3 Bucket
↓
Bucket Policy
↓
Principal: Shrayansh
The source explicitly presents these two policies as having the same basic permission purpose but a different perspective.
13. Creating an Identity-Based Policy
The document demonstrates creating a policy through:
IAM
↓
Policies
↓
Create Policy
↓
JSON
An example shown uses:
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
In the notes:
s3:*
means all S3 API operations, while:
Resource: *
represents all matching resources.
After creating the policy, it can be attached to an IAM User through the User’s Permissions section.
14. Why Did Access Start Working?
Initially:
User
↓
S3
↓
Access Denied
After attaching an appropriate policy:
User
↓
IAM Policy
↓
S3
↓
Access Allowed
The document demonstrates the change through the AWS Console and Postman.
This is a very important concept when troubleshooting AWS permissions.
15. A Real Example: S3 Access
Suppose an application needs access to:
sj-payment-prod
The resource-based policy shown in the document grants permissions to a specific principal for:
s3:*
on:
arn:aws:s3:::sj-payment-prod
arn:aws:s3:::sj-payment-prod/*
The document then tests the permission using a Spring Boot controller and AWS SDK’s S3Client.
This is particularly useful for Java developers because it demonstrates how IAM permissions affect a real Spring Boot application.
16. IAM and Spring Boot
The source includes a Java/Spring example:
@RestController
@RequestMapping("/s3")
public class S3Controller {
@Autowired
private S3Client s3Client;
@GetMapping("/bucket-location")
public String bucketLocation() {
try {
String bucketName = "sj-payment-prod";
return s3Client.getBucketLocation(
request -> request.bucket(bucketName)
).locationConstraintAsString();
} catch (Exception e) {
return e.getMessage();
}
}
}
The purpose of the example is to call an S3 operation against a specific bucket and observe whether IAM permissions allow the operation.
For a Java/Spring Boot developer, this is a good way to understand that:
AWS SDK code can be perfectly correct while the request still fails because of IAM permissions.
17. Why Can the AWS Console Show Access Denied While the API Works?
This is an interesting scenario demonstrated in the document.
Suppose your policy allows access to one specific bucket:
sj-payment-prod
But when you open the S3 bucket page, the AWS Console may need additional permissions to list or display multiple buckets.
The source explains that the S3 UI attempts to load bucket resources, while the policy in the example is restricted to a specific resource. Therefore, the API operation against the specific resource can work even though the broader console page displays Access Denied.
This is an important troubleshooting lesson:
Access to a specific API operation does not necessarily mean the AWS Console can display every related resource.
18. IAM Policy Evaluation
One of the most important parts of IAM is understanding how AWS evaluates permissions.
The source presents the simplified order as:
Explicit DENY
>
Explicit ALLOW
>
Implicit DENY
Let’s understand it.
19. Explicit Deny
Suppose one policy says:
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
But another applicable policy says:
{
"Effect": "Deny",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::sj-payment-prod/*"
}
Now the user tries:
GetObject(test.txt)
One policy says:
ALLOW
Another says:
DENY
The explicit deny wins.
The source demonstrates this exact type of scenario.
So remember:
Explicit Deny overrides Allow.
20. Implicit Deny
What happens if there is simply no policy granting permission?
Then the request is denied by default in the simplified policy model used in the notes.
For example:
User
↓
GetObject
↓
No applicable Allow
↓
Implicit Deny
The document illustrates this as Case 2: Implicit Deny.
21. Allow
Now suppose we have:
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
and there is no applicable explicit deny.
The requested operation can be allowed.
The source presents this as Case 3: Allow.
22. IAM Groups
Now imagine you have 50 developers.
Would you want to attach the same policy to every developer individually?
That would be difficult to manage.
This is where an IAM Group is useful.
The source describes a Group as a container for Users. A Group is not itself an identity, so you don’t sign in as a Group or generate credentials for it. Its main benefit is that policies attached to the Group apply to its Users.
For example:
BackendEngineer Group
|
├── User-1
├── User-2
├── User-3
└── User-4
Attach policies once:
BackendEngineer
|
├── S3
└── DynamoDB
Then users in the group receive those permissions through the group.
The source gives a similar BackendEngineer example with S3 and DynamoDB policies.
23. Why Are Groups Useful?
Without groups:
User 1 → Policy
User 2 → Policy
User 3 → Policy
User 4 → Policy
...
User 50 → Policy
With a group:
Policy
↓
BackendEngineer
/ / \ \
↓ ↓ ↓ ↓
User1 User2 User3 User4
This makes permission management easier.
If the policy needs to change, you can manage the group’s permissions instead of manually updating every user.
24. IAM Role
Now we reach one of the most important IAM concepts:
IAM Role.
The source describes an IAM Role as providing a temporary identity rather than relying on long-lived AWS Access Keys and Secret Keys.
Imagine:
Intern
↓
Normally has limited S3 permissions
But suppose the intern needs elevated permissions temporarily for one hour.
Instead of giving the intern permanent credentials with higher privileges, we can create a role:
SeniorSDERole
Attach the required permissions to the role and allow the appropriate identity to assume it.
25. Role Example
The document uses this scenario:
INTERN
→ S3 Read
SDE-3
→ S3 Read + Write
But temporarily:
INTERN
→ Needs SDE-3 permissions
→ For 1 hour
A role can be used:
Intern
↓
Assume Role
↓
SeniorSDERole
↓
Temporary permissions
This avoids permanently changing the intern’s normal permissions.
26. Trust Policy vs Permissions Policy
This is one of the most important IAM Role concepts.
A role involves two different questions:
Trust Policy
Who is allowed to assume this role?
Permissions Policy
What can the role do after it is assumed?
Think:
IAM ROLE
│
┌─────────┴─────────┐
↓ ↓
Trust Policy Permissions Policy
│ │
WHO can use it? WHAT can it do?
The document demonstrates a Trust Policy containing:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::...:user/Shrayansh"
},
"Action": "sts:AssumeRole"
}
This means the specified identity is allowed to invoke sts:AssumeRole for the role.
27. What Is AssumeRole?
AWS Security Token Service, or STS, provides the mechanism for assuming a role.
The basic flow is:
Shrayansh
|
| sts:AssumeRole
↓
SeniorSDERole
|
↓
Temporary credentials
|
↓
AWS resources
The document shows an identity policy granting permission to invoke sts:AssumeRole on the SeniorSDERole.
28. Creating the Role
The document demonstrates:
IAM
↓
Roles
↓
Create Role
↓
Custom Trust Policy
↓
Add Permissions
↓
Provide Role Name
↓
Create Role
The screenshots on pages 34–36 show the custom trust policy and permission policy configuration.
29. Why Does the User Still Get Access Denied After Getting the Role?
This is another important point from the example.
The document shows that after the role is assigned to Shrayansh, access can still be denied.
Why?
Because simply having the role available is not the same as assuming the role.
The notes explain that the user needs to assume the role to receive the role’s permissions temporarily.
So the flow is:
Role exists
↓
User is allowed to assume it
↓
User actually assumes role
↓
Temporary permissions become active
30. Switching to the Role in AWS Console
The source demonstrates the console process:
Login as Shrayansh
↓
Switch Role
↓
SeniorSDERole
↓
Role assumed
↓
S3 access works
After the role is assumed, the document shows the user successfully accessing S3.
This is a practical demonstration of how IAM Roles work.
31. IAM User vs Group vs Policy vs Role
Let’s summarize the four concepts.
| IAM Concept | Purpose |
|---|---|
| User | Represents an identity |
| Policy | Defines permissions |
| Group | Organizes Users and shares policies |
| Role | Provides permissions through temporary role assumption |
A simple diagram:
IAM
|
┌───────────┼────────────┐
↓ ↓ ↓
User Group Role
| | |
| ↓ ↓
| Users Temporary
| access
|
└──────────→ Policy
↓
Permissions
32. A Simple Real-World Analogy
Think of AWS as an office building.
User
A person who works in the building.
Employee = IAM User
Policy
The employee’s access card rules.
Policy =
"You can enter Room A and Room B."
Group
A department.
Backend Team
↓
Developer 1
Developer 2
Developer 3
The department can have common access rules.
Role
Temporary access.
For example:
“You normally cannot enter the production room, but for the next hour you are authorized to enter it.”
That’s similar to assuming a role with temporary permissions.
33. The Complete IAM Request Flow
Now let’s combine everything.
Suppose:
Shrayansh
tries to access:
S3
and wants to execute:
GetObject
The conceptual flow is:
API Request
│
↓
IAM
│
↓
Who is calling?
│
↓
What action?
│
↓
Which resource?
│
↓
Check policies
│
┌──────────┴──────────┐
↓ ↓
Explicit Deny? No Explicit Deny
│ │
YES ↓
│ Explicit Allow?
↓ │
DENIED ┌─────┴─────┐
↓ ↓
YES NO
│ │
ALLOWED DENIED
The source’s simplified policy evaluation flow emphasizes the precedence of explicit deny over allow and the default implicit deny.
34. IAM Troubleshooting Checklist
When you see:
AccessDenied
don’t immediately assume your Java or Spring Boot code is wrong.
Check these things:
1. Who is making the request?
IAM User?
Role?
Application?
2. What operation is being performed?
For example:
s3:GetObject
s3:ListBucket
3. Which resource is being accessed?
For example:
arn:aws:s3:::bucket-name/*
4. Is there an Allow?
Check applicable policies.
5. Is there an explicit Deny?
Remember:
Explicit Deny
>
Allow
6. Is the role actually assumed?
Having permission to assume a role is different from actually assuming it.
7. Is the AWS Console asking for additional permissions?
The document’s S3 example demonstrates why an API call to a specific resource can work while the broader console view still shows Access Denied.
35. IAM in a Java/Spring Boot Application
For Java developers, IAM becomes particularly important when using the AWS SDK.
For example:
Spring Boot Application
|
↓
AWS SDK
|
↓
S3 API
|
↓
IAM authorization
|
↓
Allow / Deny
Your Java code may contain:
s3Client.getBucketLocation(...);
But AWS still evaluates whether the identity making the request has permission to perform that operation.
The uploaded material demonstrates exactly this using a Spring Boot REST controller and S3Client.
36. Key IAM Concepts to Remember for Interviews
If you’re preparing for an AWS or Java microservices interview, remember these points:
IAM
AWS service used to manage identities and access permissions.
IAM User
Represents a human or long-lived program identity.
IAM Policy
Defines what actions are allowed or denied on resources.
Identity-Based Policy
Policy attached to a User, Group or Role.
Resource-Based Policy
Policy attached to a resource such as an S3 bucket.
IAM Group
Container for Users with common permissions.
IAM Role
Provides temporary permissions through role assumption.
Trust Policy
Defines who can assume a role.
Permissions Policy
Defines what the role can do after it is assumed.
Explicit Deny
Overrides an applicable Allow.
Implicit Deny
Access is denied when there is no applicable permission allowing the request.
37. Final IAM Architecture
You can remember the entire concept with this diagram:
AWS ACCOUNT
│
┌────┴────┐
│ IAM │
└────┬────┘
│
┌───────────────────┼───────────────────┐
│ │ │
USER GROUP ROLE
│ │ │
│ ┌────┴────┐ │
│ │ │ │
│ User-1 User-2 │
│ │
└──────────────┬─────────────────────────┘
│
POLICY
│
┌──────────┴──────────┐
│ │
Identity-Based Resource-Based
│ │
↓ ↓
IAM Entity Resource
│ │
└──────────┬──────────┘
↓
AWS SERVICE
│
┌──────┼──────┐
↓ ↓ ↓
S3 EC2 DynamoDB
Conclusion
AWS IAM is fundamentally about controlling access.
The easiest way to understand it is to ask three questions:
WHO? WHAT? WHICH?
WHO?
↓
User / Role / Principal
WHAT?
↓
AWS API Action
WHICH?
↓
AWS Resource
Then policies determine whether that request is allowed or denied.
The major IAM components are:
User
↓
Identity
Group
↓
Collection of Users
Policy
↓
Permissions
Role
↓
Temporary access
And when troubleshooting permissions, remember the core evaluation idea from the provided material:
Explicit DENY
↓
Explicit ALLOW
↓
Implicit DENY
Understanding these concepts gives you a strong foundation for working with S3, EC2, Lambda, DynamoDB and AWS SDKs in Spring Boot applications.
Source: This article is based on your uploaded IAM (User, Policy, Groups and Roles) notes, including the diagrams, AWS Console demonstrations, S3 examples, policy evaluation flow, and Spring Boot example.