# IAM, Security, and Compliance

> Chapter 4 of the Courseiva AWS-SYSOPS-ASSOCIATE curriculum — https://courseiva.com/learn/aws-sysops-associate/iam-security-and-compliance

**Official objective:** 5.1 — Manage AWS Identity and Access Management (IAM) and security best practices

## Introduction

IAM, Security, and Compliance—the single most important topic on the SOA-C02 exam, and the area where beginners lose the most points. If you don't secure access to your AWS resources, everything else you build can be stolen, deleted, or misused by attackers. This chapter gives you the foundational understanding to pass the exam and protect real-world cloud systems.

## The 3-Key Building Security Desk Analogy

At a 12-story office building with 4 different companies, the security desk doesn't hand every visitor a master key that opens every door and every filing cabinet. That would be chaos—anyone could walk into the CEO's office or the server room. Instead, each employee gets a specific badge that lists exactly which doors they can open between 7 a.m. and 7 p.m. Megan from accounting can unlock the break room and the bathroom on floor 4, but not the lab on floor 2. The security guard (that's the IAM system) decides who gets which badge based on a list written by each company's HR manager (the root user or admin). If Megan gets promoted, HR updates her badge permissions at the security desk—she never needs to hand back her physical badge. Nobody shares badges because if the guard sees two people using the same badge at the same time, he locks that badge and calls HR. All badge transactions are logged in a giant green book: every door opened, every time, by whom. This is precisely how AWS IAM works: you create identities, attach policies that list allowed actions (like 'open server room door'), and AWS logs every API call in CloudTrail. The key lesson: one master key equals a security disaster; the 3-key minimum of separate user, role, and permission sets prevents exactly that.

## Core explanation

IAM stands for Identity and Access Management. Think of it as the security guard for your entire AWS account. Every single action anyone or anything takes in AWS—launching a virtual server, reading a file from a storage bucket, deleting a database—must be explicitly allowed by IAM. If IAM says no, the action is blocked. That's it. No exceptions.

Every AWS account starts with one entity called the root user. The root user is created when you first sign up for AWS. It has complete, unrestricted access to everything in that account. This is extremely powerful—and extremely dangerous. AWS recommends you never use the root user for daily tasks. Instead, you create IAM users (individual people or services) and IAM roles (temporary identities for applications or AWS services).

The core mechanism of IAM is the policy. A policy is a JSON document (a text file with a specific format) that lists 'effect', 'action', and 'resource'. Effect is either Allow or Deny. Action is the specific AWS operation, like s3:ListBucket or ec2:RunInstances. Resource is the specific AWS object the action applies to, like an S3 bucket named 'my-company-data'.

Here is a simplified policy example:

{
  "Effect": "Allow",
  "Action": "s3:ListBucket",
  "Resource": "arn:aws:s3:::my-company-data"
}

This policy allows the identity to list the objects inside the bucket named 'my-company-data'—nothing else. If the policy were missing, or if it said 'Deny' instead, the action would be blocked.

Policies can be attached to:
- A user (a person logging into the AWS console)
- A group (a collection of users, like 'Developers' or 'Auditors')
- A role (a temporary identity that an AWS service, like an EC2 virtual machine, can assume)
- A resource (some AWS services, like S3 buckets, can have a policy directly attached—this is called a resource-based policy)

This flexibility is why AWS IAM replaces the old approach of hard-coding passwords or access keys into application code. In the old way, if a password leaked, you had to update code, redeploy, and hope no one had copied it. With IAM roles, a virtual server requests temporary credentials from AWS automatically, and those credentials expire after a set time (usually 1-6 hours). Even if the credentials are stolen, they are useless after expiration.

The exam tests several key IAM features:
- IAM Users: long-term credentials for people or applications. Each user has a friendly name, an optional password for the AWS console, and up to two access keys for programmatic access (API calls from code or command line).
- IAM Groups: a way to organise users. Instead of attaching the same 12 policies to 50 users individually, you attach them to a group and add users to that group. This saves time and reduces errors.
- IAM Roles: no long-term credentials. Instead, an entity (like an EC2 instance or a Lambda function) assumes a role and receives temporary security credentials from AWS STS (Security Token Service). These credentials include an access key, a secret key, and a session token. They expire automatically.
- IAM Policies: the rules. Policies are either AWS managed (created and maintained by AWS) or customer managed (created by you). There are also inline policies (embedded directly in a user, group, or role).
- IAM Permissions Boundaries: a way to set a maximum permission level. Even if a policy allows a certain action, if a permissions boundary denies it, the action is blocked. This is useful for delegating admin responsibilities safely.

A critical concept for the exam is the policy evaluation logic. AWS evaluates all policies attached to the user, the group, the role, and the resource. The default is Deny. If there is an explicit Deny anywhere, the action is blocked even if there is an Allow. If there is no Allow, the action is blocked. If there is at least one Allow and no Deny, the action is permitted. Memorise this order: explicit Deny wins over everything.

IAM also integrates with other AWS services for additional security:
- AWS CloudTrail logs all API calls made by users and roles. This gives you an audit trail of who did what, when, and from which IP address.
- AWS Config evaluates your resource configurations against desired rules (e.g., 'S3 buckets must not be publicly accessible') and alerts you when rules are violated.
- AWS KMS (Key Management Service) manages encryption keys used to protect data. IAM controls who can use those keys.

For the SOA-C02 exam, memorise these specifics:
- The root user should only be used for account-level tasks like closing the account, changing payment methods, or registering for certain support plans.
- Always enable multi-factor authentication (MFA) on the root user and all IAM users with console access.
- Use IAM roles for cross-account access—do not create duplicate users in multiple accounts.
- Use access keys only when you cannot use a role (e.g., for long-running on-premises applications). Rotate access keys regularly.
- Use the least privilege principle: grant only the permissions required to perform a task, no more.

Finally, IAM is global. It does not exist in a single AWS region. IAM users, groups, roles, and policies are available in every region. This means a single misconfiguration can affect resources across the entire world. Always review IAM policies using the IAM Access Analyzer, which identifies policies that grant unintended access to external entities.

Understanding IAM thoroughly is non-negotiable for passing SOA-C02. Approximately 10-15% of the exam questions directly test IAM concepts, and many other questions assume you understand how IAM works. Do not rush this topic.

## Real-world context

A typical day for a SysOps administrator managing IAM for a mid-sized e-commerce company, shopnow.net, which runs production, staging, and development environments in separate AWS accounts.

At 9:00 AM, Sarah checks her email and sees a ticket from the development team lead: 'Our new intern, Alex, starts tomorrow. He needs read-only access to the staging database for 30 days, and he should be able to launch EC2 instances in the dev account. Also, he must use MFA.'

Sarah opens the AWS IAM console in the dev account (where Alex will work). She does not create a new IAM user from scratch. Instead, she navigates to IAM > Users and clicks 'Add user'. She enters Alex's username (alex.dev.intern) and selects 'Provide user access to the AWS Management Console'. She sets a custom password and forces Alex to change it on first login.

Next, she does NOT attach policies directly to Alex's user. Instead, she creates an IAM group called 'Dev-Interns' and attaches two policies:

- AmazonEC2ReadOnlyAccess (an AWS managed policy that allows listing and describing EC2 instances, but not creating or deleting them)
- A custom managed policy she names 'Staging-DB-ReadOnly' which she builds using the visual editor: it allows 'rds:DescribeDBInstances' and 'rds:DownloadCompleteDBLogFile' on the staging database ARN.

Sarah adds Alex's user to the 'Dev-Interns' group. She also attaches an inline policy to Alex's user that requires MFA before any action is allowed—because the team lead specifically asked for MFA.

At 11:30 AM, a security alert from AWS Config shows that an IAM role named 'Prod-Deploy-Role' has a policy that allows 'iam:PassRole' to all resources. This is a security risk because it could allow someone to pass an admin role to an EC2 instance and escalate privileges. Sarah uses IAM Access Analyzer to validate the policy and identifies that the PassRole action is not scoped to a specific role. She edits the policy, changing the resource ARN to specify only the roles that should be passed.

At 2:00 PM, a developer calls: 'I need temporary access to the production database to troubleshoot a query. I should only have SELECT permission, and only for 30 minutes.' Sarah creates a temporary IAM role called 'Prod-DB-ReadOnly-Temp' with a trust policy that allows only the developer's IAM user to assume it. She attaches a policy granting 'rds:ExecuteSql' with a condition that restricts the SQL statements to SELECT only. She sets the role's maximum session duration to 30 minutes. The developer uses the AWS CLI to assume the role using sts:AssumeRole and receives temporary credentials.

At 4:00 PM, Sarah runs a script using AWS CLI that lists all IAM users in all accounts (using AWS Organizations) and checks if any have access keys older than 90 days. She finds three stale keys. She contacts the users and asks them to rotate keys. If they don't respond within 48 hours, she will deactivate the keys automatically via a Lambda function.

At the end of the day, Sarah reviews the last 24 hours of CloudTrail logs for any unusual API calls from unfamiliar IP addresses or regions. She finds none. She generates an IAM Credential Report that shows all users, their password ages, MFA status, and access key last used dates. She archives this report as part of the company's compliance requirements for SOC 2.

This real-world flow touches nearly every IAM concept tested on SOA-C02: user creation, groups, policies (managed and custom), roles, temporary credentials, MFA, password policies, access key rotation, permissions boundaries, cross-account access (through roles), CloudTrail auditing, and AWS Config rules. A SysOps admin does this daily. The exam expects you to know exactly which IAM feature to use in each situation.

## Exam focus

SOA-C02 tests IAM heavily, with questions appearing in every section of the exam. Expect 8-15 questions directly about IAM, plus another 10-15 questions where IAM is part of the solution.

The exam loves to test the following specific concepts, often in trick questions:

- Policy Evaluation Logic: The most common trap. AWS evaluates all policies in this order: explicit Deny, then explicit Allow, then default Deny. An explicit Deny always overrides an Allow. The exam will present a scenario where a user has an Allow policy and a Deny policy, and asks whether the action is permitted. The answer is always 'Denied'.

- Root User Restrictions: The exam tests exactly which tasks require the root user. Memorise this list: change account settings (account name, email, password), close the AWS account, change payment methods, register for certain AWS support plans (e.g., Enterprise Support), enable or disable IAM access to billing information, configure S3 bucket for CloudTrail log delivery (in some cases), and restore IAM user permissions. All other tasks CAN be done by an IAM user with appropriate permissions.

- Cross-Account Access: The exam will give a scenario where Company A needs to access resources in Company B's account. The correct answer is almost always to use an IAM role in Company B with a trust policy that allows Company A's account to assume the role. Never use IAM users in both accounts, and never share access keys.

- Resource-Based Policies vs. User-Based Policies: Some services (S3, SQS, SNS, Lambda, KMS) support both. The exam asks which policy takes precedence. The answer: both must allow the action. A resource-based policy that allows access AND a user-based policy that allows access are both required; if either denies, the action is denied.

- IAM Roles and Trust Policies: A role has two parts: the permissions policy (what the role can do) and the trust policy (who can assume the role). The trust policy is separate from the permissions policy. The exam will present a scenario where a role can do an action but the user cannot assume the role (trust policy missing), or vice versa.

- IAM Database Authentication: For RDS, you can use IAM to authenticate users to a database (PostgreSQL or MySQL) instead of a password. The exam tests that you need a special policy allowing 'rds-db:connect' to the database resource ARN.

- Permissions Boundaries: A permissions boundary sets the maximum permissions a user or role can have. Even if a policy attached to the user grants more permissions, the boundary limits them. The exam tests that you cannot use a permissions boundary to grant extra permissions—it only limits.

- Access Analyzer: This tool identifies resources (S3 buckets, IAM roles, KMS keys) that are shared with an external entity. The exam expects you to know it provides findings, not automatic remediation.

- Password Policies: The exam tests that you can enforce password complexity, rotation period, and reuse prevention in the IAM password policy. These apply to all IAM users in the account.

- Condition Keys: Conditions in policies allow fine-grained control, like 'aws:SourceIp' (allow only from a specific IP range), 'aws:RequestedRegion' (require the request to be made to a specific region), 'ec2:InstanceType' (only allow certain instance types), and 'iam:PassedToService' (limit which roles can be passed to services).

- Major trap: The exam will present a scenario where a user cannot access the AWS console, but the password policy is correctly configured, MFA is enabled, and the user exists. The answer is often that the user's IAM policy does not include the 'iam:ChangePassword' action, so they can't set a new password after the initial forced change.

To prepare for IAM questions in SOA-C02, you should:

- Create IAM users, groups, roles, and policies in your own AWS free tier account at least twice.
- Use the IAM Policy Simulator to test policies before applying them.
- Practise writing JSON policies by hand for common scenarios (read-only access to a specific S3 bucket, full access to EC2 in a specific region, cross-account role assumption).
- Memorise the five most common AWS managed policies used in exam scenarios: AdministratorAccess, PowerUserAccess, ReadOnlyAccess, AmazonS3ReadOnlyAccess, and AmazonEC2FullAccess.
- Understand that IAM is global, so a policy that works in us-east-1 works in ap-southeast-2.

The exam will not ask you to write JSON from memory, but it will present you with a JSON policy and ask you to interpret it. You must be able to read Effect, Action, Resource, and Condition statements.

## Step by step

1. **Create an IAM User for a New Employee** — Navigate to the IAM console, click 'Users', then 'Add user'. Enter a username (e.g., 'john.doe') and select 'Provide user access to the AWS Management Console'. Set a custom password and force a password reset on first login. This step creates an identity that can log into the AWS console but has no permissions yet. The exam tests that you must create a user before you can grant permissions.
2. **Assign the User to an IAM Group with Permissions** — Instead of attaching policies to the user directly, create or select an existing IAM group (e.g., 'Developers') and attach the necessary policies (like 'AmazonEC2FullAccess' and 'AmazonS3ReadOnlyAccess'). Then add the user to that group. This step demonstrates the best practice of using groups for permission management—it simplifies audits and future changes.
3. **Configure a Password Policy and Enable MFA** — In the IAM console, set an account password policy (minimum length, require symbols, rotation every 90 days). Then enable MFA on the root user and on the new user. The exam tests that password policies apply to IAM users only, not the root user. MFA is a critical security feature that the exam will ask about in scenario questions.
4. **Create an IAM Role for an EC2 Instance** — Go to IAM > Roles > 'Create role'. Select 'AWS service' and choose EC2. Attach a policy (e.g., 'AmazonS3ReadOnlyAccess'). Name the role 'EC2-S3-ReadOnly'. When launching an EC2 instance, assign this role to the instance. This step replaces hard-coded access keys with temporary credentials automatically rotated by AWS STS. The exam loves this pattern for EC2, Lambda, and ECS tasks.
5. **Review and Revise Permissions Using Access Analyzer and Policies** — Use IAM Access Analyzer to scan for policies that grant access to external entities (like 'Principal': '*'). Review findings and revise policies to restrict the resource ARN or add conditions (e.g., 'aws:SourceIp'). Then generate an IAM Credential Report to audit all users. This step mirrors real-world compliance work and the exam's focus on least privilege and auditing.
6. **Set Up Cross-Account Access Using a Role** — In Account B where resources live, create an IAM role with a trust policy that allows Account A's AWS account ID to assume it. Attach permissions (e.g., 'AmazonS3ReadOnlyAccess' to the bucket in Account B). In Account A, grant the user permission to call 'sts:AssumeRole' for that role. The user from Account A then switches roles in the console or uses the CLI. This step is the exam's standard solution for cross-account access.

## Comparisons

### IAM User vs IAM Role

**IAM User:**
- Long-term credentials: password and up to two static access keys
- Best for people who regularly log into the AWS console or use the CLI programmatically
- Credentials expire only when you manually rotate or delete them

**IAM Role:**
- Temporary credentials from AWS STS that expire automatically (default 1 hour, max 12 hours)
- Best for AWS services (EC2, Lambda, ECS) and cross-account access
- No passwords to manage; credentials are automatically rotated via the AssumeRole API

### Identity-Based Policy vs Resource-Based Policy

**Identity-Based Policy:**
- Attached to an IAM user, group, or role
- Controls what that identity can do across all AWS services
- Written as a JSON policy document with Effect, Action, and Resource

**Resource-Based Policy:**
- Attached directly to a resource like an S3 bucket, SQS queue, or Lambda function
- Controls who can access that specific resource
- Can specify Principal (who gets access) directly in the policy

### AWS Managed Policy vs Customer Managed Policy

**AWS Managed Policy:**
- Created and maintained by AWS; cannot be edited
- Updated automatically by AWS when new service features are added
- Examples: AmazonS3ReadOnlyAccess, AdministratorAccess

**Customer Managed Policy:**
- Created and maintained by you; you control all changes
- Must be updated manually when you need to add new permissions
- Gives you fine-grained control to match your company's exact requirements

### Permissions Boundary vs Service Control Policy (SCP)

**Permissions Boundary:**
- Applied to a specific IAM user or role within an AWS account
- Limits the maximum permissions that user or role can have
- Valid even if the user's attached policies grant more

**Service Control Policy (SCP):**
- Applied to an entire AWS account via AWS Organizations
- Limits the maximum permissions for all users and roles in that account
- Also affects the root user; SCPs are account-level guardrails

## Common misconceptions

- **Misconception:** If I attach an Allow policy to a user, the user automatically gets permission to do everything listed in the policy, even if another policy denies it. **Reality:** An explicit Deny always overrides an Allow. If any attached policy (including a group or role policy) has a Deny for the same action, the action is blocked. (Beginners assume permissions are additive, but AWS uses a 'Deny wins' rule. This confusion comes from everyday intuition that 'allow' means you can do it.)
- **Misconception:** The root user should always be used for administrative tasks because it has full access. **Reality:** The root user should almost never be used. Create an IAM user with AdministratorAccess policy instead. Use root only for specific account-level tasks like closing the account. (In many operating systems, the admin account (like root on Linux) is used daily. AWS's root user is far more powerful and can't be limited—a single leaked root password compromises everything.)
- **Misconception:** IAM users are the only way to give applications access to AWS resources. **Reality:** Applications running on AWS (like an EC2 instance) should use an IAM role, not an IAM user with long-term access keys. Roles provide temporary credentials that rotate automatically. (Developers are used to storing passwords in config files. IAM roles remove the need to manage and rotate secrets, reducing security risk. This is a core AWS best practice many miss.)
- **Misconception:** The IAM password policy applies to all users, including the root user. **Reality:** The IAM password policy applies only to IAM users, not to the root user. The root user password is managed separately in the account settings. (The console interface groups password policy under 'IAM', so beginners assume it covers root. AWS intentionally separates root user management from IAM for security.)
- **Misconception:** If a user is a member of two IAM groups, and one group's policy allows an action but the other group's policy doesn't mention it, the user cannot perform the action. **Reality:** If an action is allowed by any policy attached to the user (including group policies), and no policy explicitly denies it, the user can perform the action. The default is deny, but an explicit Allow from any source suffices. (People mistakenly think group permissions conflict and cancel out. AWS uses additive Allow logic—if any attached policy says 'Allow', the action is allowed unless an explicit Deny exists.)
- **Misconception:** IAM roles are only for human users, not for AWS services. **Reality:** IAM roles are specifically designed for AWS services like EC2, Lambda, and ECS. Services assume roles to get temporary credentials. Humans can also assume roles, but that's a secondary use. (The word 'role' sounds like a job title for a person. Beginners don't immediately connect it to automatic credential generation for software.)

## Key takeaways

- IAM is always global—a user or policy created in one region works in every AWS region worldwide.
- Explicit Deny overrides every Allow—the order is: deny, then allow, then default deny.
- The root user should only be used for account-closing, billing changes, and specific support plan registrations—never for daily administration.
- Always use IAM roles for EC2 instances and Lambda functions instead of hard-coding access keys.
- A resource-based policy (like an S3 bucket policy) and an identity-based policy (like a user policy) must both allow the action—if either denies, the action is blocked.
- MFA must be enabled on the root user and on every IAM user with console access to pass the exam's security best practices.
- IAM Access Analyzer identifies resources shared with external accounts—it does not fix them automatically.
- A permissions boundary limits what a user or role can do, even if their attached policies grant more—it never grants permissions.
- The IAM Credential Report provides a CSV file showing all users, password ages, MFA status, and access key last used dates.
- Use IAM groups to manage permissions efficiently—assign policies to a group, then add users to the group.

## FAQ

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

An IAM user has long-term credentials (a password and up to two static access keys) and is associated with a person or application for ongoing use. An IAM role has no long-term credentials; instead, it provides temporary security credentials that expire after a set period (usually between 1 and 12 hours). Roles are assumed by services (like EC2) or by users who need temporary elevated access.

**Can I delete the root user?**

No. The root user cannot be deleted—it is the account owner by definition. However, you can secure it by enabling MFA, using a strong password, and never using it for daily tasks. You can also delete all IAM users and roles, but the root user persists.

**What does 'aws:SourceIp' mean in an IAM policy?**

'aws:SourceIp' is a condition key that restricts an action to requests originating from a specific IP address or range. For example, you can write a policy that allows 'ec2:TerminateInstances' only if the source IP is within your company's VPN CIDR block. This prevents attackers from terminating instances from outside the network.

**How do I give someone in another AWS account access to my S3 bucket?**

You have two options. The recommended way is to create an IAM role in your account with a trust policy that allows the other account to assume it, and attach a policy granting s3:GetObject on the bucket. The other option is to attach a resource-based policy directly to the S3 bucket that grants access to the other account's root user or a specific IAM user in that account.

**What happens if I attach an inline policy and a managed policy to the same user?**

Both policies are evaluated together. If either policy explicitly allows an action and neither explicitly denies it, the action is allowed. If one denies and the other allows, the deny wins. You can attach up to 10 policies (inline and managed combined) to a single user, though AWS recommends using groups instead.

**Is IAM a regional or global service?**

IAM is a global service. IAM users, groups, roles, and policies you create are available in every AWS region. However, the resources they control (like EC2 instances in a specific region) are regional. You cannot restrict an IAM user to only exist in one region—they apply worldwide.

**What is the difference between an IAM policy and an S3 bucket policy?**

An IAM policy is an identity-based policy—it is attached to a user, group, or role and defines what that identity can do. An S3 bucket policy is a resource-based policy—it is attached directly to an S3 bucket and defines who can access that bucket. For an action to succeed, both the identity policy and the resource policy must allow it (unless a deny overrides).

---

Interactive version with quiz and diagrams: https://courseiva.com/learn/aws-sysops-associate/iam-security-and-compliance
