# Mastering AWS Security Specialty - Post 1: Deep Dive into IAM – Core of AWS Security

---

## What Is IAM and Why It Matters

AWS **Identity and Access Management** is at the core of AWS security. It determines who can access what, how, and under what conditions.

**Note**: IAM protects AWS APIs only.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745675860170/922662ff-57b8-46c7-ba1a-e10cc4503fc2.png align="center")

> AWS IAM is your **initial defense layer.** Misconfiguration can result in overly permissioned access—or worse, exposed data.

---

## IAM Identities

| **Identity** | **Description** | **When to Use** | **Example** |
| --- | --- | --- | --- |
| **User** | Represents an individual or a service | Long-term identity, used for console or programmatic access | Developers, CI/CD tools |
| **Group** | A collection of users | Apply same policies to multiple users | Developers group with S3 access |
| **Role** | Temporary credentials | Used by AWS services, users, applications, external identities | EC2 to access S3, cross-account access |
| **Federated User** | External identity (AD, Google, etc.) authenticated via STS | Don’t want to manage IAM users. | SSO with Okta or AD Federation |
| **Service-linked Role** | Predefined role linked to AWS service | Allows AWS service to manage resources on your behalf | AWS Elastic Beanstalk role, Auto scaling. |
| **AWS Account Root User** | Full access identity created during account setup | Only for billing or account recovery | Never use for daily tasks |

---

## IAM Policies

An IAM policy is a **JSON document** that must follow a strictly defined format.

### Primary Elements of policy:

* **Principal** : *Who is making the request*. It is an Identity that sends the request, such as user, role, AWS service, or some special entity.
    
* **Action** : *What they want to do.* It defines what the Principal wants to do, such as reading an object in S3.
    
* **Resource**: *What they want to access*. It is the logical entity in the account. Any AWS service that is the subject/target of the request.
    

---

## IAM Policy Filters

Elements like `Principal/NotPrincipal,` `Action/NotAction,` Resource/NotResource can serve as filters.

example policy:

```bash
    {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowSpecificPrincipalAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:user/SpecificUser"
      },
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::example-bucket"
    },
    {
      "Sid": "DenyAllExceptSpecificPrincipals",
      "Effect": "Deny",
      "NotPrincipal": {
        "AWS": "arn:aws:iam::111122223333:user/SpecificUser"
      },
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::example-bucket/*"
    },
    {
      "Sid": "AllowExceptSpecificActions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/SpecificRole"
      },
      "NotAction": [
        "s3:DeleteObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::example-bucket/*"
    },
    {
      "Sid": "DenySpecificResources",
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:user/SpecificUser"
      },
      "Action": "s3:*",
      "NotResource": "arn:aws:s3:::example-bucket/specific-folder/*"
    }
  ]
}
```

---

## IAM Policy Conditions

Conditions refine permissions by specifying when a policy statement is applicable.

**Key Components:**

* **Condition Keys**: Predefined or AWS-specific keys (e.g., `aws:SourceIp`, `s3:Prefix`).
    
* **Condition Operators**: Logical operators to compare values (e.g., `StringEquals`, `IpAddress`).
    
* **Condition Values**: The value(s) against which the condition key is evaluated
    

### **Condition Types**

#### **1\. Global Condition Keys**

These keys are common across all AWS services.

* **Examples**:
    
    * `aws:SourceIp`: Restrict access based on the IP address.
        
    * `aws:UserAgent`: Restrict access based on the user agent of the client.
        
    * `aws:RequestTag`: Control access based on request tags.
        
    * `aws:MultiFactorAuthPresent`: Check if MFA is used.
        

#### **2\. Service-Specific Condition Keys**

Each AWS service has its own condition keys. Below are examples from popular services:

* **S3 (Amazon Simple Storage Service)**:
    
    * `s3:Prefix`: Control access to objects with a specific prefix.
        
    * `s3:x-amz-acl`: Restrict actions based on the ACL used in the request.
        
    * `s3:RequestObjectTagKeys`: Control access based on object tags in the request.
        
* **EC2 (Elastic Compute Cloud)**:
    
    * `ec2:Region`: Restrict actions to a specific region.
        
    * `ec2:InstanceType`: Control actions based on instance type.
        
* **KMS (Key Management Service)**:
    
    * `kms:EncryptionContext:Key`: Restrict access based on encryption context keys.
        
    * `kms:ViaService`: Control access based on the service that is using the key.
        
* **IAM (Identity and Access Management)**:
    
    * `iam:PolicyARN`: Restrict actions based on attached policy ARNs.
        
    * `iam:ResourceTag`: Control access based on resource tags.
        
* **CloudWatch**:
    
    * `cloudwatch:Namespace`: Restrict actions to specific namespaces.
        
    * `cloudwatch:ResourceTag`: Control actions based on tags.
        

#### **3\. Common Operators**

* `StringEquals`: Checks if the string matches exactly.
    
* `StringLike`: Checks if the string matches a pattern (wildcards supported).
    
* `IpAddress`: Checks if the IP address is in specific ranges.
    
* `NumericEquals`: Checks if a numeric value matches.
    
* `DateEquals`: Checks if a date matches.
    
* `Bool`: Checks if a value is `true` or `false`.
    

---

## IAM Policy Types

***How* a policy behaves is determined by *what* it is attached to.** We can attach a policies to different entities as below, and they are named accordingly.

### 1\. **Identity-based:**

* Grant permissions to identities, attached to user, group, or role. As it attached to a Principal so there is no `Principal` element in policy.
    

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::app-logs/audit.log"
        },
        {
            "Effect": "Deny",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::app-logs/*"
        }
    ]
}
```

### 2\. **Resource-based:**

* Defined on the resource (e.g., S3 bucket policy, Lambda permission). Supports cross-account access. Only certain services support resource-based policies (S3, SNS, SQS, Lambda, etc.)
    

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789:role/app-auditors"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::app-log/audit.log"
        }
    ]
}
```

**Note**: All resources NOT supports Resource-based policies refer the [table](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html#all_svcs) for details

### 3\. **Permission Boundaries:**

* Limit max permissions regardless of attached policies. Important for delegated access.
    
    Delegate admin role to developers but cap their power using **permissions boundaries**
    

***Policy***

```json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
  }]
}
```

***Boundary***

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "LimitToSpecificServices",
            "Effect": "Allow",
            "Action": [
                "s3:*",                 // Allows S3 actions
                "ec2:Describe*",        // Allows describing EC2 resources
                "lambda:InvokeFunction" // Allows invoking AWS Lambda
            ],
            "Resource": "*"
        },
        {
            "Sid": "DenySensitiveActions",
            "Effect": "Deny",
            "Action": [
                "iam:*",             // Deny IAM actions
                "ec2:Terminate*"     // Deny EC2 termination
            ],
            "Resource": "*"
        }
    ]
}
```

### 4\. **Session Policy:**

* Attached to STS temporary session to restrict permissions during a role/session. Used during AssumeRole. They do not limit what the identity (who is using a role) can do, but they put self-imposed restraints on the permissions.
    

A role that has full access to all S3 buckets

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*"
        }
    ]
}
```

However, you want to ensure that during the session, this user can only access a specific S3 bucket (`example-bucket`) and only perform read operations (`GetObject`).

`Session-policy-example.json`

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowReadAccessToSpecificBucket",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::example-bucket/*"
      ]
    },
    {
      "Sid": "DenyAllOtherS3Actions",
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}
```

Apply the Session Policy:

```bash
aws sts assume-role \
    --role-arn "arn:aws:iam::123456789012:role/FullAccessRole" \
    --role-session-name "RestrictedSession" \
    --policy file://session-policy-example.json
```

### 5\. **Service Control Policies (SCPs)**:

Org-level permission filter. It sets permission boundaries for accounts. **Note**: *Cannot grant permissions, only restrict.*

> An operation is denied if it does not explicitly allowed.

We can use 2 approaches to define the policy -

**Allow Listing** will restrict all except allowed in policy.

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*"
        }
    ]
}
```

**Deny listing** will allow except explicitly denied.

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": "iam:*",
            "Resource": "*"
        }
    ]
}
```

### 6\. **Inline Policies**:

Attached to a single identity (User, Group, Role). Use when the policy is unique and shouldn’t be reused. When we delete the identity, the policy is deleted with it.

### 7\. **Managed Policies**:

Managed policies are separate permission resources that we can attach to multiple identities and manage in a central place.

1. **AWS Managed:** Created by AWS for most common use-cases. (e.g., `AmazonS3FullAccess`)
    
2. **Customer Managed:** You define it (recommended for control). When multiple identities need same access create your own in IAM Policy.
    

---

## Permissions Boundaries vs SCPs

| **Feature** | **Permissions Boundary** | **SCP** |
| --- | --- | --- |
| Applies to | IAM User/Role | AWS Account/OU |
| Limits | Max permissions | All IAM permissions |
| Use Case | Delegation, control | Multi-account governance |

---

## IAM Policy Evaluation Logic

* **Explicit Deny &gt; Allow &gt; Implicit Deny**
    
    * ***If*** there is a Deny, ***then*** denied.
        
    * ***If*** there is no Allow, ***then*** denied.
        
* Policies from all sources (user, group, role) are merged
    

> Denies override all allows.

![Policy evaluation logic](https://advancedweb.hu/assets/8ada9075ee331e95a350a001bee9b10e00ab1ac122c07964536782b77dd0ebf8.png align="left")

---

## Types of IAM Roles

| **Role Type** | **Purpose** | **How/When to Use** | **Example** |
| --- | --- | --- | --- |
| **Service Role** | Grant AWS services permissions | Use with EC2, Lambda, ECS, etc. | EC2 to write logs to CloudWatch |
| **Cross-account Role** | Share access between AWS accounts | Used in centralized logging, multi-account strategy | Admin role in Shared Services account |
| **Federated Role** | Used by external identities via STS | Integrate corporate directory | SAML or OIDC federation |
| **Role for Applications** | Temporary credentials for apps | Use with mobile/web apps | Cognito + IAM role |
| **Service-linked Role** | Required by AWS services | Automatically created | AWS Config or Elastic Beanstalk roles |

---

## IAM Security Best Practices

* Enable **MFA for all users**
    
* Use **roles instead of long-term credentials**
    
* Implement **least privilege access**
    
* Enable **Access Analyzer** to spot unintended access
    
* Tag identities for better management and automation
    

---

## Summary & What’s Next

IAM is foundational. You now understand:

* Different IAM entities
    
* Policy types and their roles
    
* Evaluation logic and best practices
    

**Exam Tips:**

| **Topic** | **Things to Remember** |
| --- | --- |
| **Policy Evaluation** | Explicit Deny &gt; Allow &gt; Implicit Deny |
| **MFA Policies** | You can require MFA via conditions in policy |
| **Federation** | Know difference between SAML, OIDC, and IAM Identity Center |
| **SCP** | Does NOT grant permissions, only restricts |
| **Access Analyzer** | Exam focuses on detecting unwanted access |
| **IAM Roles** | Require trust policy and are assumed using STS |
| **IAM User Keys** | Rotate regularly and avoid long-term usage |
| **Service-linked Roles** | Auto-created by AWS services – don’t modify manually |
| **Session Duration** | Can control using `sts:DurationSeconds` in trust policy |
| **Principal of Least Privilege** | Always enforce minimum required access |

**Coming Up:**  
Next, we’ll dive into **AWS CloudTrail** — your forensic lens into AWS.  
Stay tuned for more in the **"Mastering AWS Security Specialty"** series!

---

To understand big picture of AWS Security Services, check “[Choosing the Right AWS Security Services: A Solution Architect's Guide](https://techbrains.hashnode.dev/choosing-the-right-aws-security-services-a-solution-architects-guide)”
