AWS IAM basics: roles, policies, evaluation
AWS Identity and Access Management (IAM) decides who can do what to which AWS resource, using JSON policies that are evaluated on every request. The decision rule for exams: give workloads an IAM role that supplies temporary credentials, grant only the actions and resources the task needs, and remember that an explicit deny always wins. If an answer option stores an access key in code or in a container, it is almost never the right one.
Principals and the credentials they hold
IAM separates the who from the what. The who is a principal: the account root user, an IAM user, an IAM role, or an AWS service. The what is a policy.
| Principal | Credentials | Typical use |
|---|---|---|
| IAM user | Long-term: password, access keys | Cases that cannot use federation or roles (AWS lists examples such as third-party clients and emergency access) |
| IAM role | None of its own; assuming it returns temporary credentials | Workloads (EC2, Lambda, SageMaker AI jobs), federated people, cross-account access |
| Root user | Account owner credentials | Account setup and a few tasks only; protect it |
A role is not tied to one person: anyone or anything allowed by its trust policy can assume it. AWS best practice is to require human users to use federation with temporary credentials (AWS recommends IAM Identity Center for centralised access) and to require workloads to use roles rather than long-term keys. Where an IAM user or the root user is unavoidable, MFA is required by the same guidance. The cross-cloud parallel is in managed identities versus service principals; for the identity-provider side see SSO, SAML and OAuth.
A role has two policies, and exams test both
Every role carries:
- A trust policy (a resource-based policy on the role) that says who may assume it.
- One or more permissions policies (identity-based) that say what the role may do.
Confusing the two is the most common mistake. Missing trust means “nobody can assume the role”. Missing permissions means “the role can be assumed but can do nothing”.
Worked example: a role for a SageMaker AI training job
A team wants a training job to read data from s3://amzn-s3-demo-bucket/train/ and nothing else. The trust policy lets the SageMaker AI service assume the role:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "sagemaker.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}
The permissions policy grants listing on the bucket and reads on the prefix, and no write or delete:
{
"Version": "2012-10-17",
"Statement": [
{ "Effect": "Allow", "Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::amzn-s3-demo-bucket" },
{ "Effect": "Allow", "Action": "s3:GetObject",
"Resource": "arn:aws:s3:::amzn-s3-demo-bucket/train/*" }
]
}
The job runs with temporary credentials from this role. Nothing is stored in the training image, and the blast radius if the job is compromised is read access to one prefix. The elements to recognise are Effect, Action, Resource, Principal (only in resource-based and trust policies) and the optional Condition. More on how SageMaker AI pieces use roles is in SageMaker components.
Policy types: which one limits, which one grants
AWS documents several policy types. For exams, sort them by whether they grant or only limit:
| Policy type | Attached to | Grants permissions? |
|---|---|---|
| Identity-based (AWS managed, customer managed, inline) | User, group or role | Yes |
| Resource-based (S3 bucket policy, role trust policy) | A resource | Yes, to the named principal |
| Permissions boundary | A user or role | No, sets a maximum for identity-based policies |
| Organizations SCP | Organization, OU or account | No, sets a maximum for principals in member accounts |
| Session policy | A role or federated session, passed when it is created | No, limits that session |
AWS managed policies are a quick start but may be broader than you need; customer managed policies give precise control. Inline policies are tied to one identity and deleted with it.
How a request is decided
For a request inside one account, the logic AWS documents reduces to four rules:
- Everything is denied by default (implicit deny).
- An allow in an identity-based policy or a resource-based policy is enough, as the permissions are a union.
- An explicit deny in any applicable policy overrides every allow.
- Boundaries, SCPs and session policies act as intersections: the action must also be allowed by each of them.
So a role with s3:* in its identity policy is still blocked by a bucket policy that denies it, or by an SCP that does not allow the action. SCPs never grant anything on their own. Cross-account is stricter: if the principal and the resource are in different accounts, the resource policy and an identity policy must both allow the access.
Which exams test this
| Exam | How it appears | On this site |
|---|---|---|
| AIF-C01 | Domain 5, Security, Compliance and Governance for AI Solutions (14%), objective 5.1: AWS features for securing AI systems, including IAM roles, policies and permissions, alongside encryption, Macie, PrivateLink and Bedrock Guardrails. The exam guide also lists IAM as recommended background knowledge | Security, compliance and governance |
| MLA-C02 | Domain 4, Operating, Monitoring and Securing ML and AI Solutions (24%): least-privilege access to ML artifacts (4.3.2), IAM policies and roles for users and applications (4.3.3), and choosing a credential type for foundation models, such as Bedrock API keys versus IAM credentials (4.3.8) | Operating, monitoring and securing |
The vendor-neutral exams (SY0-801, N10-009) also list “IAM”, but there it means identity and access management in general (authentication, authorisation, least privilege, RBAC), not the AWS service. See AAA for that angle.
How the exam builds IAM questions
The stem describes a workload and a constraint; the options mix roles, keys and policy types.
- “No long-term credentials” or “rotate keys automatically” points to a role. A role on the compute service, or federation, beats an IAM user with access keys.
- “Least privilege” points to the narrowest action and resource list. Wildcards (
*) and broad managed policies are the traps. - “Even though the user’s policy allows it, access is denied” points to an explicit deny, a boundary or an SCP. Read for the word deny.
- “Limit the maximum permissions a team can give to roles they create” is a permissions boundary. “Limit every account in the organisation” is an SCP.
- Bedrock API keys. AWS documents short-term keys (inheriting the permissions of the principal that generated them, valid up to 12 hours, recommended for production) and long-term keys (these create an IAM user and are recommended only for exploration). Choosing between them and normal IAM credentials is exactly the 4.3.8 skill. For the service landscape see Bedrock versus SageMaker and AWS AI services.
The responsibility split behind all of this is in cloud service models and shared responsibility.
Practice questions
Question 1. A role used by an ML pipeline has an identity-based policy that allows s3:GetObject on a bucket. The bucket policy contains a statement with Effect Deny for that role on s3:GetObject. Both are in the same account. What happens when the pipeline requests an object?
- A. The request succeeds because identity-based allows take priority over resource policies
- B. The request succeeds because both are in the same account
- C. The request is denied because an explicit deny overrides any allow
- D. The request is denied only if the role also has a permissions boundary
Show answer
Answer: C
An explicit deny in any applicable policy overrides an allow, so the request is denied. The identity-based allow does not rescue it, and being in the same account does not change that: same-account access is granted by the union of allows, but a deny still wins. A permissions boundary is not needed for the deny to apply.
Question 2. A team starts a SageMaker AI training job that must read training data from one S3 prefix. Security policy forbids storing access keys in containers or code. Which design meets the requirement with least privilege?
- A. An IAM user with access keys baked into the training image
- B. A role trusted by the SageMaker AI service, with a permissions policy allowing reads on that prefix only
- C. A role with a permissions policy but no trust policy
- D. A bucket ACL that grants public read access
Show answer
Answer: B
A role whose trust policy names the SageMaker AI service principal can be assumed by the job, and a permissions policy limited to reads on the prefix gives least privilege with temporary credentials. An IAM user with embedded keys violates the policy. A role without a trust policy cannot be assumed by the service. A public-read ACL exposes the data to everyone.
Go deeper
- Policy evaluation logic (AWS IAM User Guide)
- IAM roles and security best practices in IAM
- Amazon Bedrock API keys
- Related guides: zero trust explained, Azure RBAC versus Entra roles for the Azure equivalent, and how to study for certification exams.