AWS Identity and Access Management (IAM)¶
What Is This Service?¶
AWS Identity and Access Management (IAM) is the AWS authorization service that controls access to AWS APIs and resources.
Mental model:
IAM = Principal → Policy Evaluation → Temporary Credentials → AWS API Access
IAM answers:
Who can do what, to which resource, under which conditions?
IAM secures:
- human access
- workload access
- service-to-service access
- application access
- cross-account access
Why It Matters for Security¶
IAM is the foundation of AWS security.
Most AWS security incidents involve one of these failures:
- excessive permissions
- long-lived access keys
- weak trust policies
- missing explicit denies
- unsafe cross-account access
- over-permissive
iam:PassRole - public or external resource policies
IAM exists to:
- enforce least privilege
- remove static credentials
- control blast radius
- prevent privilege escalation
- enable federation
- govern multi-account access
- audit access decisions
MOST TESTED:
IAM is not just identity.
IAM is the authorization engine behind almost every AWS security decision.
Architecture Example¶
Federated Multi-Account IAM Architecture¶
flowchart TD
User[Workforce User]
subgraph IdentityLayer[Identity Layer]
IdP[External IdP]
IdentityCenter[IAM Identity Center]
end
subgraph CredentialLayer[Credential Layer]
STS[AWS STS]
Session[Temporary Session]
end
subgraph AWSOrg[AWS Organizations]
Dev[Dev Account]
Prod[Prod Account]
Security[Security Account]
end
subgraph AuthorizationLayer[Authorization Layer]
Role[IAM Role]
Policies[IAM Policies]
SCP[SCP Guardrails]
end
subgraph AuditLayer[Audit Layer]
CloudTrail[CloudTrail]
AccessAnalyzer[IAM Access Analyzer]
end
User --> IdP
IdP --> IdentityCenter
IdentityCenter --> STS
STS --> Session
Session --> Role
Role --> Policies
SCP --> Policies
Policies --> Dev
Policies --> Prod
Policies --> Security
Dev --> CloudTrail
Prod --> CloudTrail
Security --> CloudTrail
Policies --> AccessAnalyzer
Architecture goals:
- no IAM users for workforce access
- temporary credentials only
- centralized identity
- account-level guardrails
- auditable authorization
Workflow(s)¶
AssumeRole Flow¶
sequenceDiagram
participant Principal
participant STS
participant TrustPolicy
participant IAMRole
participant AWSAPI
Principal->>STS: AssumeRole
STS->>TrustPolicy: Can this principal assume the role?
TrustPolicy->>STS: Allow or Deny
STS->>IAMRole: Create role session
IAMRole->>AWSAPI: Call AWS APIs with temporary credentials
Policy Evaluation Flow¶
sequenceDiagram
participant Request
participant ExplicitDeny
participant OrgPolicies
participant Boundaries
participant SessionPolicy
participant IdentityPolicy
participant ResourcePolicy
participant Decision
Request->>ExplicitDeny: Check explicit deny
ExplicitDeny->>OrgPolicies: If no deny, check SCP/RCP
OrgPolicies->>Boundaries: Check max permissions
Boundaries->>SessionPolicy: Check session limits
SessionPolicy->>IdentityPolicy: Check identity permissions
IdentityPolicy->>ResourcePolicy: Check resource permissions
ResourcePolicy->>Decision: Allow only if permitted
Service Role Flow¶
sequenceDiagram
participant Admin
participant IAM
participant Service
participant Role
participant Resource
Admin->>IAM: iam:PassRole
IAM->>Service: Attach role to service
Service->>Role: Assume role
Role->>Resource: Access resource
Core Concepts¶
IAM Principal¶
An entity that can make a request.
Examples:
- IAM user
- IAM role
- federated user
- AWS service principal
- assumed role session
Example service principal:
{
"Service": "lambda.amazonaws.com"
}
IAM Users¶
Long-term identities with optional passwords and access keys.
Use cases:
- break-glass only
- legacy workloads
- limited automation where roles are impossible
Best practice:
Avoid IAM users for humans.
Use IAM Identity Center instead.
MASSIVE EXAM TRAP:
Access keys are long-lived credentials.
Prefer STS temporary credentials.
IAM Roles¶
Temporary identities assumed by trusted principals.
Used by:
- EC2 instance profiles
- Lambda execution roles
- ECS task roles
- EKS IRSA roles
- cross-account access
- federated workforce users
- AWS services
Role has two sides:
Trust Policy = who can assume the role
Permission Policy = what the role can do
Trust Policy¶
Controls who can assume a role.
Example Lambda trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
WHY:
Lambda must be trusted to assume the execution role.
Exam trap:
A permissions policy does not allow assumption.
The role trust policy must allow assumption.
Permission Policy¶
Controls what actions are allowed after the role is assumed.
Example Lambda permission policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
WHY:
Trust gets the role assumed.
Permissions define what the session can do.
IAM Policies¶
Policy types:
- identity-based policies
- resource-based policies
- permissions boundaries
- session policies
- service control policies
- resource control policies
- access control lists in legacy services
Core JSON fields:
Effect
Action
Resource
Principal
Condition
AWS STS¶
AWS Security Token Service issues temporary credentials.
Common APIs:
AssumeRole
AssumeRoleWithSAML
AssumeRoleWithWebIdentity
GetSessionToken
MOST TESTED:
STS does not grant permissions by itself.
STS issues credentials for a principal that IAM has already authorized.
Important Integrations¶
| Service | IAM Integration |
|---|---|
| IAM Identity Center | Workforce federation and permission sets |
| AWS STS | Temporary credentials |
| AWS Organizations | SCPs, RCPs, account guardrails |
| CloudTrail | Audit IAM and STS activity |
| IAM Access Analyzer | Detect public and cross-account access |
| Amazon S3 | Bucket policies and data perimeters |
| AWS KMS | Key policies and cryptographic authorization |
| Lambda | Execution roles and resource policies |
| EC2 | Instance profiles and PassRole |
| ECS | Task roles |
| EKS | IRSA and OIDC federation |
| Secrets Manager | Secret resource policies |
| SQS/SNS/EventBridge | Service-to-service resource policies |
Security Features¶
Least Privilege¶
Bad policy:
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
Better policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::security-reports/*"
}
]
}
WHY:
Least privilege limits blast radius when credentials are compromised.
Policy Evaluation Logic¶
MOST TESTED
Simplified evaluation:
Default = implicit deny
Explicit deny wins
Organizations guardrails must allow
Permissions boundaries must allow
Session policies must allow
Identity/resource policies must allow
Otherwise deny
Important rule:
Explicit Deny > Allow
MASSIVE EXAM TRAP:
An administrator policy can still be blocked by:
- SCP
- RCP
- permissions boundary
- session policy
- explicit deny
- KMS key policy
Conditions¶
Conditions make authorization contextual.
Common condition keys:
aws:SourceIp
aws:SourceVpce
aws:RequestedRegion
aws:PrincipalArn
aws:PrincipalOrgID
aws:PrincipalTag
aws:RequestTag
aws:ResourceTag
aws:MultiFactorAuthPresent
aws:SecureTransport
iam:PassedToService
sts:ExternalId
MFA Enforcement¶
Deny privileged actions without MFA:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyWithoutMFA",
"Effect": "Deny",
"Action": [
"iam:*",
"kms:*",
"organizations:*"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
WHY:
MFA protects sensitive control-plane actions.
Exam trap:
MFA authenticates the user.
It does not automatically grant permissions.
Advanced Security and Operational Concepts¶
Control Plane vs Data Plane¶
Control plane:
- create users
- create roles
- update policies
- update trust
- configure permissions
Data plane:
- call AWS APIs
- assume roles
- use temporary credentials
- access resources
Exam trap:
IAM policy changes are eventually consistent.
A newly created role or policy may not work immediately.
Identity Policy vs Resource Policy¶
| Policy Type | Attached To | Controls |
|---|---|---|
| Identity policy | User, group, role | What identity can do |
| Resource policy | Resource | Who can access resource |
Resource policy examples:
- S3 bucket policy
- KMS key policy
- Lambda function policy
- SQS queue policy
- Secrets Manager resource policy
MASSIVE EXAM TRAP:
Cross-account access usually needs both sides:
Caller identity permission
+
Target resource or role trust permission
Permissions Boundaries¶
Permissions boundaries define the maximum permissions an IAM user or role can have.
They do not grant access.
Used for:
- delegated administration
- preventing privilege escalation
- safe role creation by developers
Scenario:
A developer can create roles only if every role has a boundary.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowRoleCreationOnlyWithBoundary",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:PutRolePolicy",
"iam:AttachRolePolicy"
],
"Resource": "arn:aws:iam::111122223333:role/app-roles/*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::111122223333:policy/StrictDeveloperBoundary"
}
}
}
]
}
WHY:
The developer can create roles, but cannot create an unconstrained administrator role.
Exam trap:
Boundary limits maximum permissions.
It does not grant permissions.
Service Control Policies¶
SCPs are AWS Organizations guardrails.
They apply to:
- member accounts
- OUs
- root user in member accounts
They do not grant access.
Example deny leaving approved Regions:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyOutsideApprovedRegions",
"Effect": "Deny",
"NotAction": [
"iam:*",
"organizations:*",
"route53:*",
"cloudfront:*",
"support:*",
"sts:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"eu-west-1",
"eu-west-2"
]
}
}
}
]
}
WHY:
Some AWS services are global.
Region deny policies must exclude global services.
MASSIVE EXAM TRAP:
SCP allows nothing by itself.
IAM permissions are still required.
Resource Control Policies¶
Resource Control Policies are AWS Organizations guardrails for resource access.
Mental model:
SCP = maximum permissions for principals
RCP = maximum access allowed to resources
Use cases:
- enforce data perimeter controls
- prevent access from outside organization
- protect supported resources from external principals
Exam trap:
RCPs are not identity policies.
They limit resource access at the organization level.
Session Policies¶
Session policies restrict temporary sessions.
Used with:
AssumeRole
Purpose:
Further reduce permissions for a specific session.
Exam trap:
Session policies can only reduce permissions.
They cannot add permissions beyond the role.
ABAC¶
Attribute-Based Access Control uses tags and attributes.
Example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Department": "${aws:PrincipalTag/Department}"
}
}
}
]
}
WHY:
ABAC scales better than writing one policy per team, application, or account.
Exam trap:
ABAC requires consistent tagging governance.
Session Tags¶
Session tags pass attributes into temporary credentials.
Used for:
- ABAC
- federated access
- temporary project access
- identity propagation
Example condition:
{
"StringEquals": {
"aws:PrincipalTag/Project": "Phoenix"
}
}
Exam trap:
Session tags can influence authorization.
Control who can pass tags.
iam:PassRole¶
iam:PassRole allows a principal to attach or pass a role to an AWS service.
Scenario:
Developer can launch EC2 but cannot attach an instance profile.
Cause:
Missing iam:PassRole
Secure pattern:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPassingOnlyApprovedEC2Role",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::111122223333:role/WebServerRole",
"Condition": {
"StringEquals": {
"iam:PassedToService": "ec2.amazonaws.com"
}
}
}
]
}
WHY:
Prevents users from passing powerful roles to unintended services.
MASSIVE EXAM TRAP:
ec2:RunInstances is not enough when launching with an IAM role.
You also need iam:PassRole.
Advanced JSON Use Cases¶
1. Data Perimeter: S3 + KMS + VPC Endpoint¶
Scenario:
Sensitive S3 bucket must be accessed only through a specific VPC endpoint.
Objects must be encrypted with a specific KMS key.
Bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAccessOutsideVPCEndpoint",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::highly-secure-data",
"arn:aws:s3:::highly-secure-data/*"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpce": "vpce-1a2b3c4d"
}
}
},
{
"Sid": "DenyUploadsWithoutSpecificKMSKey",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::highly-secure-data/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:us-east-1:111122223333:key/abcd-1234"
}
}
}
]
}
WHY:
This blocks access even if a user has broad s3:* permissions elsewhere.
Exam trap:
Data perimeters rely heavily on explicit deny.
Allow statements are weaker because another policy may allow unintended paths.
2. KMS Key Policy for S3 Encryption¶
Scenario:
S3 bucket enforces SSE-KMS using a customer managed key.
The role also needs KMS permissions.
KMS key policy statement:
{
"Sid": "AllowApplicationRoleToUseKey",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/AppRole"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "*"
}
WHY:
S3 permission alone is not enough.
If the object uses SSE-KMS, the principal also needs KMS authorization.
MASSIVE EXAM TRAP:
KMS requires key policy permission.
IAM alone may not be sufficient.
3. Confused Deputy: S3 to SQS¶
Scenario:
S3 bucket sends event notifications to SQS.
Unsafe policy:
Allow s3.amazonaws.com without SourceArn or SourceAccount
Safe SQS queue policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowOnlySpecificBucketToSendMessages",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:111122223333:MyQueue",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:::my-company-secure-bucket"
},
"StringEquals": {
"aws:SourceAccount": "111122223333"
}
}
}
]
}
WHY:
Prevents another AWS customer from using S3 to send messages to your queue.
Exam trap:
Service principal alone is too broad.
Use:
aws:SourceArn
+
aws:SourceAccount
4. Cross-Account Vendor Access with ExternalId¶
Scenario:
A SaaS security vendor needs read-only access.
Trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowVendorAssumeRoleWithExternalId",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::999988887777:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "vendor-generated-unique-id-98765"
}
}
}
]
}
Permission policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadOnlySecurityAudit",
"Effect": "Allow",
"Action": [
"cloudtrail:LookupEvents",
"ec2:Describe*",
"iam:Get*",
"iam:List*",
"s3:GetBucketPolicy",
"s3:GetBucketPublicAccessBlock"
],
"Resource": "*"
}
]
}
WHY:
ExternalId prevents a confused deputy attack against the vendor.
MASSIVE EXAM TRAP:
Third-party access should use:
Cross-account role
+
ExternalId
Not IAM users.
5. ABAC + EC2 Launch + PassRole¶
Scenario:
Developer can launch EC2 only when tagging instances correctly and passing only an approved role.
Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowRunInstancesOnlyWithEnvironmentTag",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestTag/Environment": "Production"
},
"ForAllValues:StringEquals": {
"aws:TagKeys": [
"Environment",
"Owner"
]
}
}
},
{
"Sid": "AllowPassingOnlyApprovedEC2Role",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::111122223333:role/WebServerRole",
"Condition": {
"StringEquals": {
"iam:PassedToService": "ec2.amazonaws.com"
}
}
}
]
}
WHY:
This controls both:
- the resource attributes
- the role attached to compute
Exam trap:
ABAC without PassRole control can still allow privilege escalation.
6. Lambda Writes CloudWatch Logs¶
Scenario:
Lambda executes but no logs appear.
Trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Permission policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
WHY:
Lambda needs:
Trust policy allowing Lambda
+
Permissions to write logs
Exam trap:
Missing execution role permissions causes missing logs.
7. Mobile Application Uploads to S3¶
Scenario:
Mobile users upload files to their own folder.
Do not embed IAM keys.
Use Cognito or federation with temporary credentials.
Policy pattern:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUserPrefixUploadsOnly",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mobile-uploads/${cognito-identity.amazonaws.com:sub}/*"
}
]
}
WHY:
Each user only accesses their own prefix.
Exam trap:
Never place IAM user access keys in mobile apps.
8. EventBridge Invokes Lambda¶
Scenario:
EventBridge rule invokes Lambda.
Lambda resource policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEventBridgeInvoke",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:111122223333:function:RemediateFinding",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:events:us-east-1:111122223333:rule/SecurityFindingRule"
}
}
}
]
}
WHY:
Lambda invocation by AWS services is controlled by Lambda resource policies.
Exam trap:
For service-to-service invocation, check resource policy first.
9. Enforce TLS for S3¶
Scenario:
Deny unencrypted transport.
Bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::secure-bucket",
"arn:aws:s3:::secure-bucket/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
WHY:
Blocks HTTP requests even if identity permissions allow S3 access.
Exam trap:
Use explicit deny for transport enforcement.
10. Restrict Resource Access to Same Organization¶
Scenario:
Only principals from your AWS Organization can access a resource.
Resource policy condition:
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::org-only-bucket",
"arn:aws:s3:::org-only-bucket/*"
],
"Condition": {
"StringNotEquals": {
"aws:PrincipalOrgID": "o-a1b2c3d4e5"
}
}
}
WHY:
Prevents accidental external access even if a resource policy is later changed.
Exam trap:
aws:PrincipalOrgID is common in data perimeter questions.
Federation and Workload Identity¶
IAM Identity Center¶
Used for workforce access.
Best for:
- humans
- SSO
- multi-account access
- permission sets
- centralized identity governance
Exam trap:
IAM Identity Center is for workforce identity.
IAM roles are still used underneath.
SAML Federation¶
Used for enterprise IdPs.
Flow:
User → IdP → SAML assertion → STS → Role session
Common API:
AssumeRoleWithSAML
OIDC Federation¶
Used for web identity and workloads.
Common examples:
- EKS IRSA
- GitHub Actions to AWS
- external CI/CD
Common API:
AssumeRoleWithWebIdentity
EKS IRSA¶
Scenario:
Kubernetes pod needs S3 access.
Use:
OIDC provider
+
Service account annotation
+
IAM role trust policy
Trust policy pattern:
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE:sub": "system:serviceaccount:payments:api"
}
}
}
WHY:
Only the specific Kubernetes service account can assume the role.
Exam trap:
IRSA avoids node-wide permissions.
IAM Roles Anywhere¶
Used for external workloads.
Examples:
- on-prem servers
- external containers
- hybrid workloads
Uses:
X.509 certificate
+
trust anchor
+
IAM role
+
temporary credentials
Exam trap:
Use IAM Roles Anywhere when external workloads need AWS access without static keys.
Troubleshooting IAM¶
Access Denied Checklist¶
Check in this order:
- Is there an explicit deny?
- Is an SCP blocking access?
- Is an RCP blocking resource access?
- Is a permissions boundary limiting the role?
- Is a session policy reducing access?
- Does identity policy allow the action?
- Does resource policy allow the principal?
- Does KMS key policy allow usage?
- Is
iam:PassRolerequired? - Is the role trust policy correct?
- Is the resource ARN correct?
- Are conditions satisfied?
- Is IAM eventual consistency involved?
CloudTrail¶
Use CloudTrail to inspect:
AssumeRoleAccessDeniedCreatePolicyPutRolePolicyAttachRolePolicyPassRoleUpdateAssumeRolePolicy
Exam trap:
CloudTrail shows API activity.
It does not explain every policy decision.
IAM Access Analyzer¶
Uses automated reasoning.
Detects:
- public access
- cross-account access
- unused access
- policy validation issues
Use cases:
- find public S3 bucket policies
- detect external KMS key usage
- validate policy before deployment
- identify unused permissions
MOST TESTED:
Access Analyzer helps find unintended access.
IAM Policy Simulator¶
Used to test whether a policy allows or denies actions.
Good for:
- identity policy debugging
- permission boundary debugging
- action/resource matching
Exam trap:
Simulator is for testing IAM logic.
It is not a runtime security control.
Comparisons¶
IAM vs IAM Identity Center¶
| Capability | IAM | IAM Identity Center |
|---|---|---|
| Authorization | Yes | Uses IAM roles |
| Workforce SSO | No | Yes |
| Permission policies | Yes | Permission sets |
| Long-lived users | Possible | Avoided |
| Multi-account workforce access | Manual | Native |
Rule:
Humans use Identity Center.
IAM roles authorize access.
IAM vs STS¶
| Capability | IAM | STS |
|---|---|---|
| Defines permissions | Yes | No |
| Issues temporary credentials | No | Yes |
| Stores policies | Yes | No |
| Federation token exchange | No | Yes |
Rule:
IAM defines access.
STS issues credentials.
IAM vs Organizations SCP¶
| Capability | IAM Policy | SCP |
|---|---|---|
| Grants permissions | Yes | No |
| Limits account permissions | No | Yes |
| Applies to accounts/OUs | No | Yes |
| Applies to root in member account | No | Yes |
Rule:
SCP is a guardrail.
IAM is authorization.
IAM vs Resource Policies¶
| Capability | IAM Identity Policy | Resource Policy |
|---|---|---|
| Attached to principal | Yes | No |
| Attached to resource | No | Yes |
| Grants cross-account directly | No | Often |
| Contains Principal | No | Yes |
Permissions Boundary vs SCP¶
| Capability | Permissions Boundary | SCP |
|---|---|---|
| Scope | User or role | Account or OU |
| Grants permissions | No | No |
| Used for delegation | Yes | Yes |
| Managed in IAM | Yes | No |
| Managed in Organizations | No | Yes |
Common Exam Traps¶
-
IAM roles are preferred over IAM users.
-
STS issues temporary credentials; IAM defines permissions.
-
Trust policy controls who can assume a role.
-
Permission policy controls what the role can do.
-
Explicit deny always wins.
-
SCPs do not grant permissions.
-
Permissions boundaries do not grant permissions.
-
Session policies only reduce permissions.
-
Identity policy alone does not grant cross-account access.
-
Resource policies commonly enable cross-account access.
-
KMS requires key policy authorization.
-
iam:PassRoleis required when assigning roles to services. -
iam:PassedToServiceprevents passing roles to unintended services. -
sts:ExternalIdprotects third-party SaaS access. -
aws:SourceArnandaws:SourceAccountprevent confused deputy. -
Data perimeters usually use explicit deny.
-
aws:SourceVpceproves traffic used a VPC endpoint. -
aws:PrincipalOrgIDrestricts access to your AWS Organization. -
IAM is eventually consistent.
-
Root user should not be used for daily administration.
-
Root can be restricted by SCPs in member accounts.
-
Global service deny policies can accidentally block IAM, STS, Route 53, or CloudFront.
-
ABAC requires strong tag governance.
-
IRSA uses OIDC and
AssumeRoleWithWebIdentity. -
IAM Roles Anywhere uses certificates for external workloads.
5-Second Recall¶
- IAM = AWS authorization engine
- Roles over users
- STS = temporary credentials
- Trust policy = who assumes
- Permission policy = what can be done
- Explicit deny wins
- SCP = account guardrail
- Boundary = identity maximum
- PassRole = attach role to service
- ExternalId = vendor confused deputy protection
- SourceArn + SourceAccount = service confused deputy protection
- KMS needs key policy
- ABAC uses tags
- Access Analyzer finds unintended access
Quick Revision Notes¶
- Use IAM Identity Center for humans.
- Use IAM roles for workloads.
- Use STS for temporary credentials.
- Avoid long-lived access keys.
- Separate trust policies from permission policies.
- Use explicit deny for data perimeters.
- Use permissions boundaries for delegated role creation.
- Use SCPs for account and OU guardrails.
- Use RCPs for organization-level resource guardrails.
- Use
iam:PassRolecarefully. - Use
iam:PassedToServiceto restrict role passing. - Use
sts:ExternalIdfor SaaS vendors. - Use
aws:SourceArnandaws:SourceAccountfor AWS service integrations. - Use
aws:PrincipalOrgIDfor organization-only access. - Use Access Analyzer to detect public and cross-account exposure.
- Use CloudTrail to audit IAM and STS activity.
- Use Policy Simulator for troubleshooting.
- Design IAM as architecture, not just JSON.