Courseiva
SCS-C02Chapter 1 of 19Objective 1.1

IAM Fundamentals and Policy Basics

IAM (Identity and Access Management) is the service that controls who can do what inside your AWS account. Without IAM, your account would be like a bank vault with the door left open—anyone with the account email and password could delete everything. For the SCS-C02 exam, you must understand how to write and evaluate IAM policies because they are the primary way to enforce security boundaries in AWS.

12 min read
Beginner
Updated Jul 23, 2026
Editorial oversight: Johnson Ajibi· Security Systems Architect · MSc IT Security · IEEE Senior Member

A simple way to picture IAM Fundamentals and Policy Basics

The Office Building Access Card Analogy

An office building uses an electronic access card system to control who can enter which rooms. The building does not have a single front door that opens for everyone. Instead, each employee receives a plastic card programmed with specific permissions. The card itself is not the employee’s identity—it is a token that proves the employee belongs to a certain group.

The building’s central security server checks every card against a policy. That policy states exactly which doors the card can unlock and during what hours. For example, a junior accountant’s card might open the main entrance, the lift, and the accounting office, but never the server room or the CEO’s office. The policy can also say “this card works only between 8 AM and 6 PM” or “this card is revoked immediately if the employee resigns.”

In the same way, AWS Identity and Access Management (IAM) uses policies to control who can access which AWS resources and what actions they can perform. An IAM policy is like the building’s access control list. An IAM user is like an employee with a card. The AWS service (like an S3 bucket or an EC2 instance) is like a locked room. The policy defines whether the user can open that room, read its contents, write new files, or delete them. Without a policy, no card works—just as in AWS, an explicit deny overrides any allow. The building manager does not hand out master keys; they grant the minimum access needed for each job. This is the principle of least privilege, and it is the foundation of AWS security.

How It Actually Works

IAM stands for Identity and Access Management. It is a free AWS service that lets you create users, groups, and roles, and attach permissions to them using policies. A policy is a JSON document that states which actions are allowed or denied on which resources. Policies are the rules of the game.

First, let us define the key building blocks. An IAM user is a person or service that needs to interact with AWS. Each user has a name, a password for the AWS Management Console, and optionally access keys for programmatic access. An IAM group is a collection of users. You attach policies to a group, and every user in that group inherits those permissions. For example, you could create a “Developers” group and attach a policy that allows read-only access to all EC2 instances. Then any developer added to that group automatically gets that access.

An IAM role is different from a user. A role does not have long-term credentials (a password or access keys). Instead, a role is assumed by a trusted entity—such as an AWS service (like an EC2 instance), or a user from another AWS account—and it issues temporary security credentials. Temporary credentials expire after a set period (between 15 minutes and 12 hours). This is far more secure than hard-coding long-term keys.

Now let us look at policies in detail. A policy is a JSON object with statements. Each statement has several elements: Effect (Allow or Deny), Action (the list of AWS API actions, like s3:ListBucket or ec2:RunInstances), Resource (the Amazon Resource Name—ARN—of the AWS resource the action applies to), and Condition (optional criteria that must be met for the policy to apply). For example, a policy might say: “Allow ec2:RunInstances on all EC2 resources, but only if the instance type is t2.micro.” The Condition element uses keys like aws:SourceIp or ec2:InstanceType.

AWS evaluates policies using an explicit deny model. By default, all requests are denied. If an allow statement matches the request, the request is allowed—unless a deny statement also matches. Because deny overrides allow, you can write a broad allow and then a specific deny to block dangerous actions. For example, you could allow all S3 actions but add a deny that prevents deletion of buckets. This structure is how AWS prevents privilege escalation.

There are two types of policies: identity-based policies and resource-based policies. Identity-based policies attach to a user, group, or role and control what that identity can do. Resource-based policies attach directly to a resource (like an S3 bucket or an AWS Lambda function) and control who can access that resource. For example, an S3 bucket policy can grant cross-account access without creating a role in the other account.

AWS also offers managed policies (pre-written by AWS or by your organisation) and inline policies (written directly on a user or role). AWS managed policies are convenient but often too permissive for the principle of least privilege. For the exam, you should prefer customer-managed policies for fine-grained control.

Finally, you need to understand how to read an ARN (Amazon Resource Name). An ARN uniquely identifies an AWS resource. Its format is: arn:partition:service:region:account-id:resource-type/resource-name. For instance, arn:aws:s3:::my-bucket identifies the bucket named “my-bucket”. In policies, you use ARNs to specify which resources the actions apply to. You can use wildcards—the asterisk (*) means “all”. For example, arn:aws:s3:::* means all S3 buckets in the account.

Why does this exist? Before IAM, AWS accounts shared a single root user that could do everything. That was a huge security risk. IAM gave administrators the ability to grant granular permissions, audit who did what, and rotate credentials safely. It replaced the all-or-nothing model with a least-privilege model. For SCS-C02, you will be tested on how to write a policy that allows exactly the required actions and nothing extra.

This diagram shows the three types of IAM identities (user, role, group) and how policies attach to them or to resources to grant or deny access.

Walk-Through

1

Define the trust entity

Decide who or what will use the permissions. For a human, create an IAM user. For an AWS service like EC2, create an IAM role. For a group of users with the same job function, create an IAM group. This step is critical because the type of entity determines how you attach the policy and whether you need long-term or temporary credentials.

2

Write the policy document

Create a JSON policy that specifies the Effect (Allow or Deny), Action (list of AWS API calls), Resource (the ARN of the resource), and optionally Condition (e.g., source IP, MFA status). Use AWS Policy Generator or write it manually. Start with the principle of least privilege: grant only the actions needed for the job.

3

Attach the policy to the entity

Attach the identity-based policy to the user, group, or role you defined in step 1. Alternatively, attach a resource-based policy directly to a resource like an S3 bucket. If you use a group, all users in that group inherit the policy. This step applies the permissions you defined.

4

Test the policy using the IAM Policy Simulator

Use the AWS IAM Policy Simulator to test your policy before deploying it. Enter the user, the action, and the resource, and the simulator will tell you whether access is allowed or denied. This is important to catch unintended denies or overly permissive allows.

5

Monitor and audit with CloudTrail and Access Analyzer

After deployment, regularly review IAM Credential Reports to check key rotation and usage. Enable AWS CloudTrail to log all API calls. Use IAM Access Analyzer to identify policies that grant access to external entities. This step ensures you maintain a secure posture over time.

What This Looks Like on the Job

Imagine you are the cloud security engineer for a mid-sized e-commerce company that uses AWS. Your team has three developers who need to deploy code to EC2 instances, two data analysts who query data in S3 and Athena, and one DevOps engineer who manages the CI/CD pipeline.

Your first task is to create IAM users for each person. You do not use the root user except for billing. Instead, you create a user called “dev-alice”, “dev-bob”, “data-charlie”, and “devops-diana”. You put Alice and Bob into a group called “Developers”. You create a group called “DataAnalysts” for Charlie, and a group called “DevOps” for Diana.

Now you need to write policies. You start with a managed policy called “AmazonEC2ReadOnlyAccess” for the Developers group—but you realise that gives them read-only access to everything EC2, including the ability to see security groups. That is too much. So you create a custom policy that allows only ec2:DescribeInstances, ec2:DescribeImages, and ec2:RunInstances, but restricts the region to us-east-1 and restricts instance types to t3.micro and t3.small. You attach that policy to the Developers group.

For the DataAnalysts group, you attach an S3 read-only policy that allows s3:GetObject and s3:ListBucket, but only on the bucket named “company-data-prod”. You add a condition that forces MFA (multi-factor authentication) for every request. For Charlie, you also attach a policy that allows athena:StartQueryExecution and athena:GetQueryResults on a specific workgroup.

For Diana in DevOps, you create a role that an EC2 instance assumes to access the CI/CD pipeline. The role has permissions to write to an S3 bucket for artifacts and to launch new EC2 instances using a specific AMI. Diana does not get a password for the console; she uses AWS CLI with temporary credentials from AWS Single Sign-On (SSO).

Now a real-world problem: a developer accidentally exposes an access key in a public GitHub repository. With IAM, you can immediately rotate that user’s access keys and review CloudTrail logs to see what actions the compromised key performed. You also disable the user until the developer verifies their identity.

As a security professional, you also set up a permissions boundary for any role that developers create. A permissions boundary is a managed policy that sets the maximum permissions a role can have. For example, you create a boundary that prevents any role from accessing DynamoDB tables with names starting with “prod-”. This way, even if a developer inadvertently attaches an overly permissive policy, the boundary caps it.

Finally, you schedule periodic reviews using IAM Access Analyzer to identify policies that grant access to external principals (like another AWS account). You also use IAM Credential Report to find users who have not rotated their keys in 90 days. These are the day-to-day actions of an AWS security engineer.

How SCS-C02 Actually Tests This

SCS-C02 devotes a significant portion of Domain 1 to evaluating and writing IAM policies. You must be able to read a JSON policy and determine whether a given request is allowed or denied. The exam loves to test the order of evaluation: explicit deny always wins over any allow. If a policy has a Deny statement that matches the request, the request is denied even if an Allow statement also matches.

Another frequent trap involves the NotAction and NotResource elements. For example, a policy that says “Deny all actions except those in the NotAction list” can be counterintuitive. You must memorise that NotAction means “all actions except these”. Similarly, NotResource means “all resources except these”. The exam will present a policy that uses NotAction and ask if a specific action is denied.

Key concepts that appear repeatedly:

Condition keys: especially aws:SourceIp, aws:MultiFactorAuthPresent, and aws:RequestedRegion. You must know how to enforce MFA or restrict to a specific IP range using conditions.

Resource-based policies vs identity-based policies. For example, an S3 bucket policy that grants access to a user from another account is a resource-based policy. The exam will ask which policy evaluation model applies when both identity-based and resource-based policies exist. The answer is that if either policy allows the request (and no deny exists), the request is allowed.

PassRole permission: the iam:PassRole action is critical. You can pass a role to an AWS service (like EC2) only if you have the iam:PassRole permission on that role. The exam will test that you cannot launch an EC2 instance with a role unless you have this permission.

Permissions boundaries: they limit the maximum permissions an IAM entity can have. They work in conjunction with identity-based policies. The exam will ask: if a user has an identity-based policy that allows s3:* but a permissions boundary only allows s3:GetObject, what can the user do? Answer: only s3:GetObject because the boundary caps the effective permissions.

Service Control Policies (SCPs) from AWS Organizations: SCPs apply to all accounts in an organisation and act as a guardrail. They do not grant permissions; they only deny. The exam will want you to distinguish between SCPs and IAM policies.

Session policies: when you assume a role, you can pass a session policy that further restricts the role’s permissions. This is used for temporary elevated access.

The most common question type is a multiple-choice question that gives you a policy JSON and asks: “Which action will result in an allowed response?” The trick is often a missing condition or a wildcard that matches an unexpected resource. Always check the Effect, then the Action, then the Resource, then any Conditions. Also check for explicit Deny statements. If you see Deny with a wildcard in Resource, it probably overrides an Allow.

Another pattern: the exam gives a scenario where an administrator wants to grant read-only access to a bucket but prevent listing of objects. The correct answer is a policy that allows s3:GetObject but denies s3:ListBucket. Many beginners try to use NotResource incorrectly. Memorise that to restrict listing, you need an explicit Deny on s3:ListBucket.

Finally, understand the difference between an IAM user and an IAM role. The exam loves to ask: “Which would you use for an application running on an EC2 instance?” The answer is always a role (with an instance profile) because it provides temporary credentials that rotate automatically. Using a user with long-term access keys is a security anti-pattern.

Key Takeaways

AWS IAM uses an explicit deny model: an explicit Deny always overrides any Allow, even if the Allow is more specific.

An IAM role provides temporary credentials that expire, making it more secure than using long-term access keys for applications.

Permissions boundaries set the maximum permissions an IAM entity can have, even if an attached identity-based policy grants more.

Resource-based policies, such as S3 bucket policies, can grant cross-account access without needing to create IAM roles in the other account.

The iam:PassRole permission is required to pass a role to an AWS service; without it, you cannot launch an EC2 instance with a role.

Service Control Policies (SCPs) act as guardrails across all accounts in an AWS Organisation and can only deny permissions, not grant them.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

IAM User

Has long-term credentials (password and access keys) that never expire unless rotated.

Directly represents a specific person or application.

Cannot be assumed by multiple entities at the same time without creating duplicates.

IAM Role

Provides temporary credentials that expire between 15 minutes and 12 hours.

Can be assumed by multiple trusted entities (users, services, accounts) simultaneously.

Does not have its own password or access keys; it is a placeholder for permissions.

Identity-Based Policy

Attached to an IAM user, group, or role.

Controls what actions the identity can perform on which resources.

Can be used for any AWS resource, but only affects the identity it is attached to.

Resource-Based Policy

Attached directly to a resource (like an S3 bucket or a Lambda function).

Controls who can access that specific resource.

Can grant cross-account access without needing a role in the target account.

Allow Policy

Permits a specific action on a specific resource.

Only takes effect if no Deny statement matches the request.

Often used to grant least-privilege permissions.

Deny Policy

Blocks a specific action on a specific resource, overriding any Allow.

Takes precedence over Allow, even if the Deny is less specific.

Used to explicitly prohibit dangerous actions (e.g., deleting a critical bucket).

Watch Out for These

Mistake

An IAM user is the same as a 'user account' like on a laptop — they can log in and do everything by default.

Correct

An IAM user has no permissions at creation. You must explicitly attach policies to grant any access. They cannot do anything until you allow it.

Because many beginners come from operating systems where a new user account automatically has some default permissions (e.g., can read their own files). AWS starts from a completely locked-down state.

Mistake

If a user has an Allow policy on S3 and also a Deny policy on S3, the Allow wins because it is more specific.

Correct

Deny always wins over Allow, regardless of specificity. AWS uses an explicit deny model. Even a generic Deny overrides a very specific Allow.

This conflicts with the common-sense rule in many other systems where a specific exception overrides a general rule. AWS deliberately chose deny-override for security.

Mistake

You need to attach a policy to the root user to give yourself access.

Correct

The root user already has full administrative access by default. You cannot attach policies to the root user, and you should never use the root user for daily tasks. Instead, create an IAM admin user with MFA.

Because the root user is the owner of the account with unrestricted power. Beginners think they need to 'enable' access via policies, but it is the opposite.

Mistake

If a policy uses NotAction, it means 'deny everything in this list'.

Correct

NotAction means 'all actions except the ones listed'. For example, NotAction: ec2:TerminateInstances means the policy applies to every action except terminating instances.

The word 'Not' is confusing. Beginners read it as a restriction, but it is an exclusion. It is a frequent exam trap.

Mistake

You can attach a resource-based policy to an IAM user or role.

Correct

Resource-based policies attach only to AWS resources (like S3 buckets, SQS queues, Lambda functions). Identity-based policies attach to users, groups, and roles.

Because both the word 'policy' and the concept of 'attaching' are similar. Beginners mix up what the policy is attached to.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

Can I give an IAM user permanent access keys?

Yes, you can generate access key ID and secret access key for any IAM user. However, these are long-term credentials and should be rotated regularly. It is more secure to use IAM roles with temporary credentials whenever possible.

What is the difference between an IAM role and an IAM user?

An IAM user has permanent long-term credentials (password and/or access keys) and represents a specific person or application. An IAM role does not have long-term credentials; it is assumed by a trusted entity to receive temporary security credentials.

How do I allow a user from another AWS account to access my S3 bucket?

You attach a resource-based policy (an S3 bucket policy) that grants access to the other account's user or role. You do not need to create an IAM user in your account for them.

What does the 'Effect' element in a policy do?

The Effect can be 'Allow' or 'Deny'. If it is Allow, the permitted actions are allowed. If it is Deny, the actions are blocked even if another policy allows them. Deny takes precedence over Allow.

Why does AWS recommend using IAM roles instead of IAM users for applications?

Roles provide temporary credentials that automatically rotate, reducing the risk of leaked keys. Users have permanent credentials that can be stolen and misused until they are rotated.

What is a permissions boundary in IAM?

A permissions boundary is a managed policy that sets the maximum permissions an IAM entity (user or role) can have. It limits what the entity can do, even if an attached identity-based policy grants more.

Terms Worth Knowing

Keep going

You've finished IAM Fundamentals and Policy Basics. Continue through the SCS-C02 study guide to build a complete picture of the exam.

Done with this chapter?