After working extensively to migrate repositories and pipelines from TFS to GitHub, we found that many steps in the pipeline flow required to be interfaced with the GitHub API. Whether it be creating a GitHub release, uploading items to the GitHub release or removing items from the GitHub release, we needed a way to authenticate with the GitHub API without having to renew personal access tokens, so as to remove as much manual intervention as possible in our pipelines.
This is where GitHub Apps came in, as it provided us a way to interface with the GItHub API in our pipelines without having to worry about the token expiring in the next 3, 6 or 12 months.
GitHub App Configuration
To set the GitHub App configuration up the following must be done.
- Log into https://github.com
- On the top right click on your profile picture and click on Settings
- On the left side panel click on Developer settings at the bottom
- On the left side panel click on GitHub Apps and on the top right click on New GitHub App
- Configure your GitHub app with the following settings
- GitHub App name – Any name you want e.g. “test-bot”
- Homepage URL – Any dummy website just needs to be in https format e.g. “https://testbot.com”
- Webhook Active – Unchecked
- Permissions – Provide the GitHub App any permissions you require it to have when interfacing with the API. For more information on permissions available look at the following page here https://docs.github.com/en/rest/overview/permissions-required-for-github-apps?apiVersion=2022-11-28
- Leave everything else as the default and click Create GitHub App
- Once created it will take you into the settings of your GitHub App here you must now go to the General settings on the left side panel and scroll down to Private keys and Generate a new private key
- When the private key is created it will automatically download this to your local computer make sure to store this file and its value somewhere safe as this will be used to authenticate with the GitHub API.
- Scroll all the way up on the General settings and also record the App ID, as this will also be used to authenticate with the API
- Once done now we need to install the app. To do this on the side panel go to Install App
- And press the install button on the organization you want to install the GitHub App on so it can run GitHub API commands against it
- Now your GitHub App is ready to be used to authenticate with the GitHub API
Modify GitHub App permissions
- If you wish to modify the permissions on your GitHub App and update what it can and can’t do then on the left side panel click on Permissions & events
- Here you can add or remove Repository, Organization or Account permissions for the GitHub App
- When permissions are modified you need to go to the GitHub organization your installed your GitHub app on and go into its settings
- On the left side panel click on GitHub Apps
- You should see your GitHub App name in the list with the following underneath Permission updates requested. Review request. Click on Review Request
- And then press Accept new permissions
Authenticating with the GitHub API
- Now to authenticate with the GitHub API there are multiple ways to do so
- If in a pipeline the following action can be used:
- https://github.com/tibdex/github-app-token
- Where you pass in the GitHub App ID and Private Key whether it be passed in as an organization secret or as a hard coded value, will look something like this
- name: Generate a token
id: generate_token
uses: tibdex/github-app-token@v1
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.PRIVATE_KEY }}- This will generate a token for you that you can pass in to your scripts or other actions to interface with the GitHub API
- If in a PowerShell script the following functions can be utilized to generate the token:
- If in a pipeline the following action can be used:
Function Get-CurrentTimestamp {
[int](Get-Date -UFormat %s) # Grab Unix Epoch Timestamp
}
Function Get-ExpiryTimeStamp {
param (
[int]$ValidForSeconds = 30
)
$exp = (Get-CurrentTimestamp) + $ValidForSeconds # Grab Unix Epoch Timestamp and add desired expiration.
$exp
}
Function Get-IssueAtTimeStamp {
param (
[int]$ValidForSeconds = 30
)
$exp = (Get-CurrentTimestamp) - $ValidForSeconds # Grab Unix Epoch Timestamp and add desired expiration.
$exp
}
Function New-GHAPIToken {
$Issuer = '<GitHub App ID>'
$rsaPrivateKey = Get-Content "<Location to Private Key File>
" -AsByteStream
$exp = Get-ExpiryTimeStamp -ValidForSeconds 300
$iat = Get-IssueAtTimeStamp -ValidForSeconds 60
$payloadClaims = @{
"iat"= $iat
}
# using RS256
$jwt2 = New-JWT -Algorithm 'RS256' -Issuer $Issuer -SecretKey $rsaPrivateKey -ExpiryTimestamp $exp -PayloadClaims $payloadClaims
$AppInstallationDetails = Get-APIData -Uri "https://api.github.com/app/installations" -Headers @{"Authorization" = "Bearer $($jwt2)"; "X-GitHub-Api-Version" = "2022-11-28"; "Accept" = "application/vnd.github+json"}
$InstallationAccessTokenDetails = Post-APIData -Uri "https://api.github.com/app/installations/$($AppInstallationDetails[0].id)/access_tokens" -Headers @{"Authorization" = "Bearer $($jwt2)"; "X-GitHub-Api-Version" = "2022-11-28"; "Accept" = "application/vnd.github+json"}
return $InstallationAccessTokenDetails.token
}
- Ensure to replace the following:
- <GitHub App ID> – The app id you recorded in the earlier step for your GitHub app
- <Location to Private Key File> – The private key file that was automatically downloaded to your local machine when you generated a new one in the earlier steps
- To call the function to create the GitHub token the following command is used
$token = Generate-GHAPIToken
- This will generate a token for you that you can pass into your scripts to interface with the GitHub API
Conclusion
In this blog post, we looked at how to configure a GitHub App to interface with the GitHub API so as to avoid using personal access tokens and not be concerned with expiry times . Hopefully you have found this post informative, if you have other GitHub tips and tricks let us know and don’t be afraid to share your thoughts
Related Links
- https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps
- https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/about-authentication-with-a-github-app
- https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app