Secure your AWS credentials on GitHub Actions with OIDC
Source: Dev.to

GitHub Actions
Ever wondered if you can tighten the security of your AWS credentials for GitHub Actions (the workflow/pipeline that lets a GitHub repository perform CI/CD)?
Most tutorials start by creating an IAM user with programmatic keys and telling you to store those keys securely (never expose them to the public Internet). In GitHub Actions you would normally add AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to the repository Secrets section.
That does not give you the best possible security. A better approach exists that removes the need for long‑lived static credentials altogether.
AWS credentials must stay secret
If credentials are exposed, an attacker can use the permissions attached to that identity to cause serious damage. Applying the principle of least privilege when designing IAM users/roles is therefore essential.
AWS IAM Identity Provider (OIDC)
When the caller to AWS services supports OIDC v2, you can exchange a short‑lived token for an AWS session token. This lets you:
- Eliminate static
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYfrom GitHub Secrets. - Assume an IAM role via the OIDC token, granting only the permissions you need for the specific workflow.
Step‑by‑step
1. Create an AWS IAM OIDC identity provider
Using the AWS CLI
aws iam create-open-id-connect-provider \
--url https://token.actions.githubusercontent.com \
--client-id-list sts.amazonaws.com
Or via the AWS Console
- Open IAM → Identity providers → Add provider.
- Choose OIDC.
- Set Provider URL to
https://token.actions.githubusercontent.com. - Set Audience to
sts.amazonaws.com.

2. Create an IAM role that trusts the OIDC provider
Use the following trust policy (replace placeholders with your own values):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam:::oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:/:ref:refs/heads/"
}
}
}
]
}
Replace AWS_ACCOUNT_ID, GITHUB_ORG, GITHUB_REPOSITORY, and “ with the appropriate values for your environment.
Attach any permission policies the role needs (e.g., AmazonS3ReadOnlyAccess, custom policies, etc.).
3. Configure your GitHub Actions workflow
Give the workflow permission to request an OIDC token and then assume the role you just created.
# .github/workflows/deploy.yml
name: Deploy to AWS
# Request an OIDC ID token
permissions:
id-token: write # required for OIDC
contents: read # (optional) needed for checkout, etc.
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam:::role/
aws-region:
- name: Verify identity
run: aws sts get-caller-identity
Key points
permissions.id-token: writeenables the workflow to obtain a short‑lived OIDC token from GitHub.aws-actions/configure-aws-credentialsautomatically exchanges that token for temporary AWS credentials using the role you specified.
After this, do not store any AWS access keys in GitHub Secrets—the workflow will use the short‑lived credentials provided by the OIDC token.
Conclusion
This walkthrough mirrors the official aws-actions documentation but shows how to:
- Set up an OIDC identity provider in AWS.
- Create a role that trusts GitHub’s OIDC token.
- Configure a GitHub Actions workflow to assume that role without any static AWS secrets.
By adopting this pattern you:
- Remove long‑lived credentials from your repository.
- Reduce the attack surface (tokens expire after a few minutes).
- Simplify secret rotation—no manual rotation is required.
Implementing OIDC‑based authentication is a straightforward way to improve your security posture with virtually no performance impact.
Happy coding! 🎉
