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:

AWS IAM Policy Evaluation Engine (The 7-Step Decision Pipeline)
1
Default State
Request begins in Implicit Deny status
PASSED ➜
2
Explicit Deny Check
No explicit denies found
PASSED ➜
3
SCP Check
Organization SCP allows action
PASSED ➜
4
Resource Policy
Allowed or deferred to identity policy
PASSED ➜
5
Permissions Boundary
Action falls within maximum ceiling permissions
PASSED ➜
6
Session Policy
STS session policy permits action
PASSED ➜
7
Identity Policy
IAM Policy has explicit "Effect": "Allow" βž” GRANTED!
ALLOWED βœ…
Golden Evaluation Rule:All requests begin as Implicit Deny. A single explicit "Effect": "Deny" in any applicable policy immediately halts evaluation. To succeed, an explicit "Effect": "Allow" must be present, and no boundary or SCP may restrict it.

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

Policy TypeDeclared Allowed ActionsSet LogicEffective Runtime Result
Identity-Based Policys3:*, dynamodb:*, lambda:*Requested Privilegesβ€”
Permissions Boundarys3:Get*, dynamodb:*∩\cap Maximum Allow Ceilingβ€”
Effective Permissionss3:Get*, dynamodb:*Identity∩BoundaryIdentity \cap Boundarylambda:* and s3:Put* are strictly blocked!

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

πŸ“–
Track Page Progress0 / 635 Read
Knowledge Base Completion0%