AWS Part 2: IAM Basics — Users, Roles & Least Privilege
Originally published at unifiedpathmedia.com. The short version: IAM (Identity and Access Management) decides who, or what, can do what in your AWS (Amazon Web Services) account. Get its building blocks straight early
Originally published at unifiedpathmedia.com.
The short version: IAM (Identity and Access Management) decides who, or what, can do what in your AWS (Amazon Web Services) account. Get its building blocks straight early and you dodge both classic failure modes. One is permissions that are too loose (a security hole). The other is permissions so tight that everyone gives up and grants admin to everything (the same security hole, wearing a disguise). The essentials: users vs. groups vs. roles, why roles beat hardcoded keys, and least privilege in practice.
← Part of the AWS Foundations series
Published September 2, 2026.
Last verified November 5, 2026 against the AWS IAM User Guide (identities, policies and the policy simulator).
Who this is for: anyone who has secured the root user and now needs to decide who can do what. You’ll need first: a locked-down account from Part 1.
IAM is the bouncer for your AWS account: it checks who’s allowed to do what, everywhere, all the time. Getting comfortable with its core pieces early heads off the two ways people usually get this wrong. Permissions end up too loose, or so annoyingly tight that someone eventually snaps and grants AdministratorAccess to everything, which recreates the original risk.
Users, groups, and roles
Three building blocks, and the differences matter:
- An IAM user represents a person (occasionally an application) with long-term credentials: a login, and maybe access keys.
- A group is a bundle of users who share the same permissions. You manage the group, not thirty individual users. Your future self, once there’s a team, will thank you.
- A role is the interesting one: an identity that gets temporarily assumed by a user, an AWS service or an app, with no long-term credentials bolted on. Roles are how EC2 (Elastic Compute Cloud) instances, Lambda functions and other services get permissions without anyone hardcoding a key somewhere it can leak.
IAM users, groups and roles: how permissions flow.
Why roles beat hardcoded access keys
Here’s a rite of passage nobody should go through: creating an access key for an IAM user and pasting it straight into your app’s code or a config file, so your EC2 instance can call other AWS services. It works, right up until that key gets committed to a public repo. At that point it’s a standing credential anyone on the internet can use, and it doesn’t expire on its own.
The better pattern is almost boringly simple: attach an IAM role directly to the EC2 instance. AWS issues temporary credentials and rotates them automatically, and there’s no static key to leak in the first place. Less code, less risk, fewer 2 a.m. surprises.
Least privilege, in practice
Least privilege means granting only the permissions the task needs, not a pile of extras “to be safe” or “so I stop hitting permission errors.” In practice, it’s the difference between two choices. One is slapping AdministratorAccess on a role because it’s the fast path to something working. The other is attaching a policy scoped to exactly what’s required: say, read and write to one specific S3 (Simple Storage Service) bucket instead of every bucket in the account.
Starting narrow and widening as needed is a far better habit than starting broad and intending to tighten it later, because “later” has a way of never arriving.
A quick look at a policy
IAM policies are JSON documents with three parts that matter: an Effect (Allow or Deny), an Action (the specific API calls, like s3:GetObject; an API, or application programming interface, is how programs ask AWS to do things) and a Resource (which specific thing the action applies to). A policy that lets you read objects from one named bucket looks very different from one granting s3:* on Resource: "*", and it’s much safer. The second is the JSON equivalent of handing out a master key with a warm smile.
The scoped version, next to the one to avoid:
scoped-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::unified-path-example-bucket/*"
}
]
}
avoid-this.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
Start scoped. It’s easier to add a permission when you hit a wall than to notice, months later, that a role could delete your entire account and nobody meant it to.
Reading a policy: the four parts
- Effect: Allow or Deny.
- Action: what’s being done, like reading an object.
- Resource: what it’s being done to, like one specific bucket.
- Condition (optional): extra rules, like “only from this network” or “only with MFA (multi-factor authentication).”
Once you can find those four, any policy becomes a sentence you can read out loud.
Test before you trust
AWS provides a policy simulator that lets you check what a user or role can and can’t do without doing it for real. Use it when you’ve written a policy and want to be sure it’s as narrow as you think.
Common mistakes
- Allowing all actions on all resources because it “just works.” It also just works for anyone who gets hold of it.
- Long-lived access keys pasted into scripts. Prefer roles and short-lived credentials.
- Sharing one login between people. You lose the trail of who did what.
- Never reviewing access. People change jobs. Their permissions should change with them.
Next: AWS Part 3: Core Services Overview — What You’ll Actually Use
← Back to the AWS Foundations series
Thanks for reading. I write a free, plain-English cloud lesson every week: subscribe to the newsletter. The full AWS Foundations series and free cloud tools live at unifiedpathmedia.com.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.