AWS: Identity and Access Management (IAM)

When building an application on Amazon Web Services, access control exists at multiple layers. Not every interaction is handled the same way, and understanding where credentials are required—and how they should be managed—is critical for building a secure and scalable architecture.

Where access control is required

  • Application-level access
  • End users must authenticate to the employee directory application.
  • Typically handled using usernames, passwords, or other application-specific authentication mechanisms.
  • This is not managed by IAM and lives entirely within the application logic.
  • AWS account access
  • Engineers and operators need access to the AWS account to create and manage infrastructure.
  • Each person must have their own identity and permissions.
  • The root user exists but should never be used for daily operations.
  • Service-to-service access
  • Application code running on Amazon EC2 needs to call other AWS services such as Amazon S3.
  • All AWS API calls must be signed and authenticated, even within the same account.
  • Credentials are required, but they must be handled securely and automatically.

Role of AWS Identity and Access Management (IAM)

IAM is responsible for managing who can access AWS and what they are allowed to do once authenticated.

It provides a centralized way to define who can access AWS, how they authenticate, and what actions they are authorized to perform once authenticated.

Authentication and Authorization in IAM

IAM separates access control into two clearly defined stages.

Authentication: determines _who or what is making the request_.

Authorization: determines _whether that identity is allowed to perform the requested action_.

Every AWS API request flows through this decision pipeline:

md
AWS API Request
       |
       v
+-----------------------+
| Authentication        |
| (User / Role / Fed)   |
+-----------------------+
       |
       v
+-----------------------+
| Authorization         |
| (IAM Policies)        |
+-----------------------+
       |
       v
   ALLOW or DENY

  • IAM Users
  • Represent individual people.
  • Provide authentication to the AWS account.
  • Each user has unique credentials.
  • IAM Groups
  • Collections of IAM users.
  • Policies are attached to groups rather than individual users.
  • Users inherit permissions from the groups they belong to.
  • Simplifies permission management as teams and roles change.
  • IAM Policies
  • JSON-based documents that define permissions.
  • Specify:
  • Effect: Allow or Deny
  • Action: AWS API calls (e.g., ec2:RunInstances)
  • Resource: Which resources the action applies to
  • Conditions (optional): Extra constraints on access
  • IAM Authorization
  • Determines what actions an authenticated identity can perform.
  • Permissions are granted or denied using IAM policies.

IAM Users: Permanent Identities

An IAM user represents a person or service that interacts with AWS directly. Each user is defined inside an AWS account, and all activity performed by that user is billed to the account.

An IAM user consists of:

  • A unique name
  • One or more credentials
  • Console access (username and password)
  • Programmatic access (access keys for AWS CLI and API)

IAM user credentials are long-lived by default, meaning they remain valid until explicitly rotated or revoked. Because of this, IAM users are best suited for human users, not applications.

md
AWS Account
   |
   ├─ IAM User: Developer_A (Console + CLI)
   ├─ IAM User: DevOps_B    (CLI only)
   └─ IAM User: Auditor_C  (Read-only)

As the number of users grows, managing permissions directly on users becomes error-prone and difficult to audit.


IAM Groups: Scalable Permission Management

An IAM group is a collection of users. Instead of attaching permissions to individual users, permissions are attached to the group, and all users in the group inherit them automatically.

md
Developers Group
   |
   ├─ Alice
   ├─ Bob
   └─ Carol
   |
   └─ Policies:
        - EC2 Read
        - S3 Read/Write

Groups make IAM scalable and maintainable:

  • New users inherit permissions instantly
  • Role changes are handled by moving users between groups
  • Permissions remain aligned with job functions

Key characteristics:

  • Groups can contain many users
  • Users can belong to multiple groups
  • Groups cannot contain other groups

IAM Policies: The Authorization Engine

IAM policies are JSON documents that explicitly define what actions are allowed or denied on which resources. Every authorization decision in AWS is based on policy evaluation.

A policy is made up of one or more statements, and each statement must include the following required elements:

When creating a policy, it is required to have each of the following elements inside a policy statement.

ElementDescriptionRequiredExample
EffectSpecifies whether the statement results in an allow or an explicit deny"Effect": "Deny"
ActionDescribes the specific actions that will be allowed or denied"Action": "iam:CreateUser"
ResourceSpecifies the object or objects that the statement covers"Resource": "arn:aws:iam::account-ID-without-hyphens:user/Bob"

Policy Example: Full Administrative Access

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

This policy:

  • Uses wildcards (*) to match all actions and all resources
  • Grants unrestricted administrative privileges
  • Should be used sparingly and only for trusted administrators

The "Version": "2012-10-17" field specifies the policy language version and is required to enable all modern IAM features.


Policy Example: Granular User Permissions

IAM policies can be highly specific. The following example allows a user to change only their own password and read their own user details:

json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "iam:ChangePassword",
      "iam:GetUser"
    ],
    "Resource": "arn:aws:iam::123456789012:user/${aws:username}"
  }]
}

Here:

  • The Action list restricts what the user can do
  • The Resource ARN limits access to the user’s own identity
  • The ${aws:username} variable ensures self-service only

This is a practical example of least privilege in action.


How AWS Evaluates Policies

When a request is made, AWS evaluates:

  • Policies attached to the user
  • Policies attached to the user’s groups
  • Policies attached to an assumed role

The final decision follows strict rules:

  • Explicit Deny always wins
  • If no Allow exists, access is denied by default

md
Request
  |
  v
Evaluate all policies
  |
  ├─ Explicit Deny? → DENY
  ├─ Explicit Allow? → ALLOW
  └─ Otherwise → DENY


IAM Roles: Secure Access for AWS Services

Applications running on AWS should never use permanent credentials. IAM addresses this using roles, which provide temporary credentials to trusted entities.

An IAM role:

  • Has no long-term credentials
  • Is assumed by AWS services like EC2 or Lambda
  • Uses short-lived, automatically rotated credentials

md
EC2 Instance
   |
   | assumes
   v
IAM Role
   |
   | permissions
   v
S3 Bucket

Roles eliminate hardcoded secrets, reduce blast radius, and are the correct choice for service-to-service authentication.

Service-to-service authentication with IAM Roles

IAM Roles

  • Provide temporary credentials to AWS services like EC2.
  • Allow services to make signed API calls securely.
  • Ideal for EC2-to-S3 access (read/write employee photos).
  • Automatically rotated and scoped to specific permissions.
  • Why roles instead of IAM users
  • No hardcoded secrets in code.
  • Reduced blast radius if compromised.
  • Designed specifically for machine identities.

Best practices for AWS account access

  • Enable MFA on the root user immediately.
  • Create an IAM user with administrative permissions.
  • Stop using the root user for daily operations.
  • Assign permissions to groups, not individual users.
  • Grant only the permissions required to perform a task (least privilege).

What IAM does NOT manage

  • User authentication inside the application.
  • Application-level passwords or login flows.
  • Business logic related to end-user access.

Key takeaways

md
                         Access to AWS Account
                               |
                               v
+------------------------------------------------------------------+
|                         AWS ACCOUNT                               |
|                                                                  |
|  +------------------------------------------------------------+  |
|  |                        Amazon VPC                          |  |
|  |                                                            |  |
|  |  Availability Zone 1              Availability Zone 2      |  |
|  |                                                            |  |
|  |  +----------------------+      +----------------------+    |  |
|  |  |   EC2 Instance       |      |   EC2 Instance       |    |  |
|  |  |  (App running)       |      |  (App running)       |    |  |
|  |  |                      |      |                      |    |  |
|  |  |  App-level auth      |      |  App-level auth      |    |  |
|  |  | (username/password)  |      | (username/password)  |    |  |
|  |  +----------+-----------+      +-----------+----------+    |  |
|  |             |                              |               |  |
|  |             |        Elastic Load Balancer |               |  |
|  |             +-------------<---->-----------+               |  |
|  |                           |                                |  |
|  |                     Auto Scaling Group                     |  |
|  |                                                            |  |
|  |  +----------------------+      +----------------------+    |  |
|  |  |   RDS DB (Primary)   |<---->|   RDS DB (Standby)   |    |  |
|  |  +----------------------+      +----------------------+    |  |
|  |                                                            |  |
|  +------------------------------------------------------------+  |
|                                                                  |
|                       AWS API CALLS                              |
|                 (must be signed & authenticated)                 |
|                                                                  |
|        EC2 Instance  ---- IAM Role ---->  Amazon S3              |
|             |                                   |                |
|             |-------- Read / Write -------------|                |
|                                                                  |
|                                                                  |
|  IAM (Identity & Access Management)                              |
|  +------------------------------------------------------------+  |
|  |  IAM Users  -> Login to AWS Account                         | |
|  |  IAM Groups -> Group permissions                            | |
|  |  IAM Policies -> Allow/Deny AWS API actions                 | |
|  |  IAM Roles -> Temporary credentials for services (EC2)      | |
|  +------------------------------------------------------------+  |
|                                                                  |
|  Other AWS Services (API access controlled by IAM):              |
|    - Amazon CloudWatch                                           |
|    - Amazon DynamoDB                                             |
|                                                                  |
+------------------------------------------------------------------+


ACCESS CONTROL SUMMARY
----------------------

1) Application-level access
   - Users authenticate to the app itself
   - Managed inside application code (NOT IAM)

2) AWS account access
   - Humans authenticate via IAM users
   - Authorization via IAM policies & groups

3) Service-to-service access
   - EC2 → S3 uses IAM Roles
   - No hardcoded credentials
   - Temporary, scoped permissions


KEY SECURITY PRINCIPLES
----------------------

- Root user: locked down, MFA enabled, rarely used
- IAM users: unique per person
- IAM groups: permissions assigned to roles, not individuals
- IAM roles: used by AWS services (EC2, Lambda, etc.)
- Every AWS action = signed API call

  • Access control exists at multiple layers in AWS architectures.
  • IAM manages authentication and authorization for AWS resources, not application users.
  • Every AWS API call must be authenticated and authorized.
  • Root users are powerful but dangerous—lock them down.
  • IAM roles are the correct way to grant permissions to AWS services.
  • Proper IAM design is foundational to building secure cloud applications.