OpenID Connect and Github Actions to authenticate with Amazon Web Services.

Hi, I’m DevOps Engineer at Tikal Knowledge.
In this tutorial, I will show how to:
- Use OpenID Connect within your Github workflows to authenticate with Amazon Web Services.
The reason behind that is security: Avoid storing long living AWS credentials (access_key_id and secret_access_key) in Github as a secrets.
2. Improve the security of ‘EC2 provisioning’ workflow I described in first guide: https://medium.com/everything-full-stack/use-github-actions-and-terraform-to-provision-ec2-instance-5b51636e4e54
Github Actions Published guides:
- Use GitHub Actions and Terraform to provision EC2 instance
- GitOps way with Github Actions and self-hosted runner on Kubernetes
- Automatic scaling with Github Actions and self-hosted runners
- Github Actions with k8s and Karpenter to dynamically provision your runners on spot instances
- Github Actions with ChatOps to write beautiful python code
- Use OpenID Connect with Github Actions to authenticate with Amazon Web Services
What is OpenID Connect?
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
OpenID Connect allows clients of all types, including Web-based, mobile, and JavaScript clients, to request and receive information about authenticated sessions and end-users. The specification suite is extensible, allowing participants to use optional features such as encryption of identity data, discovery of OpenID Providers, and logout, when it makes sense for them.
See https://openid.net/connect/faq/ for a set of answers to Frequently Asked Questions about OpenID Connect.
Let’s start
In previous post, I used ‘configure-aws-credentials’ action in workflow to authenticate via AWS.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: '${{ secrets.TF_USER_AWS_KEY }}'
aws-secret-access-key: '${{ secrets.TF_USER_AWS_SECRET }}'
aws-region: us-east-2
But we can do better, following the best practices and security considerations and not storing security credentials for AWS authentication in your repository.
To make it possible need to configure first OIDC provider in your AWS account and use ‘role-to-assume’ method with ‘configure-aws-credentials’ action.
Using ‘configure-aws-credentials’ with OIDC provider, will look like:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
aws-region: us-east-2
I will start by setting up AWS OpenID Connect Identity Provider
Explanation of how to configure OpenID Connect in Amazon Web Services you can find here
Your AWS account -> IAM -> Identity providers -> Create Identity Provider. Select OpenID connect.

For the provider URL: Use ‘https://token.actions.githubusercontent.com’
For the “Audience”: Use ‘sts.amazonaws.com’

Click on ‘Get thumbprint’ and then ‘Add provider’ button.

Next we need to create IAM role to start using provider
IAM -> Roles -> Create role
Select ‘Web Identity’
Identity provider: ‘token.actions.githubusercontent.com’
Audience: ‘sts.amazonaws.com’

Click ‘Next’ and add needed permissions, I will use AmazonEC2FullAccess needed to provision EC2 instance.

Click ‘Next’
Give your role a name: ‘gh-role’ in my case
Trusted policy auto generated for you, account name I changed to 12345678, but you will see you account instead.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRoleWithWebIdentity",
"Principal": {
"Federated": "arn:aws:iam::12345678:oidc-provider/token.actions.githubusercontent.com"
},
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": [
"sts.amazonaws.com"
]
}
}
}
]
}
Click ‘Create Role’ and the role will be created.
Use OIDC provider with EC2 provisioning workflow
The original workflow I created in first guide: https://medium.com/everything-full-stack/use-github-actions-and-terraform-to-provision-ec2-instance-5b51636e4e54
Workflow with changes included:
name: Provision t3.micro EC2
on:
workflow_dispatch:
inputs:
ec2-name:
description: EC2 name
required: true
default: 'App Server'
type: string
jobs:
provision-ec2:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::12345678:role/gh-role
aws-region: us-east-2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false
- name: Terraform Apply
id: apply
env:
TF_VAR_ec2_name: "${{ github.event.inputs.ec2-name }}"
run: |
cd tf-example/
terraform init
terraform validate
terraform plan
terraform apply -auto-approve
- ‘Configure AWS credentials’ step changed
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::12345678:role/my-github-actions-role
aws-region: us-east-2
I want to use new created OIDC provider, for this ‘assume role is used’
Read: https://github.com/aws-actions/configure-aws-credentials for more info.
2. Permissions section added: you need in order to be able request the OIDC JWT ID token.
permissions:
id-token: write
contents: read
You can validate everything works great after changes.
You can find YAML with final workflow in github repo: https://github.com/warolv/github-actions-series/gh-oidc
git clone git@github.com:warolv/github-actions-series.git
cd gh-oidc
Conclusion
In this tutorial, I explained how to make your workflow with Github Actions more secure, by not storing your AWS credentials in your repo and using OIDC provider for authentication.
Thank you for reading, I hope you enjoyed it, see you in the next post.
If you want to be notified when the next post of this tutorial is published, please follow me here on medium, Twitter (@warolv) and my YT channel.