Killing Long-Lived Credentials with Workload Identity and Dynamic Secrets
Static credentials are the breach vector that actually gets used: they work until someone revokes them, and nobody revokes them. A phased plan for replacing IAM user keys, CI secrets, and database passwords with workload identity, OIDC federation, and dynamic secrets, with the static-credential count as the program KPI.
No-Long-Lived-Credentials Migration Checklist
Copy as markdown to paste into your repo, or download a branded PDF for sharing with non-technical stakeholders.
Frequently asked questions
Why are long-lived credentials such a security risk?
Because stolen does not mean expired: a static key keeps working until a human notices and revokes it, and credential-based intrusions have averaged around 240 days to identify. A short-lived credential lifted from a compromised pod is worth an hour to an attacker; a long-lived one is worth however many months pass before someone catches it.
How do I replace AWS access keys in my GitHub Actions pipeline?
Register `token.actions.githubusercontent.com` as an IAM identity provider and have the pipeline assume a role directly via GitHub's native OIDC token, instead of storing `AWS_ACCESS_KEY_ID` in repository secrets. Pin the trust policy's `sub` to a specific repo and ref rather than a `repo:your-org/*` wildcard, and give pull-request builds a separate plan-only role.
What is the difference between IRSA and EKS Pod Identity?
Both give pods short-lived credentials without stored keys, but IRSA registers a per-cluster OIDC provider in IAM and matches a role's trust policy to the token's `sub` claim, while EKS Pod Identity (GA since late 2023) skips that registration and manages role associations through a plain EKS API call — easier once you run several clusters. The trade-offs: Pod Identity does not cover Fargate pods and needs explicit role chaining for cross-account access, so pick one mechanism per cluster and stay consistent.
Do I need HashiCorp Vault to get rid of database passwords?
Usually not. RDS IAM authentication swaps the password for a 15-minute connection token on Postgres, MySQL, and Aurora, and Secrets Manager with managed Lambda rotators handles the rest on a schedule. Vault's dynamic per-lease database users go further, but at 10-80 engineers running Vault solely for database credentials is overkill — it earns its keep when you are multi-cloud or already operate it for something else.
How do I migrate off static credentials without breaking production?
Work one credential class at a time in four moves: inventory, build the new issuance path, run both in parallel, then revoke the old credential. Deactivation is the safety net — flip an IAM key Inactive for a week and watch CloudTrail before deleting it. Sequence by last-used data: dead keys first, then CI, then workloads, then humans.
Does killing long-lived credentials help with SOC 2 compliance?
Yes. Once credentials are issued rather than stored, every AssumeRole call is a CloudTrail event binding an action to an identity, a session, and a timestamp, so your rotation control is satisfied structurally — they expire hourly and issuance is logged. That is a materially stronger position for SOC 2 CC6.1 than a spreadsheet of quarterly rotations, and it feeds evidence pipelines directly.
Get the next one.
New operating guides as we publish them — practical, infrequent, unsubscribe in one click.
The Assessment includes the IAM credential report.
Kaan Systems does platform engineering and Terraform for funded SaaS, health-tech, and fintech. Compliance evidence is the by-product of that work. The Assessment includes the IAM credential report: which keys are still long-lived, and the order to remove them. The 7-day Assessment is read-only. Book a call.