paint-brush
Access GitHub API Securely Using GitHub Actions from an Organization Perspective - A Case Studyby@hackernoonnew
126 reads

Access GitHub API Securely Using GitHub Actions from an Organization Perspective - A Case Study

by Cristian LepadatuSeptember 13th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Have you ever wandered into the realm of GitHub API authentication? In case you did, you have arrived in the right spot, because I have an experience that I want to share with you.
featured image - Access GitHub API Securely Using GitHub Actions from an Organization Perspective - A Case Study
Cristian Lepadatu HackerNoon profile picture

Have you ever wandered into the realm of GitHub API authentication? In case you did, you have arrived in the right spot, because I have an experience that I want to share with you.


When trying to authenticate to the GitHub REST API you need to use either a personal access token , the workflow GITHUB_TOKEN variable or a GitHub installation access token. The first option is not really an option for automation purpose, because a personal access token as the name suggests it is usually attributed to an user and expires after a given time frame. The GITHUB_TOKEN variable can be an interesting option for a stand-alone repo, but it is scoped to the respective repository. Hence the correct option from a GitHub organization perspective is the use of GitHub installation access token.


The process of generating an installation access token requires several inputs that we obtain when we register a new GitHub application in an organization:


  1. Enter name, description, provide an URL (we’ll only use the app for authentication purposes, so you can use a dummy one) and uncheck the “Active” tick for the webhook. The other optional fields are to be left blank.
  2. While on the same page you need to configure the permissions required by the app.
  3. Once the registration is done, you will receive additional information on the next screen, such as app id.
  4. While on the same screen, press “Generate a new client secret” button.
  5. Import the App's private key in your AWS Account KMS service, under customer-managed keys of type asymmetric, sign-verify, RSA 2048, following steps 1 to 4 from the link. The private key is the client secret from previous step.


The previous step follows the security best practices of storing the app private key. Storing the private key in a GitHub secret is not as secure, because if an attacker gains access to the GitHub runner environment, the attacker will consequently have access to the GitHub secret. The solution proposed is similar to Azure Key Vault, but uses AWS KMS instead. Once imported in KMS, the private key can no longer be retrieved. The authorized users can ask the AWS KMS API to sign/verify messages on their behalf, but will not perform such actions directly on the messages using the key. This way, sign/verify actions, key storage as well as user authentication and authorization are delegated to AWS.

Please, make sure your AWS account access is properly secured!

As you might have realized already, AWS authentication becomes the weakest link in the chain in this scenario. While AWS takes care of the security of the cloud, you are responsible for the security in the cloud. This is a broader topic which is outside the scope of this article, but as a guideline, It is highly advised to use temporary AWS credentials scoped to the least privilege when accessing AWS API in order to sign the JWT token. More on how to set up a GitHub as an OIDC provider for AWS here.

Using AWS KMS will generate additional charges in your AWS bill.


In the following steps, we’ll prepare the repository to be able to get the GitHub app installation access token:


  1. Store the App's ID generated previously in your repository environment variable or secret (example: APP_ID).
  2. Store the previously generated KMS Key ID as a repository secret (example KMS_KEY_ID).
  3. Store the AWS role to be assumed by the action as a repository secret (example ROLE_TO_ASSUME). The setup assumes you are assuming an AWS role, hence using temporary AWS credentials.
  4. Store the AWS session name as an environment variable (example ROLE_SESSION_NAME). This is needed in case you are assuming and AWS role using OIDC.
  5. Store the AWS region name as an environment variable (example AWS_REGION).


Once you’re set up with all the above, you have all the prerequisite necessary in order to use this GitHub action for generating the GitHub installation access token for your GitHub app. The action which I have developed unlike the vanilla one uses AWS KMS in order to sign/verify the JWT token required for generating the GitHub installation access token.


Terraform - A Case Study

Recently I have started to investigate ways to authenticate terraform provider to the GitHub API in order to be able to use it in deploying GitHub Infrastructure (create repos, etc) inside a GitHub organization. The terraform documentation gives 2 options, GitHub app and OAuth/personal access token.


I have taken the inputs required by the GitHub app authentication (i.e. app id and app private key) and developed a GitHub action capable of using AWS KMS for storing the private key and generating the installation access token.


Once the token is generated, you can override the GITHUB_TOKEN workflow environment variable with the token produced by the action.


Here is a terraform example on how to use the action as well as the respective workflow file.


Enjoy!