Skip to main content

IAM Least-Privilege Clinic

Retrieval Prompts

  1. State the five elements of an IAM statement (Effect, Principal, Action, Resource, Condition) and when Principal appears.
  2. State the order of evaluation for IAM: explicit Deny, explicit Allow, default Deny.
  3. Explain the difference between an identity-based policy and a resource-based policy.
  4. State why an IAM role is preferred over an IAM user for any workload.
  5. State the purpose of a Service Control Policy (SCP) and what it cannot do.

Compare and Distinguish

Separate these pairs:

  • IAM user vs IAM role
  • identity-based policy vs resource-based policy
  • Principal element vs policy attachment target
  • Condition vs Resource narrowing
  • SCP (organization-level Deny-list) vs IAM policy (identity/resource-level Allow)
  • permissions boundary vs SCP vs IAM policy

Common Mistake Check

For each statement, identify the error or the missing detail:

  1. { "Effect": "Allow", "Action": "*", "Resource": "*" }
  2. An EC2 instance that authenticates to S3 using an IAM user's static access keys stored in /etc/aws/credentials.
  3. A Lambda function role attached to 8 unrelated functions from 4 different teams.
  4. A bucket policy with "Principal": "*" and no Condition.
  5. "We are fine - our policy has Deny on s3:DeleteBucket; nobody can delete our bucket." (think: bucket policy vs SCP vs IAM)

Mini Application

Task A: Draft a policy. A batch job (running on Fargate with a task role) must:

  • read from s3://acme-inbox-prod/*
  • write to s3://acme-processed-prod/*
  • publish to one SNS topic arn:aws:sns:us-east-1:123456789012:processing-done
  • log to CloudWatch under /aws/ecs/batch-processor/*

Write the JSON policy with an Sid per statement, narrow Action and Resource, and include at least one Condition (for example, aws:SourceVpc).

Task B: Critique an existing policy. Take this (intentionally bad) policy and tighten it:

{
"Version": "2012-10-17",
"Statement": [
{ "Effect": "Allow", "Action": "s3:*", "Resource": "*" },
{ "Effect": "Allow", "Action": "dynamodb:*", "Resource": "*" },
{ "Effect": "Allow", "Action": "sns:*", "Resource": "*" }
]
}

List each problem and write the tightened version assuming the workload only needs to read one DynamoDB table and write to the SNS topic from Task A.

Task C: Design a role-assumption boundary. A CI/CD pipeline in a shared-services account needs to deploy into team-a-prod. Sketch (in words) the trust policy on the role in team-a-prod, the identity-based policy in shared-services, and any Condition you would add (for example, aws:PrincipalTag/ci-role).

Evidence Check

Complete only if your Task A policy uses narrow Resource values and at least one Condition; your Task B rewrite removes every wildcard that is not strictly necessary; and your Task C design names the two sides of the cross-account trust.