Skip to content
GKgkml.dev
← Learn AWS Cloud

Lesson 2 of 7 · 10 min

IAM: identity, policy and the evaluation order

Understand how a request is authorised, why roles beat access keys, and what an SCP can and cannot do.

The four things IAM deals in

A user is a person with long-lived credentials. A group is a bundle of users sharing policies. A role is an identity with permissions but no permanent credentials — something assumes it and receives temporary keys. A policy is the JSON document that says what is allowed.

The one to internalise is the role. An EC2 instance, a Lambda function or a person from another account assumes a role and gets credentials that expire automatically. Nothing long-lived is stored anywhere, so nothing long-lived can leak.

How a request is evaluated

Start from deny. Any explicit Deny, anywhere — identity policy, resource policy, service control policy, session policy — ends the evaluation immediately and the request fails.

Otherwise the request must be permitted by every applicable layer: it has to be inside the SCP's ceiling, inside any permission boundary, and allowed by at least one identity or resource policy. The effective permission is the intersection, not the union.

A least-privilege policy
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["s3:GetObject"],
    "Resource": "arn:aws:s3:::reports-bucket/2026/*",
    "Condition": {
      "Bool": { "aws:SecureTransport": "true" }
    }
  }]
}

Note: Scope the action, scope the resource ARN, and add conditions. A wildcard on either is what turns a small compromise into a large one.

The restricting mechanisms

MechanismApplies toNotes
Service control policyEvery principal in an accountSet at the Organization level; the management account is exempt
Permission boundaryOne user or roleCaps what an identity policy can grant — prevents privilege escalation
Session policyOne assumed sessionScopes a role down at AssumeRole time; ideal for multi-tenant isolation
Resource policyOne resourceAttached to the bucket, key or function rather than the caller

Cross-account access

Two policies are always involved. The role's trust policy says who may assume it. An identity policy in the caller's account must allow sts:AssumeRole on that role ARN. Missing either produces AccessDenied.

For third parties, add an external ID to the trust policy. It prevents the confused-deputy problem, where a vendor is tricked into using your role on someone else's behalf.

Worth remembering

  • Everything is denied unless explicitly allowed, and an explicit Deny always wins.
  • Roles issue temporary credentials — prefer them over long-lived access keys everywhere.
  • SCPs and permission boundaries restrict; they never grant.

Test it now

IAM evaluation and cross-account access run through the medium bank.