IAM Deep Dive
IAM answers one question:
Who can do what on which resource under which conditions?For interviews and production work, the important part is understanding policy evaluation order, temporary credentials, and guardrails.
Core Model
- Principal: user, role, service, or federated identity making the request
- Action: API operation like
s3:GetObjectordynamodb:PutItem - Resource: ARN the action targets
- Condition: extra checks such as IP range, MFA, tags, or time window
Minimal example:
json{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::app-assets/*"
}
]
}How AWS Evaluates Permissions
Evaluation is easier if you remember these rules:
- Start with implicit deny.
- Collect matching identity-based and resource-based policies.
- Apply permission boundaries and SCPs as caps.
- If any explicit deny matches, the request is denied.
- Otherwise an allow succeeds only if something explicitly allows it.
Think of it like:
Implicit deny
+ matching allows
- explicit denies
capped by boundaries / SCPsUsers vs Roles vs Federation
Users
Long-lived credentials for humans. Fine for small labs, but avoid for applications.
Roles
Preferred for workloads. The app assumes a role and receives temporary credentials from STS.
Federation
Humans authenticate with Google, Okta, Azure AD, or IAM Identity Center, then assume roles instead of managing AWS passwords directly.
Production default:
- Humans: SSO / federation
- Apps on AWS: IAM roles
- Apps outside AWS:
AssumeRolewith OIDC or external identity
Resource Policies vs Identity Policies
Use identity policies when you control the caller.
Use resource policies when the resource must trust another principal directly.
Common examples:
- S3 bucket policy
- KMS key policy
- SNS topic policy
- SQS queue policy
- IAM role trust policy
Trust policy example:
json{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "ecs-tasks.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}This policy does not grant S3 or DynamoDB access. It only says who may assume the role.
Permission Boundaries and SCPs
These are often confused.
Permission Boundary
Attached to a user or role. It limits the maximum permissions that principal can ever receive.
SCP
Applied at the AWS Organization account or OU level. It limits the maximum permissions for the entire account subtree.
Good mental model:
- Identity policy says "may do X"
- Boundary says "not above this ceiling"
- SCP says "the org never allows this"
Conditions Matter
Conditions are where IAM becomes powerful.
Useful patterns:
- Require MFA for sensitive actions
- Restrict access to specific VPC endpoints
- Allow access only when tags match
- Limit role assumption by source account or external ID
Example:
json{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::reports/*",
"Condition": {
"StringEquals": {
"aws:PrincipalTag/team": "analytics"
}
}
}This is how attribute-based access control (ABAC) usually starts.
Common Production Patterns
EC2 / ECS / Lambda Accessing AWS APIs
Attach a role to the workload. Never hardcode access keys in config files.
Cross-Account Access
Create a role in Account B that trusts Account A, then let Account A assume it.
GitHub Actions Deploying to AWS
Use OIDC federation instead of storing long-lived AWS secrets in GitHub.
S3 Uploads from Browser
Give the backend permission to create a pre-signed URL, not blanket bucket credentials to the browser.
Failure Modes to Watch
- Overusing
Resource: "*"for convenience - Mixing trust policy and permission policy concepts
- Forgetting explicit denies from SCPs or bucket policies
- Using users with permanent keys for workloads
- Not rotating away from shared admin roles
- Debugging by attaching
AdministratorAccessand forgetting to remove it
Interview Answers
How do you design least privilege in AWS?
Start from roles, not users. Grant the smallest resource scope possible, add conditions where useful, and use boundaries or SCPs for blast-radius control.
Why use roles instead of access keys?
Roles issue short-lived credentials automatically, reduce secret sprawl, rotate by default, and integrate cleanly with EC2, ECS, Lambda, and federation.
What wins when policies conflict?
Explicit deny always wins. Otherwise, some explicit allow must match for access to succeed.