Skip to main content

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โ€‹

CharacteristicIdentity PolicyResource Policy
Attached toIAM User, Group, or RoleS3 Bucket, KMS Key, SQS Queue, Lambda
DefinesWhat this identity can doWho can access this resource
Principal elementโŒ Cannot haveโœ… MUST have
Cross-accountGrants outbound accessGrants 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โ€‹

ServiceResource Policy Name
S3Bucket Policy
SQSQueue Policy
SNSTopic Policy
LambdaFunction Policy
KMSKey Policy
ECRRepository Policy
API GatewayResource Policy
Secrets ManagerResource 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โ€‹

Advanced IAM Exam Cheat Sheet
  1. Explicit Deny always wins โ€” no exceptions
  2. SCP doesn't grant โ€” only restricts (and doesn't affect management account)
  3. Permission Boundary = max permissions ceiling (intersection with identity policy)
  4. Cross-account = identity policy + resource policy (both needed)
  5. Same-account = either identity OR resource policy sufficient
  6. ExternalId = confused deputy prevention for third-party access
  7. Resource policies with specific principal can grant cross-account independently
  8. ABAC = tag-based policies scale better than role-per-team
  9. AssumeRole default 1h, max 12h (configured on the role)
  10. 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.


๐Ÿ”— Resourcesโ€‹