Advanced IAM & Security
IAM is arguably the most complex and critical service in AWS. These advanced topics appear frequently on the DVA-C02 exam.
IAM Policy Evaluation Logic (Complete Flow)โ
When AWS evaluates an API request, it follows a strict order:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Default: All requests start as DENIED โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 2. Explicit Deny check (ANY policy) โ
โ โ If found: DENY immediately โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 3. Service Control Policy (SCP) โ
โ โ If doesn't allow: DENY โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 4. Resource-Based Policy โ
โ โ If allows AND same account: ALLOW โ
โ
โ โ If allows AND cross-account: continue checking โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 5. Permissions Boundary โ
โ โ If doesn't allow: DENY โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 6. Session Policy (if AssumeRole) โ
โ โ If doesn't allow: DENY โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 7. Identity-Based Policy โ
โ โ If allows: ALLOW โ
โ
โ โ If not: DENY โ (implicit deny) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Key rule: For an action to be allowed, ALL applicable policy types must allow it. ONE explicit Deny anywhere = denied.
Identity Policies vs Resource Policiesโ
| Characteristic | Identity Policy | Resource Policy |
|---|---|---|
| Attached to | IAM User, Group, or Role | S3 Bucket, KMS Key, SQS Queue, Lambda |
| Defines | What this identity can do | Who can access this resource |
| Principal element | โ Cannot have | โ MUST have |
| Cross-account | Grants outbound access | Grants inbound access |
Same-Account Accessโ
Either identity policy OR resource policy can grant access.
You don't need both โ just one Allow is sufficient.
Cross-Account Accessโ
Account A's identity policy must allow the action
AND
Account B's resource policy must allow Account A's principal
EXCEPTION: If the resource policy specifies the exact role ARN
(not just the account), the identity policy is not strictly needed.
Resource Policies That Support Cross-Accountโ
| Service | Resource Policy Name |
|---|---|
| S3 | Bucket Policy |
| SQS | Queue Policy |
| SNS | Topic Policy |
| Lambda | Function Policy |
| KMS | Key Policy |
| ECR | Repository Policy |
| API Gateway | Resource Policy |
| Secrets Manager | Resource Policy |
Permissions Boundariesโ
A Permissions Boundary sets the maximum permissions. It does NOT grant permissions on its own.
Effective Permissions = Intersectionโ
Identity Policy Permission Boundary Effective
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ s3:* โ โ s3:Get* โ โ s3:Get* โ
โ dynamodb:* โ โฉ โ dynamodb:* โ = โ dynamodb:* โ
โ lambda:* โ โ โ โ โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
Delegated Administration Use Caseโ
Problem: Senior admin wants to let junior dev create Lambda execution roles, but prevent privilege escalation.
// Step 1: Create Permission Boundary policy
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "dynamodb:GetItem", "dynamodb:PutItem", "logs:*"],
"Resource": "*"
}]
}
// Step 2: Allow junior dev to create roles WITH boundary attached
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["iam:CreateRole", "iam:PutRolePolicy", "iam:AttachRolePolicy"],
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/LambdaBoundary"
}
}
}]
}
Now the junior dev can create roles, but every role MUST have the boundary โ preventing them from creating overly permissive roles.
Service Control Policies (SCPs)โ
SCPs are guardrails for AWS Organizations:
AWS Organization
โโโ Root
โ โโโ SCP: "DenyDeleteS3" (applied to all accounts)
โ โโโ OU: Production
โ โ โโโ SCP: "DenyNonApprovedRegions"
โ โ โโโ Account: prod-us-east-1
โ โ โโโ Account: prod-eu-west-1
โ โโโ OU: Development
โ โโโ No additional SCP (inherits root)
โ โโโ Account: dev-sandbox
Key rules:
- SCPs do NOT grant permissions โ they only restrict
- SCPs apply to all users/roles in the account (including root!)
- Management account is NOT affected by SCPs
- SCPs must explicitly Allow actions (deny-by-default)
Common SCP Patternsโ
// Deny all regions except approved ones
{
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": ["us-east-1", "eu-west-1"]
}
}
}
// Prevent disabling CloudTrail
{
"Effect": "Deny",
"Action": ["cloudtrail:StopLogging", "cloudtrail:DeleteTrail"],
"Resource": "*"
}
Cross-Account Role Assumption (STS) Deep Diveโ
Step-by-Stepโ
1. Account B (target) creates a role: CrossAccountRole
2. Account B's Trust Policy allows Account A:
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111111111111:root" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "shared-secret-123" }
}
}
3. Account A's identity policy allows sts:AssumeRole on Account B's role ARN
4. Account A calls sts:AssumeRole with ExternalId
5. STS returns temporary credentials valid for 1-12 hours
Confused Deputy Preventionโ
Without ExternalId:
Attacker (Account C) tricks Service into assuming role in Account B
โ Service uses its own credentials to assume the role
โ Attacker gains access to Account B's resources
With ExternalId:
Role requires ExternalId that only legitimate caller knows
โ Attacker can't provide the correct ExternalId
โ AssumeRole fails
Web Identity Federationโ
OIDC Federation (Mobile/Web Apps)โ
User โ Login with Google/Apple โ JWT Token
โ Cognito Identity Pool (or direct AssumeRoleWithWebIdentity)
โ STS returns temporary AWS credentials
โ App calls S3/DynamoDB directly
SAML 2.0 Federation (Corporate)โ
Employee โ Login via AD/Okta โ SAML Assertion
โ App calls sts:AssumeRoleWithSAML
โ STS returns temporary AWS credentials
โ Employee accesses AWS Console or APIs
IAM Identity Center (SSO)โ
- Modern replacement for manual SAML federation
- Centralized access management for all AWS accounts
- Integrates with AD, Okta, Azure AD
- Provides temporary credentials via SSO portal
Attribute-Based Access Control (ABAC)โ
Instead of creating separate policies per team, use tags as policy conditions:
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::company-data/*",
"Condition": {
"StringEquals": {
"s3:ExistingObjectTag/department": "${aws:PrincipalTag/department}"
}
}
}
Benefits: One policy works for all teams. New team? Just tag the user โ no policy changes.
๐ฏ DVA-C02 Exam Tipsโ
- Explicit Deny always wins โ no exceptions
- SCP doesn't grant โ only restricts (and doesn't affect management account)
- Permission Boundary = max permissions ceiling (intersection with identity policy)
- Cross-account = identity policy + resource policy (both needed)
- Same-account = either identity OR resource policy sufficient
- ExternalId = confused deputy prevention for third-party access
- Resource policies with specific principal can grant cross-account independently
- ABAC = tag-based policies scale better than role-per-team
- AssumeRole default 1h, max 12h (configured on the role)
- IAM Identity Center = modern SSO for organizations
๐งช Practice Questionsโ
Q1. IAM user has s3:* policy. SCP denies s3:DeleteBucket. User tries to delete. Result?
A) Allowed โ identity policy permits
B) Denied โ SCP explicit deny wins
C) Allowed โ SCP doesn't affect users
D) Depends on bucket policy
โ Answer & Explanation
B โ SCPs restrict ALL principals in the account. Explicit Deny in SCP overrides any Allow.
Q2. Cross-account: Account A needs S3 access in Account B. Most secure approach?
A) Share access keys
B) VPC Peering
C) IAM Role in Account B + AssumeRole from Account A
D) Public bucket
โ Answer & Explanation
C โ AssumeRole provides temporary credentials. VPC Peering is for network connectivity, not S3 access control.
Q3. Junior dev creates a Lambda role with AdministratorAccess. How to prevent this?
A) Remove iam:CreateRole from the dev
B) Require a Permission Boundary on all created roles
C) SCP denying iam:CreateRole
D) Enable MFA
โ Answer & Explanation
B โ Permission Boundaries ensure any role the dev creates is capped at the boundary's permissions, preventing privilege escalation.
Q4. Role in Account B has trust policy allowing Account A. Account A's user has NO identity policy for AssumeRole. Can the user assume the role?
A) No โ identity policy must also allow sts:AssumeRole
B) Yes โ trust policy is sufficient
C) Yes โ if ExternalId matches
D) Depends on SCP
โ Answer & Explanation
A โ Cross-account access requires BOTH the resource policy (trust policy) AND the identity policy. The user needs sts:AssumeRole permission on the target role ARN.