Using the root account is like the CEO mopping the floors: possible, but neither safe nor efficient. In this guide we’ll hire your first "digital employee" — create an IAM user, give them permissions, and teach a server how to do its job without a password. I’ll walk you through practical labs, real-world explanations, and little stories so the steps stick.
Note: You mentioned you already have annotated screenshots for each step — great! I added image placeholders where you can drop them in the final draft.
Hiring Your First Employee: Creating an IAM User
Imagine Joy, the CEO of a small but growing company. Joy knows she shouldn't share the root account (the master keys). Instead she hires Samuel — a real person — and gives Samuel a proper employee identity. That identity has a console password so Samuel can log in, and (optionally) programmatic keys if Samuel needs CLI or SDK access.
Why not use the root account?
The root account has full power. If it’s compromised, everything is compromised.
Root access should be reserved for account-level tasks (billing, closing the account, etc.).
Using IAM users lets you apply the principle of least privilege: give people only what they need.
Practical Lab: Creating Your Digital Identity
Before you start: Log in using the root account, or an IAM user with permission to create users.
In the AWS Console, open the IAM service and click Users.
This is where you manage human identities and machine identities.
Click Create user.
You’ll be prompted for a username and credential types.
Enter a username, e.g., Alice.
Use clear, real names where possible (Alice.Smith) for accountability.
Select AWS credential types:
AWS Management Console access — gives a console (web) password so Alice can login.
*Programmatic access *(optional) — creates an access key pair for CLI/SDK. Only enable if truly needed.
Why separate? Console access is for humans using a browser. Programmatic access is for scripts and automated tools.
Click Next: Permissions.
This is where you attach permissions via groups, policies, or inline policies.
Add the user to a group. Click Create group.
Groups are the easiest way to manage sets of permissions.
Enter group name: Admin. Search for and select AdministratorAccess.
For the lab we use AdministratorAccess so you can test workflows. In production prefer more restrictive groups.
Security note: Avoid making every user an admin. Create role-based groups (Dev, Ops, Billing) with only necessary permissions.
Click Create group, then select the Admin group.
Now **Samuel **inherits whatever permissions the Admin group has.
Click Next: Tags (skip for now), then Next: Review.
Tags can help with billing, auditing, and automation. Consider adding team or project tags later.
Review settings and click Create user.
Download the .csv file. It contains the login details and keys. Store it securely.
The .csv includes: IAM sign-in link, username, password (temporary if auto-generated), and access keys if you enabled programmatic access.
Security tip: This file is shown only once. If you lose it, delete keys and create new ones or reset the console password.
Log out of the root account.
Log back in as Samuel using the IAM user sign-in link (found on the IAM Dashboard).
Enter the temporary password from the .csv file, then set a new password.
If you checked Require password reset, Alice will be forced to set a new password at first login. This is a recommended best practice.
You are now logged in as an IAM User with safer credentials.
Quick Story Recap: Joy created Alice, downloaded the CSV, delivered it securely, and Alice logged in and set her own password. Root stays quiet and secure.
** IAM Policies**
Analogy: Think of an IAM policy as a rulebook for what an employee can or cannot do. Policies are JSON documents that say "Allow" or "Deny" specific actions on specific resources.
Example — Read-Only Access to S3 (policy JSON)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": "*"
}
]
}
Explanation:
Effect: "Allow" — this statement grants permission (as opposed to Deny).
Action — the API actions allowed. s3:ListBucket lets you list bucket contents; s3:GetObject lets you download objects.
Resource: "*" — applies to all buckets. In production you should scope this to ARNs for specific buckets.
Practical Lab: Create a Read-Only Group
In the IAM console, go to User Groups → Create group.
Name the group S3-ReadOnly.
Attach the policy AmazonS3ReadOnlyAccess.
This is an AWS-managed policy that implements a safe read-only rule set.
Add your user Samuel to this group.
Samuel is now in two groups: Admin and S3-ReadOnly.
Permissions are additive — Samuel’s effective permission set is the union of group permissions, except where an explicit Deny overrides.
Why groups & policies?
Easier to audit and scale. Add/remove people without touching policies.
Reuse policies for many users.
** IAM Roles**
Samuel needs an EC2 server to read files from S3. You could give the server an access key (yuck), or you can dress the server in a role — a temporary identity the instance can assume. Roles are the secure, AWS-native way to let services act on behalf of each other.
Practical Lab: Assigning a Role to a Service
In IAM, go to Roles → Create role.
Choose AWS service → EC2.
This sets the trust policy so EC2 instances can assume the role.
Add permissions: AmazonS3ReadOnlyAccess.
Name the role MyEC2S3ReadRole and create it.
Go to EC2 → Launch instance.
Under Advanced details, select IAM instance profile → MyEC2S3ReadRole.
This attaches the role to the instance on launch. If the instance is already running, attach the role via Instance Actions → Security → Modify IAM role.
Launch (or apply) the instance.
Once it’s running, connect using EC2 Instance Connect or SSH.
In the terminal, run:
aws s3 ls
The instance lists your S3 buckets using role permissions — no long-term keys required.
Quick tip: Make sure the instance either has the AWS CLI installed or use the platform's built-in tooling that can access the instance
profile credentials.
Best Practices & Security Checklist
Never use the root account for daily tasks. Keep it locked and enable MFA on root.
Require password reset on first login for any default password you create.
Enable MFA for all console users — especially any admin or privileged accounts.
Principle of least privilege: avoid attaching AdministratorAccess unless needed.
Use groups & roles instead of attaching policies directly to users whenever possible.
Rotate and revoke credentials: If a .csv is lost or a key is exposed, delete it and create new credentials.
Use secure channels to share .csv files (encrypted email, secure vaults). Don’t paste credentials in chat.
Enable CloudTrail to audit actions and detect suspicious behavior.
Limit programmatic keys and prefer roles for services and EC2.
Tag resources & users for billing, ownership, and audits.
Troubleshooting & FAQs
Q: I lost the .csv — can I download it again? A: No. AWS shows access keys and generated passwords only once. If lost, delete the key and create a new one, or reset the console password for that user.
Q: I want Alice to switch teams later — how do I change her permissions? A: Remove Alice from the old group and add her to the new group. Changes take effect immediately.
Q: Do policies add or override? A: Policies are additive — all Allow permissions are combined. However, an explicit Deny in any policy overrides an Allow.
Q: Should I give EC2 instances access keys? A: No — prefer IAM Roles (instance profiles). They provide temporary credentials and are far safer.
*Final Notes *—
Joy did the right thing: she kept the root account safe, created Samuel with a console password, downloaded the .csv, handed it over securely, and had Alice set her own password at first login. Later, Joy used groups and roles to make the environment auditable and maintainable.
Top comments (0)