Source: Dev.to | Dec 22, 2025 (UTC)
As the year is coming to an end, I’ve been spending some time reflecting and intentionally improving my security knowledge.
Since joining Muzz, I’ve been exposed to systems that operate at scale, multiple AWS accounts, production-critical pipelines, and infrastructure that really cannot afford loose security practices. One of the most valuable things I learned during this journey is AWS role chaining in GitHub Actions.
It’s one of those setups that looks complex at first, but once it clicks, you realise:
“Yeah… this is how CI/CD should work.”
So I thought I’d share what we did, why we did it, and why you should probably do it too.
The Problem with “Simple” AWS Credentials in CI/CD
Traditionally, CI/CD pipelines access AWS by storing credentials like:
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
as GitHub Secrets.
This works but it comes with problems:
-
Long-lived credentials sitting in GitHub
-
Hard to rotate safely
-
Over-permissioned “just in case”
-
No clear trust boundaries between environments
-
Risk increases as the organisation scales
As teams grow and environments multiply (shared, dev, staging, prod), this approach doesn’t scale securely.
The Modern Answer: GitHub OIDC + IAM Roles
Instead of static secrets, we moved to:
-
GitHub Actions OpenID Connect (OIDC) (I have already discussed that in my other blog)
-
IAM Roles with trust policies
-
Short-lived AWS credentials
-
Role chaining for environment isolation
This means:
-
No AWS secrets stored in GitHub
-
Credentials are issued only when a job runs
-
Access is tightly scoped and time-limited
GitHub Actions first assumes a base role (usually in a shared AWS account)
From there, it assumes a target role in another account (dev/prod).
Each hop has explicit trust and permissions.
Think of it like airport security:
- GitHub gets through the main gate (shared role)
- Then gets escorted to the correct terminal (dev/prod role)
- No free roaming, no shortcuts
Make sure you’re using the official AWS configure-aws-credentials GitHub Action with role chaining enabled (role-chaining: true).
If that approach doesn’t work for your setup, you can always fall back to the good old aws sts assume-role command as a manual alternative.
- uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::ACCOUNT_ID:role/target-role role-chaining: true aws-region: eu-west-2
Enter fullscreen mode
Exit fullscreen mode



Залишити відповідь