Every action in AWS, from the console to Lambda, is an API call checked by IAM, so it underpins everything else.
IAM (Identity and Access Management) is global and free. Every API request is made by a principal and is denied unless a policy allows it.
The identity types:
- IAM users: a long-term identity with a console password and/or access keys. Today they are for exceptions, such as a third-party tool that cannot assume roles.
- IAM groups: collections of users to attach policies to. A group is not a principal; you can't sign in as one or name it in a resource policy.
- IAM roles: identities with no long-term credentials. A trusted principal or service assumes the role and gets temporary credentials. EC2 instances, Lambda functions, ECS tasks, CI pipelines and humans from another account all use roles.
- Federated users: people signing in through IAM Identity Center or an external identity provider, ending up in a role.
The modern pattern: humans use IAM Identity Center (one login, permission sets mapped to roles in each account); workloads use roles; IAM users with access keys are rare and audited.
Resources are named by ARNs, arn:partition:service:region:account-id:resource, for example arn:aws:iam::111122223333:role/orders-fn (IAM has no Region) or arn:aws:sqs:eu-west-1:111122223333:orders.
The guiding rule is least privilege: grant only the actions and resources a principal needs, start narrow and widen with evidence. AWS managed policies like ReadOnlyAccess are convenient starting points but are usually broader than necessary.
Example
# A group for auditors, using an AWS managed policy
aws iam create-group --group-name auditors
aws iam attach-group-policy --group-name auditors \
--policy-arn arn:aws:iam::aws:policy/SecurityAudit
aws iam create-user --user-name legacy-scanner
aws iam add-user-to-group --group-name auditors --user-name legacy-scanner
aws iam list-attached-group-policies --group-name auditors \
--query 'AttachedPolicies[].PolicyName' --output text
# SecurityAudit
aws iam list-roles --query 'Roles[?starts_with(RoleName, `orders`)].Arn'Remember
- Everything is denied unless a policy allows it
- Roles give temporary credentials and are the default for workloads and people
- Groups organise users but are not principals
- ARNs identify resources in policies
Watch out for
- Creating an IAM user with access keys for an application running on AWS, instead of a role.