The most common AWS compromise story isn't clever. It's a static access key, pasted into CI secrets years ago, powerful enough to deploy, forgotten by everyone except the log line that eventually leaks it. The key doesn't expire, doesn't know what repo it's being used from, and doesn't care whether the workflow calling it is the one it was made for.
On one of the platforms I've worked on, repos deployed with exactly such keys. The fix wasn't rotation policy or a secrets manager. It was making the credential class extinct.
How the federation works
GitHub Actions can mint a short-lived OIDC token for every workflow run, carrying verifiable claims: which repository, which branch, which environment. AWS IAM can be told to trust GitHub's token issuer, but only for tokens whose claims match a specific pattern. The workflow exchanges its token for temporary credentials via STS. Nothing is stored anywhere. There is nothing to leak, and a stolen token dies in minutes.
The security is entirely in how narrowly you write the trust policies. Blanket-trusting an org is barely better than a static key. Here, every repo × environment pair gets its own role. Non-prod roles trust a specific branch. Production roles trust only a protected GitHub environment, which means deploys inherit the branch protections and review requirements GitHub already enforces.
every role's inline policy is scoped to the stacks that repo deploys, and nothing org-wide.
Production gets change-sets, not deploys
The sharpest edge is that production roles don't hold apply rights at all in the general case. They are restricted to CloudFormation change-sets. That pairs with a CI guard that inspects every change-set before execution and fails the deploy if any stateful resource would be replaced. The role that automates production is mechanically incapable of the worst category of mistake, and explicit Deny statements shield live stacks from the preview-environment reaper for the same reason.
Rollout, including the repos I didn't own
A credential class is only extinct if it's extinct everywhere, so the rollout crossed repo boundaries. That included migrating a sister repo's release pipeline, which was still shipping artifacts with static keys. This is the part I'd emphasize to anyone doing this: the last two repos matter more than the first ten, because attackers only need one key.
Cost of the whole program: some IAM policy authoring and a few workflow edits. Standing risk retired: every stored AWS credential in CI, permanently. It is the rare security project with no trade-off to argue about.
Provenance of numbers:Iimplemented