IAM
6 pages · ~4 min✓ Reviewed
Start here. Next up: EC2 and VPC.
Users, Groups and Roles Mental Model
1. What IAM Is
- IAM is global: decides who (authN) can do what on which resource (authZ)
- Principals: users, roles, root
- A group only holds users: attach policies to it
- A group cannot nest groups or be a principal
2. User vs Role
| User | Role | |
|---|---|---|
| Credentials | permanent password / keys | none of its own |
| Gets access | signs in | assumed via STS |
| Lifetime | long-lived | 1 h default, 12 h max |
3. EC2 Instance Profile
- App on EC2
- Instance profilewraps role
- STS
- Temp keysrotate
Instance profile
Wraps a role: rotating credentials, no keys on disk
4. Interview Point
- Group as principal? No, it only carries policies for its users
- User vs role? User has permanent credentials; role has none
- Role credentials? Assumed via STS: temporary, 1 h default, 12 h max
- Who can assume a role? Principals named in its trust policy
Policies, Least Privilege and Evaluation Logic
1. Policies and evaluation
- Policy = JSON of statements:
Effect,Action,Resource, optionalCondition - Least privilege = only the actions and resources a task needs
- Implicit denythe default
- Explicit Deny?wins, stop
- Allow?needed to pass
2. Policy types
| Type | Attached to | Grants? |
|---|---|---|
| Identity-based | user, group, role | yes |
| Resource-based | bucket, role trust policy; names a Principal | yes |
| Permission boundary | user or role | no, max only |
| SCP | account or OU | no, max only |
3. Deny beats Allow
json
{"Effect": "Allow", "Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket/*"}
{"Effect": "Deny", "Action": "s3:*",
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"}}}Deny wins even though the Allow matches
- Deny on
aws:SourceIpor MFA false blocks access even if another policy allows it
Remember
Default is implicit deny. An Allow never overrides an explicit Deny.
- No matching policy? Implicit deny
- Allow over explicit Deny? Never
- SCP or boundary vs identity policy? Limit only, never grant
- Real permissions used? Access Analyzer, last accessed data
MFA, Root Account and Access Keys vs Roles
1. What They Are
- MFA = second factor on top of the password
- Types: virtual TOTP app, FIDO2 key, hardware token
- Root = all-powerful email identity made with the account
2. Locking Down Root
- Root gets MFA
- Root gets no access keys
- Root-only: change root email or password, close account, restore locked-out IAM admin
- Daily work: IAM user or IAM Identity Center
3. Keys vs Roles
| Access key | Role | |
|---|---|---|
| Prefix | AKIA... | ASIA... + session token |
| Lifetime | long-lived | temporary, auto-expires |
| Leaks via | code, git | little to leak |
| Use for | local CLI only | EC2, Lambda, CI |
4. Example: Enforce MFA
- Deny all but MFA setup when
aws:MultiFactorAuthPresentis false DeactivateMFADevicestays denied
json
"Effect": "Deny", "NotAction": ["iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:ListMFADevices", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "iam:GetUser", "sts:GetSessionToken"], "Condition": {"BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}}
Keys hygiene
Rotate or delete any access key unused for 90 days.
Everyday IAM Commands and Common Mistakes
1. The Everyday Loop
- Createuser, group
- Attachpolicy
- Testsimulate
- Reviewaccess data
aws sts get-caller-identityshows the principal your CLI usessimulate-principal-policytests an action before you ship
bash
aws iam create-user --user-name dev1 aws iam create-group --group-name devs aws iam add-user-to-group --group-name devs --user-name dev1 aws iam attach-group-policy --group-name devs \ --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess aws iam simulate-principal-policy --policy-source-arn ARN \ --action-names s3:GetObject
2. Policy Types
| Type | Traits |
|---|---|
| AWS managed | AWS-maintained, broad |
| Customer managed | reusable, tailored |
| Inline | embedded in one identity, dies with it |
3. Common Mistakes
AdministratorAccessor*on*to fix AccessDenied- Policies on users, not groups
- Keys committed to git
- Role needs a trust policy and a permissions policy
4. Interview Point
- Debug AccessDenied? Simulate it, then look for a Deny
- Managed vs inline? Managed to reuse; inline for strict one-to-one
- Who am I?
aws sts get-caller-identity - Principal
*? Anyone can assume the role
AWS IAM Cheat Sheet
1. Evaluation Order
- Implicit denythe default
- Explicit Denywins, stop
- Allowneeded to pass
Remember
Deny always beats Allow, in every policy.
2. Identities and Root
| Holds | Credentials | |
|---|---|---|
| Group | users only; policies attach here | none |
| User | one person or app | long-lived |
| Role | assumed by others | temporary |
- Root: enable MFA and delete its keys
- Root only for root-only tasks: change email, close account, unlock admin
- Everyone else: roles or IAM Identity Center
3. Commands and Keys
bash
aws sts get-caller-identity aws iam list-attached-user-policies --user-name X aws iam simulate-principal-policy \ --policy-source-arn ARN --action-names s3:GetObject
who am I, what is attached, would it be allowed
| Prefix | Key | Life |
|---|---|---|
AKIA | user access key | long-lived |
ASIA | role key + session token | temporary |
- Prefer roles over keys
- Rotate or delete unused keys
Check yourself
A group policy allows s3:* on everything. Another policy on the same user denies s3:DeleteObject. Can the user delete an object?
- No. An explicit Deny beats every Allow.
- Evaluation: implicit deny, then explicit Deny wins, else Allow.
A role has a policy allowing S3 read, yet EC2 gets AccessDenied on sts:AssumeRole. What is missing?
- The trust policy must name
ec2.amazonaws.comas Principal. - Permissions policy = what the role can do. Trust policy = who can assume it.
You attached admin rights to user dev, but the CLI still says AccessDenied. First command to run?
aws sts get-caller-identity- The CLI may be using a different principal, such as old keys or an assumed role.