AWS
Intermediate 15 min read AWS

AWS IAM Fundamentals

Users, roles, policies and the trust between them

IAM is how AWS decides who can do what. Users, groups, roles, policies, and trust relationships — get these five wrong and everything from security to debugging gets worse.

IAMrolespoliciestrust policySTSleast privilegefederation
Prerequisites: AWS Service Map
Before we start

What you will learn

  • Distinguish IAM users, groups and roles
  • Read and write an IAM policy document
  • Chain trust policies, roles and STS to make cross-account access safe
In 60 seconds

IAM identities (users/roles) carry policies that grant or deny API actions against resources. Roles are assumed via trust policies and return temporary credentials through STS. Effective access is the intersection of every policy that applies.

Introduction

What is this?

AWS IAM controls access to every API call. Users represent people, groups bundle users with common permissions, and roles are identities that anything (a person, an EC2 instance, another account) can assume. Policies are JSON documents describing Allow or Deny effects on actions and resources. A role's trust policy names who is allowed to assume it; STS issues short-lived credentials; organizations/federation extend access across accounts and identity providers.

Motivation

Why do you need it?

  • IAM is the blast-radius control — a misconfigured policy makes every other service insecure.
  • Serverless and container workloads must act as something; roles give machines identity with credentials that expire.
  • Multi-account strategy is built on cross-account roles, not shared keys.
  • Auditors read IAM to prove least privilege and the policy review process.
Think about it

Mental model

Imagine

Building badge + room access list

Think of

IAM users and roles

Your badge (identity) who you are; the access control list per room (policies) what you may enter. A 'room service' badge (role) lets a service act without being a person.

Mechanics

How it works

  • A principal (user or role) invokes an API; IAM evaluates all applicable policies and ultimately decides Allow or Deny.
  • Policies attach to identities (identity-based) or to resources like S3 buckets (resource-based); both must allow.
  • A Role has two documents: the trust policy (who may assume it) and the permissions policy (what they can do once assumed).
  • sts:AssumeRole returns temporary credentials (expiring keys) subject to the trust + permission intersection.
  • Federation (SAML/OIDC) maps external identities to roles automatically; IAM Identity Center manages this at scale.

How AWS decides whether an API call succeeds.

Principal
Action + Resource
Identity policy
Resource policy
Allow or Deny
Hands-on

Examples

A minimal policy and role

A minimal policy and role
// Policy allowing read on one bucket and key prefix
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::acme-data", "arn:aws:s3:::acme-data/reports/*"]
}]
}
# Assume a role with the CLI (temporary, time-boxed)
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/DataRead --role-session-name ci-job --duration-seconds 3600

Policies scope actions to specific resources; roles add a trust boundary; STS rotates credentials so nothing long-lived is stored in CI config.

Real world

In production

  • EC2 instances get instance profiles: a role with least-privilege policies, no keys burned into the image.
  • CI pipelines assume cross-account roles from an IAM Identity Center (OIDC) to deploy into dev/prod.
  • A data team reads only their bucket prefixes via a scoped role; a deny-all-then-allow strategy keeps it tight.
Guidelines

Best practices

  • Default deny: start with no permissions and add only what each workload needs.
  • Prefer roles and temporary credentials over user keys and hardcoded secrets.
  • Name policies and roles meaningfully (app:env:function) and version them as code.
  • Review unused roles/policies with IAM Access Analyzer and CI-based policy checks.
Watch out

Common mistakes

  • Giving users AdministratorAccess because debugging permissions is annoying.
  • Hardcoding access keys in Lambda env vars or repo config files.
  • Putting a full trust policy (everyone) on a role and calling it cross-account.
  • Forgetting explicit Deny always wins — a stray deny SCP/policy blocks everything.
Root cause analysis

Common issues

Error
AccessDenied for an action your IAM policy allows
Root cause

Resource policy, SCP or explicit Deny elsewhere blocks it

Fix

Inspect bucket/role trust policies and the OU chain; use Policy Simulator to see effective permissions.

Error
EC2 can't do s3:GetObject
Root cause

Instance has no IAM role attached (or wrong role)

Fix

Attach the intended instance profile; verify with aws sts get-caller-identity on the box.

Error
CI role assumption fails because of MFA
Root cause

Trust policy requires MultifactAuthPresent but CI has no MFA

Fix

Scope MFA requirement to human users, or add a separate trust path for automated principals.

When things break

Debugging tips

  • When an access call fails, read the error — AccessDenied often names the lacking action.
  • Use IAM policy simulator and CloudTrail (SourceIP, AccessKeyId) to locate the effective deny.
  • Check for SCPs and resource policies: IAM may allow while an SCP or bucket policy denies.
  • Compare the identity's attached policies to what the resource actually requires.
Interviews

Interview checkpoint

Practice

Hands-on lab

Build a Least-Privilege Role and Prove It
30 min · intermediate
In progress
Objectives
  • Create an IAM role with a scoped policy
  • Assume the role with STS and confirm limited permissions
  • Prove an action outside the policy is denied

Build a Least-Privilege Role and Prove It

30 min · intermediate

0/6 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/2
1

Which component decides WHO can assume a role?

2

IAM roles issue permanent access keys stored in the account.

Go deeper

Official documentation