Configuring OIDC in AWS for Github Actions
Configure OpenID Connect (OIDC) in AWS to enable GitHub Actions to assume IAM roles with short-term credentials—eliminating the need for storing long-term secrets and improving your CI/CD pipeline’s security posture.
Published on May 5, 2025
Tags: security aws oidc github-actions devops ci-cd
Github Actions workflows requires access to AWS resources for CI/CD. We can use long-term credentials by storing access key id and secret access key as a secret in GitHub, but using long-term credentials is not a security best practice. It is recommended to use short-term credentials. We can use OIDC to gain short term credentials from cloud providers such as AWS, Azure, GCP, HashiCorp, etc.
GitHub provides a comprehensive documentation for Configuring OIDC in AWS.
Setup
The configuration is done in three major steps:
- Creating an Identity Provider (IdP) in AWS
- Creating a role with required permissions in AWS
- Creating/Updating the workflow to use the role to access and use AWS resources
Creating an Identity Provider (IdP) in AWS
The official documentation for creating an OIDC IdP in AWS can be found here.
The steps with the AWS CLI commands are as follows:
- Optional: Get the publicly available configuration and metadata for github actions using https://token.actions.githubusercontent.com/.well-known/openid-configuration
- Add the identity provider to AWS
aws iam create-open-id-connect-provider --url https://token.actions.githubusercontent.com
- Get the ARN for the IdP
aws iam list-open-id-connect-providers
- Output(oidc-arn):
arn:aws:iam::<account-number>:oidc-provider/token.actions.githubusercontent.com
- Add
sts.amazonaws.com
as audaws iam add-client-id-to-open-id-connect-provider --client-id sts.amazonaws.com --open-id-connect-provider-arn arn:aws:iam::<account-number>:oidc-provider/token.actions.githubusercontent.com
- Verify:
aws iam get-open-id-connect-provider --open-id-connect-provider-arn arn:aws:iam::<account-number>:oidc-provider/token.actions.githubusercontent.com
There is also a CloudFormation template provided by the aws-actions/configure-aws-actions
that can be used to create the IdP. See Configure IAM to Trust Github
Create Role with required permissions in AWS
This step involves creating a trust policy for the role to be assumed by GitHub actions. Various versions can be found for limiting access to an org, repository or a branch in the AWS Documentation. It uses token.actions.githubusercontent.com:sub
as a key condition for the trust policy.
An example Trust Policy to allow access to an entire GitHub Organization is as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::012345678910: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:GitHubOrg/*"
}
}
}
]
}
You can create the role using the json file for the Trust Policy using the following CLI command:
aws iam create-role --role-name GithubActionsRole --assume-role-policy-document file:<path-to-TrustPolicy.json>
You can add the required permissions to the created role using attach-role-policy command. For example, if you want to grant a administrator access:
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/PowerUserAccess --role-name GithubActionsRole
Creating/Updating the workflow to use the role to access and use AWS resources
The final step is to configure the Github Actions Workflow to configure AWS credentials and access AWS resources.
aws-actions/configure-aws-credentials can be used to configure the AWS credentials.
The job also requires the following permission settings:
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
A sample workflow to list S3 buckets (assuming appropriate permissions are granted to the GithubActionsRole) is as follows:
name: AWS example workflow
on: push
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
jobs:
ListS3Buckets:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ROLE-TO-ASSUME-ARN
aws-region: ${{ env.AWS_REGION }}
# Upload a file to AWS s3
- name: List S3
run: aws s3 ls
How it works
The working of OIDC flow is illustrated in the diagram below (dotted lines show the configuration):
The explanation of what is happening is as follows:
- When you create an IAM OIDC Identity Provider, it establishes trust between AWS and Github
- aws-actions/configure-aws-credentials does the following:
- Generates an OIDC token (sends request to GithubOIDC provider using the specified audience and get JWT ID token that can be used to get the access token from AWS) (Source Code, uses getIDToken function in actions/core)
- Uses the webIdentityToken (OIDC Token) to make an
AssumeRoleWithWebIdentity
call to get the AWS STS token- AWS uses the established trust relationship to validate the authenticity of the identity token, and returns a STS token
- Once the STS token is received, it can be used to access the AWS resources (for example, when running
aws s3 ls
)- AWS validates the assumed role using STS and permissions granted to the role to grant/deny access to permissions
Additional details on aws-actions/configure-aws-credentials
- If you are using a non-default partition, you need to specify
audience
as an option (For example,audience: sts.amazonaws.com.cn
) in the Configure AWS Credentials step. - There are other useful options such as
role-duration-seconds
role-session-name