02. Security

Author

Senthil Kumar

๐Ÿ‘ˆ Back to: ๐Ÿ“ Blog | ๐Ÿ’ผ LinkedIn | โœ๏ธ Medium


2.1 Responsibility of IAM Service in AWS - Who can do What

Who can do What: This is the fundamental IAM question.

IAM decides who can call which AWS APIs on which resources.

Security in AWS revolves around:

  • Authentication โ†’ Who are you?
  • Authorization โ†’ What are you allowed to do?

Everything ultimately resolves to an AWS API call being evaluated against policies.


2.2 Security in AWS - 5000 feet View

flowchart LR
  A[Security in AWS]
  A --> B["AWS Identity<br>and Access<br>Management (IAM)"]
  A --> C[Security Best Practices]

  %% IAM branches
  B --> B1[Purpose]
  B --> B2[IAM Identities]
  B --> B3[IAM Policies]
  B --> B4[IAM Characteristics]

  %% Purpose
  B1 --> P1["Authentication<br/>(Who are you?)"]
  B1 --> P2["Authorization<br/>(What can you do?)"]

  %% Identities
  B2 --> I1["IAM User<br/>(Human or service)"]
  B2 --> I2["IAM Group<br/>(Users + shared permissions)"]
  B2 --> I3["IAM Role<br/>(Temporary credentials)"]

  %% Policies
  B3 --> PL1[JSON permission documents]
  B3 --> PL2[Attached to<br>Users, Groups, Roles]
  B3 --> PL3[Evaluated<br>on every<br>AWS API call]

  %% IAM characteristics
  B4 --> CH1[Global service]
  B4 --> CH2[MFA support]
  B4 --> CH3[Password policies]
  B4 --> CH4[Identity federation]

  %% Best practices
  C --> BP1[Lock down root user]
  C --> BP2[Least privilege]
  C --> BP3[Prefer roles over users]
  C --> BP4[Use federation<br>/ SSO when possible]


2.3 How IAM Role, User and Policies Interplay?

Key Questions Answered in this Section:

  • What Are IAM Identities and Why Do They Exist?
  • How Do Roles, Trust Policies, and Permission Policies Interact?

graph LR
    AWS_Service["AWS Service<br>(Principal)"] -->|Assumes| Role
    User[IAM User] -->|Assumes| Role[IAM Role]
    TrustPolicy["Trust Policy<br>Who can<br>assume role"]
    TrustPolicy -.->|"sts:AssumeRole"|Role
    User -->|Belongs to| Group[IAM Group]
    Role -->|Attached| Policy[Permissions Policy<br>What Actions<br>on What Resources]
    Group -->|Attached| Policy
    Policy -->|Allows/Denies| Resource[AWS Resource]
    
    style AWS_Service fill:#f9f,stroke:#333    
    style User fill:#f9f,stroke:#333
    style Policy fill:#bbf,stroke:#333
    style TrustPolicy fill:#bbf,stroke:#333
    style Resource fill:#dfd,stroke:#333

An Example

  • Goal: A Lambda (AWS Service) accessing S3
  • Principal AWS Service: AWS Lambda
  • IAM Role: A Role that enables AWS Lambda to access S3
  • Trust Policy for the IAM Role mentioning which โ€œPrincipalโ€ can use the role ๐Ÿ‘‡
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
  • Permissions Poicy that dictates which resource is permitted to ask and what can they do
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*",
                "s3-object-lambda:*"
            ],
            "Resource": "*"
        }
    ]
}

2.4 Structure of an IAM Permissions Policy

Every IAM policy contains:

  • Version

  • Statement

    • Effect (Allow / Deny)
    • Action
    • Resource

Key principles emphasized:

  • "*" on Action + Resource = full access
  • Explicit deny overrides allow
  • Policies are evaluated on every API call
  • Variable substitution (e.g., ${aws:username}) enables fine-grained control

2.5 The concept of Groups and Roles

  • IAM Groups provide a scalable organizational pattern to accesses.
  • One user can belong to multiple groups

  • Different groups carry different permissions

  • AWS evaluates:

    • User-attached policies
    • Group-attached policies

This encourages:

Assign permissions to groups, not individuals.

2.5.1 User in 2 groups; One Group Allows, Other Group Says Nothing

flowchart LR

    User[IAM User]

    GroupA[IAM Group A]
    GroupB[IAM Group B]

    PolicyA[Policy A<br>Effect: Allow<br>Action: s3:GetObject<br>Resource: MyBucket]
    PolicyB[Policy B<br>No mention of S3<br>No Deny]

    S3Bucket[S3 Bucket: MyBucket]

    User -->|Member of| GroupA
    User -->|Member of| GroupB

    GroupA -->|Attached| PolicyA
    GroupB -->|Attached| PolicyB

    User -->|Requests s3:GetObject| S3Bucket

    PolicyA -->|Allow found| S3Bucket
    PolicyB -.->|No explicit Deny| S3Bucket

    S3Bucket --> Success[Access Granted]

    style PolicyA fill:#bbf,stroke:#333
    style PolicyB fill:#eee,stroke:#333
    style Success fill:#dfd,stroke:#333

  • User is in two groups
  • One group allows s3:GetObject
  • The other group does not deny anything
  • IAM finds at least one Allow
  • No explicit deny exists
  • โœ… Access is granted
  • IAM is additive by default.

2.5.2 User in 2 groups; One Group Allows, Other Group does not Allow

flowchart LR

    User[IAM User]

    GroupA[IAM Group A]
    GroupB[IAM Group B]

    PolicyA[Policy A<br>Effect: Allow<br>Action: s3:GetObject<br>Resource: MyBucket]

    PolicyB[Policy B<br>Effect: Deny<br>Action: s3:GetObject<br>Resource: MyBucket]

    S3Bucket[S3 Bucket: MyBucket]

    User -->|Member of| GroupA
    User -->|Member of| GroupB

    GroupA -->|Attached| PolicyA
    GroupB -->|Attached| PolicyB

    User -->|Requests s3:GetObject| S3Bucket

    PolicyA -->|Allow found| S3Bucket
    PolicyB -->|Explicit Deny found| S3Bucket -->DenyResult[Access Denied]

    style PolicyA fill:#bbf,stroke:#333
    style PolicyB fill:#fbb,stroke:#333
    style DenyResult fill:#fdd,stroke:#333

  • IAM evaluates all policies
  • It finds:
    • โœ… One Allow
    • โŒ One Explicit Deny
  • Because an explicit deny existsโ€ฆ
    • โŒ Final result: Access Denied

2.6 IAM Roles >> IAM Users

Security best practices emphasize:

  • Avoid long-lived access keys
  • Prefer roles over users
  • Use temporary credentials
  • Reduce blast radius

Roles are positioned as the safer default, especially for:

  • Services
  • Cross-account access
  • Federated identities

2.7 How Should Employees Access AWS Accounts? (hint: via IdP)

---
title: How to access AWS Account via IdP
---

flowchart LR

%% ================= USER =================
User[Corporate User]

%% ================= PATH A =================
subgraph PathA["Path A: IAM Identity Center based Access"]
    
    IIC["AWS IAM Identity Center<br>(AWS IdP)"]

    subgraph Org["AWS Organization"]
        subgraph AccA["Member Account A"]
            RoleA[IAM Role - Account A]
        end
        subgraph AccB["Member Account B"]
            RoleB[IAM Role - Account B]
        end
        STS1[AWS STS]
    end

    User --> IIC
    IIC -->|Permission Set Mapping| RoleA
    IIC -->|Permission Set Mapping| RoleB
    RoleA --> STS1
    RoleB --> STS1
end


%% ================= PATH B =================
subgraph PathB["Path B: Federation Access"]
    
    AAD["Azure AD / Okta / External IdP"]

    subgraph Accounts["AWS Accounts"]
        RoleA2[IAM Role - Account A]
        RoleB2[IAM Role - Account B]
        STS2[AWS STS]
    end

    User --> AAD
    AAD -->|"SAML Assertion*"| RoleA2
    AAD -->|"SAML Assertion*"| RoleB2
    RoleA2 --> STS2
    RoleB2 --> STS2
end


%% ================= CREDENTIALS =================
STS1 --> TempCreds1["Temporary Credentials<br>(access_key, secret_key, token)"]
STS2 --> TempCreds2["Temporary Credentials<br>(access_key, secret_key, token)"]

TempCreds1 --> Console1[AWS Console / CLI / SDK]
TempCreds2 --> Console2[AWS Console / CLI / SDK]

Legend1[["*SAML assertion:
Signed authentication statement from an IdP"]]
Legend2[["*Permission Set Mapping:
JSON template defining account permissions"]]

%% ================= STYLING =================
classDef container fill:#f4f6f9,stroke:#2c3e50,stroke-width:2px,color:#000;
classDef awsbox fill:#e8f4fd,stroke:#1f4e79,stroke-width:1px;
classDef idpbox fill:#fdf2e9,stroke:#a04000,stroke-width:1px;

class PathA,PathB,Org,AccA,AccB,Accounts container;
class IIC,RoleA,RoleB,RoleA2,RoleB2,STS1,STS2 awsbox;
class AAD idpbox;


2.8 How Should Customers Access Applications on AWS?

---
title: How to enable access to Application deployed in AWS Account
---

flowchart LR
    AppUser[Application User]
    App["Web / Mobile App"]

    UserPool["Amazon Cognito<br>User Pool<br>(AuthN)"]
    IdentityPool["Amazon Cognito<br>Identity Pool<br>(AuthZ)"]

    AppRole[IAM Role for App]
    STS[AWS STS]
    S3["S3 / DynamoDB / APIs"]


    AppUser --> App

    App -->|"1. Sign-in"| UserPool
    UserPool -->|"2. JWT (ID token)"| App

    App -->|"3. Present JWT"| IdentityPool
    IdentityPool -->|"4. AssumeRoleWithWebIdentity"| STS
    STS -->|"5. Temporary AWS Credentials"| IdentityPool
    IdentityPool -->|"6 Temporary AWS Credentials"| App

    App -->|"7. Signed requests"| AppRole
    AppRole -.->|"8. Access"| S3

2.7 & 2.8 - A Joint Recap

Feature AWS IAM Identity Center AWS Cognito
Used by Employees App users
Purpose Access AWS accounts Access your application
Grants console access? Yes No
Grants CLI access? Yes No
Issues AWS creds? Yes Yes (via Identity Pool)
Scope Organization-wide Application-level