Skip to main content

IAM – Identity & Access Management

Exam Weight: Domain 2 (Security) β€” 26% of exam
Key Theme: "Who can do what, on which resources, under what conditions?"


Core Concepts​

IAM Building Blocks​

ComponentDescription
UserLong-term credential for a person or application
GroupCollection of users β€” attach policies to group
RoleTemporary credentials β€” assumed by services, users, or external identities
PolicyJSON document defining permissions
Think of it this way (Java analogy)
  • User = a named instance
  • Group = an interface users implement
  • Role = a context you assume() temporarily
  • Policy = an @Authorized annotation on steroids

Policy Types​

1. Identity-Based Policies​

Attached to users, groups, or roles.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}

2. Resource-Based Policies​

Attached directly to the resource (S3 bucket, SQS queue, Lambda function).

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::123456789012:role/LambdaRole" },
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}

3. Permission Boundaries​

Set the maximum permissions an entity can have. Used to delegate IAM admin without granting all permissions.

4. Service Control Policies (SCPs)​

Apply to an AWS Organization account β€” restrict what even account root can do.

5. Session Policies​

Passed inline when using AssumeRole β€” limits permissions for that session only.


Policy Evaluation Logic​

Explicit DENY? β†’ DENY βœ‹
No explicit ALLOW? β†’ DENY βœ‹
Explicit ALLOW exists? β†’ ALLOW βœ…
caution

An explicit Deny always wins over any Allow β€” even from a different policy.


IAM Roles & STS​

AssumeRole Flow​

Your App / Service
β”‚
β–Ό
STS:AssumeRole(RoleArn, Duration, ExternalId?)
β”‚
β–Ό
Temporary Credentials (AccessKey + SecretKey + SessionToken)
β”‚
β–Ό
Call AWS APIs with temp credentials

Key STS APIs​

APIUse Case
AssumeRoleCross-account or same-account role assumption
AssumeRoleWithWebIdentityFederate with OIDC (Cognito, Google, GitHub)
AssumeRoleWithSAMLCorporate SSO (AD/LDAP via SAML 2.0)
GetSessionTokenMFA enforcement for API calls

Cross-Account Role Assumption​

Account A (Trusting)          Account B (Trusted)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ App in Account A │──────▢│ Role in Account B β”‚
β”‚ calls AssumeRole β”‚ β”‚ Trust Policy allows β”‚
β”‚ with Role ARN β”‚ β”‚ Account A principal β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

IAM Best Practices (Exam Favorites)​

  1. βœ… Use IAM Roles for EC2/Lambda β€” never hardcode credentials
  2. βœ… Apply least privilege β€” start with nothing, add as needed
  3. βœ… Enable MFA for privileged users
  4. βœ… Use Permission Boundaries to safely delegate IAM
  5. βœ… Rotate access keys regularly
  6. βœ… Use AWS Organizations + SCPs for multi-account governance
  7. ❌ Never use root account for daily operations
  8. ❌ Never embed credentials in source code

Java SDK β€” Assuming a Role​

import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.model.*;

StsClient stsClient = StsClient.create();

AssumeRoleResponse response = stsClient.assumeRole(AssumeRoleRequest.builder()
.roleArn("arn:aws:iam::123456789012:role/CrossAccountRole")
.roleSessionName("my-session")
.durationSeconds(3600)
.build());

Credentials creds = response.credentials();
// Use creds.accessKeyId(), creds.secretAccessKey(), creds.sessionToken()

Common Exam Scenarios​

Scenario 1: Lambda accessing DynamoDB​

Solution: Create an IAM Role with a DynamoDB policy. Attach the role to the Lambda function (Execution Role). Never use access keys.

Scenario 2: EC2 in Account A reads S3 in Account B​

Solution:

  1. Create a role in Account B with S3 permissions
  2. Trust policy allows Account A's EC2 role
  3. EC2 calls AssumeRole to get temp credentials

Scenario 3: Third-party SaaS needs access​

Solution: Use AssumeRole with an ExternalId condition to prevent the "confused deputy" problem.


πŸ§ͺ Practice Questions​

Q1. A developer's Lambda function needs to read from an S3 bucket. What is the MOST secure and AWS-recommended approach?

A) Store AWS access keys in Lambda environment variables
B) Hardcode credentials in the Lambda source code
C) Attach an IAM execution role to the Lambda function with S3 read permissions
D) Use root account credentials

βœ… Answer & Explanation

C β€” Always use IAM execution roles for Lambda. The role provides temporary credentials automatically via the instance metadata service β€” no keys needed.

A and B are security anti-patterns. D is never acceptable.


Q2. Which IAM policy element can DENY a specific action even when another policy grants it?

A) NotAction
B) Condition
C) An explicit "Effect": "Deny" statement
D) Principal

βœ… Answer & Explanation

C β€” An explicit Deny always overrides any Allow, regardless of which policy document it comes from.


Q3. A company uses a third-party auditing tool that needs read access to their AWS resources. The security team is worried about the confused deputy problem. What should they add to the role's trust policy?

A) A condition with aws:SourceIp
B) A condition with sts:ExternalId
C) A Permission Boundary
D) An SCP

βœ… Answer & Explanation

B β€” sts:ExternalId is the standard defense against confused deputy. The external party must supply this secret ID when assuming the role, preventing unauthorized cross-account access.


Q4. What is the maximum duration (in hours) for a role session assumed via AssumeRole by default?

A) 1 hour
B) 1 hour (default), up to 12 hours if configured on the role
C) 24 hours
D) 36 hours

βœ… Answer & Explanation

B β€” Default is 1 hour. You can set MaxSessionDuration on the role up to 12 hours. Lambda uses a 1-hour auto-renewed credential.


πŸ”— Resources​