I Leaked My AWS Keys on GitHub. Here's What I Learned.
Early in my cloud journey, I made the mistake everyone warns you about: I hardcoded my AWS credentials into a Terraform script and pushed it to a public GitHub repo.
I caught it in under 30 minutes. A quick code review, an SNS alert, and a panicked credential rotation later, I got lucky. No unauthorized usage. No surprise bill. But that close call taught me something I should have understood from day one: why AWS has so many different ways to manage identity and access.
IAM Users. IAM Groups. IAM Roles. Policies. Instance profiles. When I first opened the AWS IAM console, it felt like overkill. Coming from Power BI, I understood permissions as a simple hierarchy: Admin, Member, Contributor, Viewer. Four roles. Done.
AWS has four pages of IAM documentation.
But here's the thing: once you understand the logic behind IAM, it clicks. And if you're coming from a data analytics background like me, you already have the mental model. You just need the translation.
Who This Is For
This post is for data analysts, BI developers, and anyone making the jump to cloud engineering who keeps hearing "just use an IAM Role" without understanding why.
If you've ever:
- Confused IAM Users with IAM Roles
- Hardcoded credentials because you didn't know another way
- Nodded along in an interview when someone asked about least privilege
- Wondered why AWS has 47 different ways to grant access
This is for you. I'll break down the core IAM concepts using analogies from Power BI, show you when to use each, and share the misconfigurations I've made so you don't have to.
The Mental Model That Made IAM Click
In Power BI, workspace permissions follow a clear hierarchy:
| Power BI Role | What They Can Do |
|---|---|
| Viewer | View reports and dashboards |
| Contributor | Create and edit content, can't manage access |
| Member | All of the above, plus share content |
| Admin | Full control, including managing permissions |
Simple. Four roles, increasing levels of access.
AWS IAM follows the same principle, but with more flexibility. Instead of fixed roles, you build permissions by combining identities (who) with policies (what they can do).
Here's the translation:
| Power BI Concept | AWS IAM Equivalent |
|---|---|
| Workspace | AWS Account |
| User in a workspace | IAM User |
| Workspace role (Admin, Member, etc.) | IAM Policy attached to user |
| Group of users with same role | IAM User Group |
| Shared dataset accessed by another workspace | IAM Role (cross-account access) |
| Service account / app identity | IAM Role (assumed by services) |
The key difference: Power BI gives you four preset roles. AWS gives you building blocks to create exactly the permissions you need. More complex, but more powerful.
IAM Users: The Individual Identity
An IAM User is a unique identity within your AWS account. One person, one user.
When you create an IAM User, that identity can:
- Log into the AWS Console (with a password)
- Make API calls (with access keys)
- Access specific AWS resources (based on attached policies)
Key constraint: An IAM User belongs to one and only one AWS account. If you work across multiple accounts, you'll need a different approach (more on Roles later).
When to Use IAM Users
Use IAM Users when:
- A human needs console access to a single AWS account
- You need to track individual activity in CloudTrail
- Your organization requires named accounts for compliance
Avoid IAM Users when:
- An application needs AWS access (use Roles instead)
- You're managing access across multiple accounts
- You'd need to create dozens of users with identical permissions (use Groups)
The Power BI Parallel
Think of an IAM User like a named user in your Power BI tenant. They have their own login, their own activity history, and permissions assigned specifically to them. When they leave, you deactivate their account.
The Catch: Access Keys
IAM Users can have access keys for programmatic access. These are long-lived credentials. They don't expire unless you rotate them manually. This is where security problems start.
If you're using access keys, ask yourself: could this workload use an IAM Role instead? Nine times out of ten, yes.
IAM User Groups: Permissions at Scale
Managing permissions for one user is easy. Managing permissions for fifty users doing the same job is a nightmare. That's where Groups come in.
An IAM User Group is a collection of IAM Users. Attach policies to the group, and every user inherits those permissions. Add a new analyst? Drop them in the "DataAnalysts" group. Done.
How Groups Work
Groups don't have credentials. They're not identities. You can't log in as a group. They're purely an organization tool for managing permissions efficiently.
A user can belong to multiple groups. If Sarah is both a data analyst and a project lead, she can be in both the "DataAnalysts" and "ProjectLeads" groups. Her effective permissions are the combination of both.
When to Use IAM User Groups
Use Groups when:
- Multiple users need identical permissions
- You want to manage access by job function
- You need to quickly onboard or offboard team members
Avoid Groups when:
- You only have one or two users
- Permissions are highly individualized with no overlap
The Power BI Parallel
This maps directly to Power BI workspace management. Instead of assigning "Contributor" to each analyst individually, you create a security group in Azure AD, assign that group the role, and manage membership in the group. Someone joins? Add them. Someone leaves? Remove them. Permissions stay clean.
IAM User Groups work identically. The group holds the permissions. The users inherit them.
IAM Roles: The Game Changer
If IAM Users are the first thing people learn, IAM Roles are what actually matters in production.
A Role is an identity with permissions, just like a User. But instead of belonging to one person, a Role is assumed by whoever or whatever needs it. A human can assume a Role. An EC2 instance can assume a Role. A Lambda function can assume a Role. Another AWS account can assume a Role.
The Key Difference: Temporary Credentials
When you assume a Role, AWS gives you temporary security credentials. They expire automatically. No long-lived access keys in a config file. No credentials to leak. No secrets to rotate manually.
This is why Roles are the standard for anything running in AWS. Your application doesn't store credentials. It assumes a Role, gets temporary credentials, does its work, and the credentials expire.
When to Use IAM Roles
Use Roles when:
- An AWS service needs permissions (EC2, Lambda, ECS, EKS)
- You're granting cross-account access
- A human needs temporary elevated permissions
- You want to eliminate long-lived credentials entirely
Avoid Roles when:
- You need a persistent human identity for audit purposes (use a User, then have them assume Roles as needed)
That's about it. Roles are almost always the right answer for workloads.
The Power BI Parallel
This one's trickier. Power BI doesn't have a direct equivalent because it's built around persistent user identities.
The closest analogy: imagine if Power BI let you create a "Report Refresh" identity that your datasets could temporarily become when pulling data from a source system. The dataset doesn't have its own credentials. It borrows the identity, does the refresh, and the access expires.
That's what an IAM Role does for AWS services.
Instance Profiles: Roles for EC2
When an EC2 instance assumes a Role, it uses an instance profile. Think of it as the container that attaches a Role to an instance. When you launch EC2 and select an IAM Role in the console, AWS creates an instance profile behind the scenes.
You'll see "instance profile" in documentation and error messages. Just know: it's the mechanism that lets EC2 instances assume Roles.
Service-Linked Roles
Some AWS services create and manage their own Roles automatically. These are service-linked roles. You don't create them. AWS does when you enable certain features.
Example: When you set up AWS Config, AWS creates a service-linked role that gives Config permission to read your resources. You don't manage this Role. AWS does.
If you see a Role you didn't create with a name like "AWSServiceRoleForConfig," that's a service-linked role. Leave it alone.
When to Use Each: The Decision Framework
| Scenario | Use This | Why |
|---|---|---|
| Human needs console access | IAM User | Trackable identity, password login |
| Multiple humans need identical permissions | IAM User Group | Manage once, inherit everywhere |
| Application running on EC2/Lambda/ECS | IAM Role | Temporary credentials, no keys to leak |
| Cross-account access | IAM Role | Trust policies define who can assume |
| Temporary elevated permissions | IAM Role | Time-limited, auditable |
| You're about to hardcode credentials | IAM Role | Stop. There's almost always a better way. |
When in doubt, ask: "Can this use a Role instead?" Usually, yes.
Common Misconfigurations (Including Mine)
Hardcoded credentials in code.
I did this. Early in my cloud journey, I hardcoded AWS credentials into a Terraform script and pushed it to GitHub. I caught it in under 30 minutes through a code review and an SNS alert. I rotated the keys immediately. No damage, but I got lucky.
The fix: I moved secrets to AWS Secrets Manager and switched to IAM Roles for any service that needed AWS access. No more long-lived keys in code.
Other mistakes I see often:
Overly permissive policies. Granting
"Action": "*"because it's faster than figuring out the exact permissions. This is how small misconfigurations become security incidents.Not using Groups. Managing permissions user-by-user until onboarding and offboarding becomes a nightmare.
Long-lived access keys without rotation. If you must use access keys, rotate them. Better yet, use Roles and eliminate them entirely.
Key Takeaways
IAM Users are for humans. IAM Roles are for everything else. If an application, service, or cross-account workflow needs AWS access, use a Role. Temporary credentials beat long-lived keys every time.
Groups save your sanity. Don't manage permissions individually. Group users by function, attach policies to the group, and let inheritance do the work.
If you're about to hardcode credentials, stop. There's almost always a Role-based alternative. Secrets Manager exists for the rare cases where it doesn't.
Interview tip: When asked "What's the difference between an IAM User and an IAM Role?" the answer is: Users are persistent identities with long-lived credentials. Roles are assumed identities with temporary credentials. Roles are preferred for workloads because there are no keys to leak.
What's Next
This post is part of my "Data Analyst to Cloud Engineer" series. Next up: the $200 EKS mistake that taught me how Fargate pricing actually works.
If IAM still feels fuzzy, drop a comment. I'll answer what I can and turn common questions into future posts.

Top comments (0)