Jerome Kelly

2025-05-07

GitHub OIDC

While injecting AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY through Github secrets is a very common practice, it is a suboptimal approach. Instead the OIDC protocol should be leverage to build more secure pipeline. This will be a very hands-on tutorial on how to it



Get the OIDC token

This is already documented in the official documentation, but in short: you can ask Github to generate one or more tokens for job execution. The audience should represent the external system the token is intended for. In this case, STS refers to AWS Secure Token Service.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_id_token.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Exchanging the OICD token

While the step described above is interesting, we recommend not doing this. Instead, simply use the official configure-aws-credentials GitHub Action. This abstracts all the steps involved in creating the token and exchanging it through the Secure Token Service. Just provide an existing IAM role, and you’re good to go!

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_extension.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Configuring AWS

The part were most people struggle is to configure the AWS side. In AWS create go to IAM > Identity providers and create a new one.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_create_idp.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

If you are unsure about the URL, add /.well-known/openid-configuration to it and it should return JSON. Every OIDC provider exposes their configuration at this endpoint. For Github, the url is https://token.actions.githubusercontent.com

Note that the audience field is actually arbitrary—just make sure it matches on both Github and AWS, and that it has a meaningful value.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_match_audience.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Create an IAM role

This is the fun part—you can now create an IAM role that uses the identity provider we just created as its trusted entity.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_create_role.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

Always respect the Principle of Least Privilege when adding permissions!

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/git_app_permission.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

Github includes a sub value in the OIDC token that contains the organization, repo, and branch information. This is extremely powerful! It means you can create IAM roles that are only usable when running from a specific branch.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_app_permission.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

For example, the IAM role that deploys to production should include a condition that restricts its usage to the prod branch. In Github, you can then enforce protections on the prod branch, such as requiring code reviews. By combining the granularity of IAM roles with Github’s branch protection features, you can build a highly secure and compliant DevOps pipeline.

Jerome Kelly

2025-05-07

GitHub OIDC

While injecting AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY through Github secrets is a very common practice, it is a suboptimal approach. Instead the OIDC protocol should be leverage to build more secure pipeline. This will be a very hands-on tutorial on how to it



Get the OIDC token

This is already documented in the official documentation, but in short: you can ask Github to generate one or more tokens for job execution. The audience should represent the external system the token is intended for. In this case, STS refers to AWS Secure Token Service.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_id_token.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Exchanging the OICD token

While the step described above is interesting, we recommend not doing this. Instead, simply use the official configure-aws-credentials GitHub Action. This abstracts all the steps involved in creating the token and exchanging it through the Secure Token Service. Just provide an existing IAM role, and you’re good to go!

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_extension.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Configuring AWS

The part were most people struggle is to configure the AWS side. In AWS create go to IAM > Identity providers and create a new one.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_create_idp.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

If you are unsure about the URL, add /.well-known/openid-configuration to it and it should return JSON. Every OIDC provider exposes their configuration at this endpoint. For Github, the url is https://token.actions.githubusercontent.com

Note that the audience field is actually arbitrary—just make sure it matches on both Github and AWS, and that it has a meaningful value.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_match_audience.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Create an IAM role

This is the fun part—you can now create an IAM role that uses the identity provider we just created as its trusted entity.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_create_role.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

Always respect the Principle of Least Privilege when adding permissions!

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/git_app_permission.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

Github includes a sub value in the OIDC token that contains the organization, repo, and branch information. This is extremely powerful! It means you can create IAM roles that are only usable when running from a specific branch.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_app_permission.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

For example, the IAM role that deploys to production should include a condition that restricts its usage to the prod branch. In Github, you can then enforce protections on the prod branch, such as requiring code reviews. By combining the granularity of IAM roles with Github’s branch protection features, you can build a highly secure and compliant DevOps pipeline.

Jerome Kelly

2025-05-07

GitHub OIDC

While injecting AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY through Github secrets is a very common practice, it is a suboptimal approach. Instead the OIDC protocol should be leverage to build more secure pipeline. This will be a very hands-on tutorial on how to it



Get the OIDC token

This is already documented in the official documentation, but in short: you can ask Github to generate one or more tokens for job execution. The audience should represent the external system the token is intended for. In this case, STS refers to AWS Secure Token Service.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_id_token.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Exchanging the OICD token

While the step described above is interesting, we recommend not doing this. Instead, simply use the official configure-aws-credentials GitHub Action. This abstracts all the steps involved in creating the token and exchanging it through the Secure Token Service. Just provide an existing IAM role, and you’re good to go!

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_extension.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Configuring AWS

The part were most people struggle is to configure the AWS side. In AWS create go to IAM > Identity providers and create a new one.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_create_idp.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

If you are unsure about the URL, add /.well-known/openid-configuration to it and it should return JSON. Every OIDC provider exposes their configuration at this endpoint. For Github, the url is https://token.actions.githubusercontent.com

Note that the audience field is actually arbitrary—just make sure it matches on both Github and AWS, and that it has a meaningful value.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_match_audience.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">



Create an IAM role

This is the fun part—you can now create an IAM role that uses the identity provider we just created as its trusted entity.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_create_role.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

Always respect the Principle of Least Privilege when adding permissions!

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/git_app_permission.png" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

Github includes a sub value in the OIDC token that contains the organization, repo, and branch information. This is extremely powerful! It means you can create IAM roles that are only usable when running from a specific branch.

<img src="https://s3.ca-central-1.amazonaws.com/assets.prod.thirdbridge.ca/blog_images/github_app_permission.webp" alt="Responsive Image" style="width: 95vw; max-width: 95%; height: auto; display: block; margin: 0px auto;" media="(max-width: 768px)" onload="this.style.width='95vw'; this.style.maxWidth='95%';">

For example, the IAM role that deploys to production should include a condition that restricts its usage to the prod branch. In Github, you can then enforce protections on the prod branch, such as requiring code reviews. By combining the granularity of IAM roles with Github’s branch protection features, you can build a highly secure and compliant DevOps pipeline.

contact@thirdbridge.ca

+1 514 316 5399

1751 Rue Richardson Bureau 5.120, Montréal, QC H3K 1G6

330 Rue Saint-Vallier E suite 330, Québec, QC G1K

1475 North Scottsdale Road, Suite 200, Scottsdale, AZ 85257

contact@thirdbridge.ca

+1 514 316 5399

1751 Rue Richardson Bureau 5.120, Montréal, QC H3K 1G6

330 Rue Saint-Vallier E suite 330, Québec, QC G1K

1475 North Scottsdale Road, Suite 200, Scottsdale, AZ 85257

contact@thirdbridge.ca

+1 514 316 5399

1751 Rue Richardson Bureau 5.120, Montréal, QC H3K 1G6

330 Rue Saint-Vallier E suite 330, Québec, QC G1K

1475 North Scottsdale Road, Suite 200, Scottsdale, AZ 85257