IAM is the service that decides whether an API call succeeds. Every request to every AWS service passes through it. It is also the single largest source of exam questions, so it is worth building a precise mental model rather than a vague one.
The four objects
Users
An IAM user is a long-lived identity representing a person or an application. It can have a console password, and up to two access key pairs for programmatic use. Users are global, not Regional.
The modern guidance is to create as few of them as possible. Human access should come from federation; application access should come from roles. A user is what you fall back to when neither is possible.
Groups
A group is a container of users that exists purely so you can attach a policy once instead of many times. Three things the exam likes to test:
- Groups cannot be nested — a group cannot contain another group.
- A group is not an identity. You cannot make a group the
Principalof a policy, and a group cannot assume a role. - A user can belong to multiple groups and receives the union of their permissions.
Roles
A role is an identity with permissions but no permanent credentials. Instead, a trusted principal assumes it and receives temporary credentials from STS that expire — anywhere from 15 minutes to 12 hours.
Every role has two policies, and confusing them is a classic error:
- The trust policy (a resource-based policy on the role) says who may assume it — an AWS service, another account, a federated identity provider.
- The permissions policy says what the assumed role may do.
Roles are the answer to an enormous share of exam questions. Whenever a scenario involves an EC2 instance, Lambda function, or ECS task needing access to another service, or one account needing access to another, the answer involves a role.
Policies
A policy is a JSON document listing permissions. The important taxonomy:
| Type | Attaches to | Has a Principal element? | Cross-account? |
|---|---|---|---|
| Identity-based | User, group or role | No — the principal is whoever it is attached to | Only via role assumption |
| Resource-based | The resource itself (S3 bucket, SQS queue, KMS key, Lambda function, SNS topic) | Yes — required | Yes, directly |
Not every service supports resource-based policies. S3, SQS, SNS, KMS, Lambda, Secrets Manager, ECR and API Gateway do; EC2, RDS and DynamoDB (mostly) do not.
Anatomy of a policy
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "ReadReportsBucket",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::acme-reports",
"arn:aws:s3:::acme-reports/*"
],
"Condition": {
"IpAddress": { "aws:SourceIp": "203.0.113.0/24" }
}
}]
}
Points worth internalising:
EffectisAlloworDeny. Nothing else.- Bucket-level actions (
s3:ListBucket) act on the bucket ARN; object-level actions (s3:GetObject) act on the/*ARN. Getting this wrong is the most common real-world S3 policy bug and appears in exam distractors. Conditionis where most of the sophistication lives. Frequently-tested keys:aws:SourceIp,aws:RequestedRegion,aws:PrincipalOrgID,aws:MultiFactorAuthPresent,s3:x-amz-server-side-encryption,aws:SourceVpce.
Managed versus inline
- AWS managed policies — written and maintained by AWS (
ReadOnlyAccess,AmazonS3FullAccess). Convenient, usually too broad for production. - Customer managed policies — yours, reusable across many identities, versioned. The recommended default.
- Inline policies — embedded directly in one user, group or role, with a strict one-to-one lifecycle: delete the identity and the policy goes with it. Use when you need to guarantee a policy is never accidentally attached to anything else.
The root user
The root user is the email address the account was created with. It has unrestricted access that cannot be limited by any IAM policy. Treat it as a break-glass credential:
- Enable MFA on it, ideally hardware.
- Delete any root access keys.
- Never use it for day-to-day work.
A short list of tasks genuinely requires root: closing the account, changing the account name or root email, changing support plans, restoring an S3 bucket policy that locked everyone out, and registering as a seller in the Reserved Instance Marketplace.
Any answer option containing "store the access key on the instance", "embed credentials in the application", or "share the access keys with" is wrong. There is no scenario in SAA-C03 where that is the best answer.