Skip to content

Lab 02 — IAM policy evaluation

✅ Done 🧭 Identity and Access Management 💲 $0
Services: IAM, STS, SSM Parameter Store, SQS, IAM Access Analyzer

In one sentence

Watch each layer of IAM policy evaluation — permissions boundary, session policy, ABAC conditions, Access Analyzer — allow or deny a real request, and learn to read from the error message which layer said no.

The idea

Request ──► 1. Explicit Deny anywhere?  (SCP · RCP · resource · identity · boundary · session) ──► DENY
            2. Organizations SCP / RCP allow?                                       no ──► DENY
            3. Resource-based policy allows? (same account: can grant access by itself)
            4. Identity-based policy allows?                                        no ──► DENY
            5. Permissions boundary allows?                                         no ──► DENY
            6. Session policy allows?                                               no ──► DENY
                                                                                          ──► ALLOW
Effective permissions = identity ∩ boundary ∩ session ∩ SCP   (and any Deny wins)

The delegated-admin trick from Part A — the dev may create roles only if they carry the boundary:

"Condition": {
  "StringEquals": { "iam:PermissionsBoundary": "arn:aws:iam::111111111111:policy/sec2-boundary" }
}

What happened in the lab run

Part A — delegated admin with a permissions boundary (as sec2-dev-role)

Action Result
CreateRole without the boundary ❌ "no identity-based policy allows" — the Allow's condition didn't match → implicit deny
CreateRole with sec2-boundary + inline policy granting EC2/SSM on * ✅
DeleteRolePermissionsBoundary on that role ❌ "explicit deny in an identity-based policy"

Part B — effective permissions = identity ∩ boundary (as sec2-app-reader)

# Call Identity Boundary Result
1 s3 list-buckets ✅ ✅ ✅
2 ec2 describe-instances ✅ ❌ ❌ "no permissions boundary allows"
3 ssm get-parameter /sec2/alpha/… ✅ ✅ /sec2/* ✅
4 ssm get-parameter /sec2-outside/flag ✅ ❌ ❌ "no permissions boundary allows"

Part C — session policy (dev role assumed with a policy allowing only s3:ListAllMyBuckets)

Call Role Session Result
s3 list-buckets ✅ ✅ ✅
iam list-roles ✅ ❌ ❌ "no session policy allows"
something the role doesn't have (e.g. sns:ListTopics) ❌ ✅ ❌ — a session policy can only narrow

Part D — ABAC with session tags (aws:PrincipalTag/project = aws:ResourceTag/project)

Session Parameter Result
tagged project=alpha /sec2/alpha/db-password ✅
tagged project=alpha /sec2/beta/db-password ❌
no tag /sec2/alpha/db-password ❌
caller picks project=beta itself — ⚠️ nothing stops it: whoever has sts:TagSession chooses the tag values

Part E — IAM Access Analyzer

Test Result
validate-policy on the bad policy ✅ ERROR INVALID_ACTION (s3:GetObjects) + SECURITY_WARNING PASS_ROLE_WITH_STAR_IN_RESOURCE
Third bug: s3:GetObject on the bucket ARN instead of bucket/* ⚠️ not reported — valid syntax, but it never matches an object
SQS queue with Principal: "*" ✅ ACTIVE finding, isPublic: true
Queue restricted to the org (aws:PrincipalOrgID) ⚠️ finding still ACTIVE, no longer public — an ACCOUNT analyzer treats other org accounts as external
Policy removed ✅ finding RESOLVED

Key lessons

  1. Effective permissions are an intersection. An Allow in an SCP, boundary or session policy grants nothing — the identity (or resource) policy must also allow it, and every ceiling on the path must too.
  2. The error message names the layer: "no identity-based policy allows", "no permissions boundary allows", "no session policy allows", "explicit deny in …". Read it before you change anything.
  3. Delegating role creation safely needs two pieces: an Allow conditioned on iam:PermissionsBoundary, and an explicit Deny on removing the boundary or editing the boundary policy.
  4. ABAC scales (no policy change per project) but is only as safe as the tags: tags must come from the IdP or be constrained, and principals must not be able to retag themselves or resources.
  5. Access Analyzer's zone of trust is its type, not your intent. Syntax validation passing ≠ the policy works.

Exam notes

  • Same account: a resource-based policy can grant access by itself (no identity policy needed) — but an explicit Deny, SCP, or boundary still applies. Cross-account needs both sides.
  • Boundaries never grant; they set a ceiling for users/roles. Identity ∩ boundary.
  • Privilege escalation paths to watch in answer choices: create a role without a boundary, remove the boundary (DeleteRolePermissionsBoundary / PutRolePermissionsBoundary), edit the boundary policy (CreatePolicyVersion / SetDefaultPolicyVersion), attach an admin managed policy, iam:PassRole on * to EC2/Lambda.
  • Session policies are accepted by AssumeRole, AssumeRoleWithSAML, AssumeRoleWithWebIdentity and GetFederationToken (--policy / --policy-arns). Typical use: a broker hands out narrowed creds.
  • ABAC keys: aws:PrincipalTag/<key> = aws:ResourceTag/<key>; enforce tags at creation with aws:RequestTag/<key> + aws:TagKeys. Passing session tags needs sts:TagSession in the trust policy; constrain values with aws:RequestTag there. Transitive session tags survive role chaining.
  • Deny iam:TagRole / ssm:AddTagsToResource (etc.) to principals, or they grant themselves access.
  • "Validate policies in CI/CD before deployment" → Access Analyzer ValidatePolicy, or custom policy checks CheckNoNewAccess / CheckNoPublicAccess (small charge per call).
  • Analyzer types: ACCOUNT = anything outside this account is external; ORGANIZATION = only outside the org is external, and it can only be created in the management account or a delegated admin. Intended sharing → archive the finding or create an archive rule.
  • When a CLI profile is set, it wins over temp-credential environment variables.

Review questions

Question 1

A user's identity policy allows s3:*. Their boundary allows only s3:GetObject. The SCP allows everything. Can they call s3:PutObject?

Show answer

No. Effective permissions are the intersection of identity policy, boundary and SCP. The boundary doesn't include s3:PutObject, so the request fails with "no permissions boundary allows". The SCP allowing everything only means the SCP isn't the layer blocking it — an SCP never grants anything.

Question 2

A developer has iam:CreateRole and iam:AttachRolePolicy on *. Name two ways they could escalate privileges, and the controls that stop each one.

Show answer

(a) Create a role that trusts themselves and attach AdministratorAccess, then assume it. Stop it by allowing CreateRole only with the iam:PermissionsBoundary condition, and restricting which policies may be attached (iam:PolicyARN condition on AttachRolePolicy). (b) Attach an admin policy to a role they can already use or pass — e.g. an existing role, or a new role passed to EC2/Lambda with iam:PassRole, then run code as it. Stop it with the same boundary requirement plus scoping iam:PassRole to specific role ARNs (and iam:PassedToService). In both cases add an explicit Deny on removing the boundary (DeleteRolePermissionsBoundary) and on editing the boundary policy (CreatePolicyVersion, SetDefaultPolicyVersion), or they just lift the ceiling.

Question 3

Can a session policy grant access the role's identity policy doesn't have?

Show answer

No. The session's permissions are the intersection of the role's identity policy and the session policy, so it can only narrow. In the lab, adding sns:ListTopics in the session policy still failed. (A resource-based policy that names the session ARN directly is the one edge case where access isn't limited by the session policy.)

Question 4

An SCP denies ec2:TerminateInstances. An admin in the management account terminates an instance. Does it succeed?

Show answer

Yes. SCPs never apply to principals in the management account, even when attached to the root. That's why AWS recommends keeping workloads out of the management account and protecting it tightly. (SCPs also don't restrict service-linked roles.)

Question 5

Your company adds a new project every week. Which access approach avoids writing a new IAM policy each time, and which two condition keys does it rely on?

Show answer

ABAC (attribute-based access control). One policy compares aws:PrincipalTag/project with aws:ResourceTag/project; a new project just needs tagged principals and resources. Pair it with aws:RequestTag / aws:TagKeys to force correct tags at creation, and source principal tags from the IdP so users can't pick their own.

Question 6

Security wants alerts whenever a resource gets shared with any account outside the company. Which tool and analyzer type, and from which account?

Show answer

IAM Access Analyzer with an ORGANIZATION analyzer (zone of trust = the org), created in a delegated administrator account for Access Analyzer (or the management account, but delegated admin is the best practice). Findings flow to EventBridge / Security Hub for alerting. An ACCOUNT analyzer would also flag sharing between your own accounts — noise for this requirement.

My first attempt: 2 / 6

Weak spots: effective permissions are an intersection (an SCP allowing an action isn't enough) · privilege escalation via CreateRole / AttachRolePolicy / PassRole · ABAC condition keys · Access Analyzer organization zone of trust.