Is a "Zero IAM Users" AWS Setup Actually Possible?
I set out to eliminate every single IAM user from my AWS accounts. The short answer: it's an achievable ideal, but the honest landing point isn't "zero" — it's "as close to zero as your dependencies allow." This post walks through why IAM users are a problem, how to replace them stage by stage, and the one case where I couldn't fully get rid of one.
Why get rid of IAM users at all
The core issue with IAM users is that they let you issue access keys — long-lived credentials. Access keys have a few uncomfortable properties:
- No built-in expiration; they stay valid forever unless someone manually rotates them
- If one leaks into a repo or a log, an attacker can keep using it until it's explicitly revoked
- Tracking who issued a key, when, and why depends entirely on manual bookkeeping, which doesn't scale
IAM roles assumed via temporary credentials (STS) behave very differently: they expire automatically within minutes to hours. The blast radius and duration of a leak shrink dramatically. "Zero IAM users" is really shorthand for "eliminate long-lived credentials wherever possible."
Stage 1: Remove IAM users from human access
The first target is how humans log into the AWS console or CLI.
- Adopt IAM Identity Center (formerly AWS SSO) as the identity provider, so human logins always resolve to temporary federated credentials
- Even at solo/small-team scale, stop using the root user for daily operations. Enforce MFA on it and reserve it strictly for break-glass emergencies
- When you do need console credentials, use
aws login(announced November 2025, AWS CLI 2.32.0+) to fetch temporary credentials through a browser-based flow. Note it's distinct fromaws sso login, which is specific to IAM Identity Center — pick the right one for your setup
This stage alone removes most of the access keys that would otherwise get issued and stored day to day.
Stage 2: Remove IAM users from CI/CD and deployment
The next pain point is external CI/CD services — GitHub Actions, Vercel, etc. — that need to touch AWS resources. The old default was to create a dedicated "deploy" IAM user and stash its access key as a secret.
OIDC Federation replaces this pattern. GitHub Actions or Vercel issues an OIDC token, AWS verifies it, and the CI/CD job assumes an IAM role temporarily. No access key ever needs to be stored.
In practice, my nico-comment-app and marp-ai-app projects both connect to AWS resources (Lambda, S3) keylessly via Vercel's OIDC Federation — just an AWS_ROLE_ARN and nothing else. Removing IAM users from the deploy pipeline is not just theoretically possible; it works in real production use.
Stage 3: Remove IAM users from cross-service and on-prem access
If you need to reach AWS resources from outside AWS — on-prem servers, another cloud — IAM Roles Anywhere is the option. It issues temporary IAM role credentials based on X.509 certificates, so no long-lived access key needs to sit on external infrastructure either.
Stage 4 (the real-world wall): you can't eliminate every exception
Everything above works well on paper. In practice, you will hit exceptions. I hit mine with wallet-agent.
That project combines Privy (a signing/custody service), Vercel, and AWS (AgentCore Runtime, DynamoDB). I initially aimed for the same OIDC-based keyless setup as my other projects, but a limitation on the Privy signer side broke that approach. I ended up with an IAM user, wallet-agent-vercel, whose access key handles the Vercel connection (AgentCore-side permissions are still handled separately via OIDC Federation).
In other words: once a third-party integration doesn't support OIDC or temporary credentials, you can't fully remove the IAM-user option — the constraint sits outside your own architecture.
Conclusion: zero is a direction, not an absolute goal
A "zero IAM users" setup is achievable in three stages:
- Human access → IAM Identity Center /
aws login - CI/CD access → OIDC Federation
- On-prem / cross-cloud access → IAM Roles Anywhere
But real third-party services sometimes don't support OIDC or temporary credentials, and in those cases a long-lived access key — an IAM user — is genuinely necessary.
The practical policy I've landed on: don't treat "zero" as an absolute requirement. Instead, make any remaining IAM users visible, scope their permissions down as tightly as possible, and review them regularly. Being upfront about where you couldn't get to zero is, arguably, the more honest security posture.
This post is based on hands-on experience running personal projects on AWS. Your organization's security requirements may call for a different approach.

Top comments (0)