Skip to Content

IAM: Users, Groups, Roles & Policies

When to use

Control who/what can call which AWS APIs with least-privilege granularity.

Analogy

IAM is a security checkpoint with badges. Users are individual badges; Roles are costumes a service wears; Policies are the rulebook.

Data-flow diagram

  Policy (JSON)
  { Effect, Action, Resource }
        |
        v
  User <---> Group <---> Role  ---> STS AssumeRole
                                       (auto-rotates)

Deep explanation

IAM is the universal authorisation plane: every AWS API call must be signed by an IAM principal whose policy explicitly allows the action. A Principal can be a User (long-lived), a Role (temporary STS-issued credentials - used by EC2, ECS, Lambda, cross-account), or a service-linked Role. Policies are JSON documents with Effect, Action, Resource. Default for new users: NO permissions. Always use Roles for applications.

Examples

Example 1

aws iam create-user --user-name alice

creates IAM user Alice with no permissions; attach policies next.

Example 2

aws iam attach-user-policy --user-name alice \
  --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess

grants AWS-managed ReadOnlyAccess; pre-curated and versioned by AWS.

Example 3

aws iam create-role --role-name myapp-role \
  --assume-role-policy-document file://trust.json

Role that EC2 / Lambda can assume via instance profile / function config.

Common mistake

Granting *:* AdministratorAccess to application roles ‘just to make it work’. Hardcoding long-lived AWS_ACCESS_KEY_ID in env vars / code.

Key takeaway

principle of least privilege; never use root after initial setup; never share long-lived keys; prefer Roles / OIDC / IRSA. Use IAM Access Analyzer to find unused permissions.

Production Failure Playbook

Failure scenario 1: wildcard-admin-policy

Failure scenario 2: long-lived-access-keys