IAM
Examples of S3 bucket policies
IAM Explained, IAM Roles Explained
IAM is a framework for managing permissions
Permissions define which actions an identity can perform on a specific set of resources.
IAM ensures that the appropriate set of identities have access to the right resources at the right time.
At its core:
IAM = Identities + Permissions + Policies governing how identities interact with AWS resources.
The IAM Root User
The Root User is the identity that is created when you first open an AWS account. It has unrestricted access to everything in that account.
✔ What the Root User can do
Close the AWS account
Change payment methods
Access and modify billing information
Change Support Plans
Create or delete the very first admin IAM user
Enable/disable MFA for itself
Access all AWS resources (no restrictions)
✔ Why Root should not be used
Root is too powerful. Using it for daily work exposes you to:
Accidental destructive actions
Account takeovers
Unrecoverable misconfigurations
⭐ AWS Best Practice
Log in as root once.
Immediately configure:
MFA (preferably hardware key)
Strong password
Create an Administrator IAM user or role
Never use the root user again except in the rare scenarios above.
IAM Users
An IAM User is a long-term identity for a person or application that needs access to AWS.
Each user has:
Credentials (username/password for console)
Access keys (if needed for API/CLI)
Permissions granted via policies
When to use IAM Users
Humans who log into the AWS Console
Legacy applications that cannot assume roles (avoid when possible)
Best practice
Use roles for applications (highly preferred). It is best to assign IAM roles to applications (e.g., running on EC2, Lambda, ECS) instead of embedding access keys in code or containers. Roles provide temporary credentials automatically managed and rotated by AWS, enhancing security and eliminating the need to store long-lived keys.
Use SSO for people if possible. AWS Single Sign-On (SSO), also called AWS IAM Identity Center, is recommended for user access because it issues short-lived credentials and supports centralized access and multi-factor authentication (MFA), which strengthens security.
Avoid access keys — use temporary credentials instead: Permanent access keys for IAM users or root accounts are discouraged. Temporary credentials obtained via roles or federated login have a limited lifetime, reducing the risk if credentials are compromised. These temporary credentials expire and are automatically revoked, so they are much safer than long-term keys.
IAM Groups
A Group is a collection of users that share permissions.
Why Groups?
Easier permission management
Apply least privilege consistently
Examples:
DevelopersData-Engineering-TeamSecurity-TeamReadOnlyUsers
Users can belong to multiple groups, and groups contain only permissions, not credentials.
IAM Roles
IAM Roles are identities without long-term credentials.
Instead:
They are assumed temporarily
AWS issues temporary security credentials valid for minutes–hours
Roles solve major security issues:
✔ Applications shouldn’t use access keys → use an IAM Role on:
EC2
ECS task
Lambda function
EKS service account
Glue job
SageMaker notebook
✔ Humans shouldn’t work with overly privileged IAM Users → assume an Admin Role, Developer Role, etc.
Common types of roles
Service Role (AWS service assumes it, e.g., Lambda)
Assumable Role for Humans (via AWS SSO or console)
Cross-account Role (allow Account A users to access Account B)
IAM Policies (the heart of permissions)
A policy is a JSON document that defines permissions. Policies get attached to users, groups, or roles.
Structure of a JSON IAM Policy
Key Components
Effect
Allow or Deny
Action
The API operations permitted
Resource
The ARN(s) the action applies to
Condition
Optional, adds fine-grained control
Policy Types
1. AWS Managed Policies
Pre-built by AWS. Examples:
AdministratorAccessAmazonS3ReadOnlyAccessAmazonEC2FullAccess
Good for quick setup; not ideal for strict least privilege.
2. Customer Managed Policies
Created by you. These are best practice for real environments.
Created and stored separately in IAM
Independent of any user/role
Reusable across multiple identities
Easy to version, update, audit, and manage
Follow best-practice principle of separation of concerns
Fine for CI/CD and GitOps workflows
If you adjust one customer-managed policy:
Every user/role attached to it gets updated permissions automatically.
This makes permission changes:
Scalable
Consistent
Auditable
Traceable
Maintainable
3. Inline Policies
Policies attached directly to a single user, group, or role. Use sparingly — hard to manage.
They live inside the identity
They cannot be reused
They disappear if you delete the identity
Harder to track, audit, and version control
Example Problem:
If you attach an inline policy to DeveloperUser1, and then you later want to give the same permissions to DeveloperUser2, you must manually recreate that policy.
Inline policies are OK only in edge cases:
You want a policy that must be unique and tied directly to an identity (rare).
Permission Granularity
IAM provides extremely fine-grained control:
Control by:
Service Example: “Allow DynamoDB only, block S3.”
Action level Example:
s3:GetObjectalloweds3:PutObjectdenied
Resource level Example: Limit to:
a specific bucket
a specific prefix
a specific DynamoDB table
Condition level (very powerful) Examples:
Allow only during business hours
Allow only from a certain VPC
Allow access only via MFA
Allow based on IP range
Allow only when using HTTPS
Trust Policies vs Permissions Policies
Roles have two kinds of policies:
1. Trust Policy (controls who can assume?)
A trust policy is attached to a role and defines who is allowed to obtain temporary credentials for that role.
It uses "Principal" to specify:
AWS services (Lambda, EC2, Glue, etc.)
IAM users or roles
External AWS accounts
Identity Center users (via assumed role)
Federated identities (OIDC/SAML providers)
Example: Lambda Service Role Trust Policy
This means: “Lambda is allowed to assume this role.”
Another example: Let users in another account assume a cross-account role.
This means: “Account 111122223333’s DevTeam role is allowed to assume this role.”
2. Permissions Policy (controls what can they do once assumed?)
Like any other IAM policy.
A role’s permissions policy defines what actions AWS will allow using the temporary credentials.
They define:
allowed actions (
Action)allowed resources (
Resource)optional conditions
Example:
This means: “Once assumed, this role can get/put objects in mybucket.”
This separation is crucial for understanding IAM.
They have different purposes, different JSON formats, and different evaluation times.
Think of it like this:
Trust Policy = door access (who can enter the role) Permission Policy = what they can do inside once they enter
Trust policy does NOT grant AWS access rights
A trust policy does not allow actions on AWS services.
This is a common misconception.
A trust policy only gives permission to assume the role.
A permissions policy determines what the temporary credentials can do.
You need both for a role to be usable.
3️⃣ How They Work Together (Step-by-Step)
Here's the flow when something assumes a role:
Step 1 — Caller tries to assume the role
Caller could be:
EC2 instance profile
Lambda function
Another role
A user via console
AWS SSO identity
Step 2 — AWS checks the trust policy
If trust policy contains:
Effect: Allowcorrect
PrincipalAction: sts:AssumeRole
→ Caller receives temporary credentials. If not, assumption is denied even if the caller’s own IAM policies allow it.
Step 3 — Caller uses temporary credentials
Now AWS evaluates:
the role’s permission policies
the caller’s session policies (if any)
service control policies (SCPs)
permission boundaries
This determines what they can actually do.
🔑 Real-World Analogy
Imagine a secure lab.
Trust Policy
The security guard at the entrance. It asks:
Who are you?
Are you allowed to come inside at all?
If you’re not on the list → you never get inside.
Permission Policy
Once you're inside, your badge only opens the rooms and equipment you’re allowed to use.
You may enter the lab (trust policy allowed it)
But maybe you can only use microscopes, not centrifuges (permissions policy)
Different control layers.
Common Examples
🟦 EC2 Instance Assuming a Role
Trust Policy — allows EC2 service:
Permissions Policy — e.g. allow reading from S3:
🟩 Human user assuming AdminRole
Trust Policy:
Permissions Policy:
AdministratorAccess or a custom policy.
🟧 Cross-account access
Account A trusts principals from Account B.
Account A Trust Policy:
Now Account B’s DataEngineers can assume the role. Once inside, the role’s permission policy controls what they can do.
5️⃣ How to Identify Which Is Which (Quick Visual)
Trust Policy format:
Contains
"Principal"Contains
"sts:AssumeRole"Always attached to a role
Controls who can assume the role
Permission Policy format:
Contains
"Action"Contains
"Resource"Can be attached to roles, users, groups
Controls what they can do
IAM Boundaries and Advanced Controls
Permissions Boundary
Cap the maximum permissions an IAM entity can have.
Use cases:
Delegating IAM administration safely
Preventing privilege escalation
Service Control Policies (SCPs) (Organizations)
Apply to AWS accounts, not users.
Examples:
“No one can create public S3 buckets”
“Disable EC2 in this account entirely”
Resource-based Policies
Define permissions on the resource itself.
Examples:
S3 bucket policies
KMS key policies
Lambda resource policies
SQS queue policies
These differ from identity-based IAM policies.
Mental Model Summary
If you remember only this:
Users = people (but ideally use SSO)
Groups = permission collections for users
Roles = identities assumed temporarily (ideal for apps)
Policies = JSON documents defining permissions
Root = only for emergencies
SCPs = guardrails for entire AWS accounts
Roles (most recommended) > Users (sometimes necessary) > Access Keys (avoid when possible). This is a priority hierarchy for how identities should be created and granted permissions in AWS.
IAM is all about least privilege + temporary credentials.
What is ARN?
An ARN is a globally unique identifier for any AWS resource.
Think of it as the absolute path to a resource—like a file path on a computer, but for cloud objects.
📌 ARN Format
🔍 Breakdown
arn
Literal prefix indicating an ARN
partition
Usually aws (could be aws-us-gov, aws-cn)
service
AWS service, e.g., s3, ec2, kms
region
Region code like us-east-1 (some resources are global → * or empty)
account-id
AWS account ID (some services don't use it)
resource
The resource name, path, or ID
⭐ Examples Across Services
S3 bucket
(S3 is global, no region or account)
S3 object
EC2 instance
IAM role
Lambda function
DynamoDB Table
KMS Key
⭐ Why ARNs Matter in IAM Policies
Policies often refer to resources using ARNs to enforce fine-grained permissions:
Example: Allow access only to a specific S3 folder
Example: Allow only one EC2 instance
Without ARNs, AWS wouldn’t know which specific resource you’re granting access to.
IAM Best Practices (the ones AWS expects you to know)
🔐 Identity Management
Do not use root except when absolutely necessary
Enable MFA for root + all privileged users
Use IAM Roles, not access keys
Rotate access keys if they exist (better: eliminate them)
Adopt AWS IAM Identity Center (SSO) for human users
🪪 Permissions
Apply least privilege
Prefer customer-managed policies
Avoid attaching
AdministratorAccessexcept for break-glass roles
🧱 Architecture
Use resource isolation via AWS Organizations accounts
Use SCPs for guardrails
Use roles for workloads
🔍 Observability
Enable CloudTrail everywhere
Enable Access Analyzer
Review IAM Access Advisor for unused permissions
📝 Operational Security
No sharing accounts
No hardcoding credentials in repos or apps
Use temporary credentials ALWAYS
Create automation for lifecycle of users and roles
Last updated