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:
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:
APP_ID
).KMS_KEY_ID
).ROLE_TO_ASSUME
). The setup assumes you are assuming an AWS role, hence using temporary AWS credentials.ROLE_SESSION_NAME
). This is needed in case you are assuming and AWS role using OIDC.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.
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!