
Table of Contents
This post is a write-up of the talk I delivered at the AWS Community on eliminating long-lived AWS credentials and adopting a Zero Standing Credentials (ZSC) model.
Why Long-Lived Credentials Are a Problem
If you have been operating in AWS for any length of time, you have probably seen the same pattern repeat itself. A developer creates an IAM user, generates an access key, drops it into a ~/.aws/credentials file, and moves on. Months later that key is still there. It has likely been copied into a CI runner, baked into a Docker image, pasted into a Slack thread, or accidentally committed to a public GitHub repository. The credential outlives the use case, the project, and sometimes even the employee.
Almost every major cloud breach in recent years can be traced back to a credential that should not have existed at the moment it was abused. Standing credentials are the cloud equivalent of leaving the office keys taped under the doormat: convenient until someone you did not invite walks in.
What Is Zero Standing Credentials (ZSC)?
Zero Standing Credentials is a security model where no human or workload holds permanent, long-lived credentials. Instead, identities request access at the moment they need it, receive short-lived tokens (typically valid for minutes to a few hours), and those tokens automatically expire. There is nothing left behind to steal.
The three principles I keep coming back to are:
- No persistent secrets. Access keys, passwords, and tokens are never stored on disk for routine use.
- Just-in-time access. Permissions are granted when a task begins and revoked when it ends.
- Strong identity over secrets. Trust is anchored in verifiable identity (a person via SSO, a workload via OIDC or IAM roles), not in possession of a string.
The Building Blocks in AWS
AWS already gives you everything you need to implement ZSC. The challenge is mostly organizational, not technical.
1. IAM Identity Center for Humans
IAM Identity Center (formerly AWS SSO) is the front door for every engineer. You federate it with your identity provider (Okta, Entra ID, Google Workspace, or its built-in directory) and map groups to permission sets. When an engineer signs in, they assume a role for a bounded session and receive temporary STS credentials. When the session expires, the credentials are gone.
The CLI experience is clean too. A single aws sso login opens the browser, authenticates the user, and refreshes short-lived credentials in the background. There is no static access key anywhere on the laptop.
2. IAM Roles and OIDC for Workloads
For workloads, the equivalent pattern is IAM roles assumed via trusted identity providers. A few patterns I rely on:
- EC2, ECS, EKS, and Lambda get instance, task, or execution roles. The SDK handles credential rotation automatically.
- GitHub Actions, GitLab, and other CI/CD systems authenticate via OIDC and assume a role with a deployment-scoped session. No access key ever leaves the pipeline.
- Kubernetes workloads use IAM Roles for Service Accounts (IRSA) or EKS Pod Identity so each pod gets its own scoped credentials.
3. Just-In-Time Elevation
For sensitive actions (production write access, IAM changes, breaking glass) I avoid giving anyone standing admin access. Engineers request elevation through a workflow: an approval in Slack, a ticket in Jira, or a self-service portal. On approval, a short-lived permission set or a temporary group membership is granted. After the window closes, it is automatically removed.
You can build this with native services (IAM Identity Center permission sets plus EventBridge and Lambda), with AWS Verified Access, or with a third-party tool. The mechanism matters less than the principle: no one is admin by default.
How I Rolled This Out
The technology is the easy part. Migrating an organization is where most teams get stuck. The approach that has worked for me:
- Inventory every existing access key. Use IAM credential reports, Access Analyzer, and CloudTrail to find who is using what. You cannot remove what you cannot see.
- Onboard humans to IAM Identity Center first. This is the highest-value, lowest-risk migration. Once developers see how smooth
aws sso loginis, they stop defending their old keys. - Migrate CI/CD to OIDC. Replace stored access keys in GitHub Actions or GitLab with OIDC trust relationships. This usually closes the biggest blast radius in any company.
- Replace service accounts with workload identity. Anywhere a workload is using a long-lived key, move it to an IAM role accessed through the EC2, ECS, EKS, or Lambda metadata service, or IRSA.
- Enforce with policy. Use SCPs to deny
iam:CreateAccessKeyoutside of break-glass accounts, and set up automation to disable keys older than a chosen threshold. - Measure. Track the number of active access keys per account over time. The graph should trend toward zero. That is your ZSC scorecard.
Common Pitfalls
A few things I have seen trip teams up:
- Forgetting third-party integrations. SaaS tools that integrate with AWS often default to asking for an access key. Almost all of them now support cross-account role assumption with an external ID. Use that instead.
- Overly broad permission sets. ZSC removes standing credentials, but it does not magically enforce least privilege. Combine it with scoped policies and Access Analyzer findings.
- Break-glass without a plan. You still need an emergency path when SSO is down. Document it, store it offline, and audit its use ruthlessly.
- Ignoring session duration. A 12-hour session is still 12 hours of attacker time if a laptop is compromised. Tune session duration to match the sensitivity of the role.
The Payoff
After running this model across multiple accounts and teams, the wins are concrete. Leaked-key incidents drop to near zero because there are no keys to leak. Audit conversations get shorter because every access event ties back to a real human identity or a verifiable workload. Onboarding and offboarding become a single change in the identity provider rather than a frantic key-rotation exercise.
Zero Standing Credentials is not a product you buy. It is a posture you adopt, one workload and one team at a time. AWS gives you the primitives. The work is deciding that long-lived secrets are no longer acceptable and then methodically eliminating them.
Resources
- AWS IAM Identity Center documentation
- Configuring OpenID Connect in GitHub Actions for AWS
- IAM Roles for Service Accounts (IRSA) and EKS Pod Identity
- AWS Service Control Policies for guardrails
Thanks to everyone who attended the AWS Community session and pushed back with great questions. If you are starting your own ZSC journey, I would love to hear what works and what does not for your team.