GitHub Action
workflow-application-token-action
This is a GitHub Action that can be used to get scoped limited access, expiring credentials for use inside GitHub Actions Workflows.
Why would you want to do this? Well the GITHUB_TOKEN
whilst having an expiry, has some protections around creating
events that prevent downstream GitHub Actions workflow from triggering. This prevents recursive loops from workflows, but
there are a number of valid types of workflows that may require or desire triggering downstream GitHub Actions Workflows.
The existing way to work around this today is to use a Personal Access Token, but these tokens are tied to a user and
generally are over priviledged for the tasks at hand, increasing the risk if they get exposed and are not time limited
like the GITHUB_TOKEN
.
This is where a GitHub Application access token can really help out. The benefits of GitHub Applications is that you can restrict/scope the access of the token considerably more than what can be achieved using a Personal Access Token. The access token from the GitHub Application is also time limited, expiring after an hour from being issued, providing some more protection against any leaking of credentials from a Workflow.
To use this action you first need a GitHub Application created so that you can request temporary credentials on behalf of the application inside your workflows.
Requirements:
- A new or existing GitHub Application with the access scopes required
- A private key for the GitHub Application
- The GitHub Application installed on the repository that the GitHub Actions Workflow will execute from
You will need to have a GitHub Application that is scoped with the necessary permissions for the token that you want to retrieve at runtime.
To create a GitHub Application you can follow the steps available at https://docs.github.com/en/developers/apps/creating-a-github-app
The important configuration details for the application are:
GitHub App name
a human readable application name that is unique within GitHub.comDescription
some details about your application and what you intend to use it forHomepage URL
needs to be set to something as long as it is a URLExpire user authorization tokens
should be checked so as to expire any tokens that are issuedWebhook
Active
checkbox should be uncheckedRepository permissions
,Organization permissions
and/orUser permissions
should be set to allow the access required for the token that will be issuedWhere can this GitHub App be installed?
should be scoped to your desired audience (the current account, or any account)
Once the application has been created you will be taken to the General
settings page for the new application.
The GitHub Application will be issued an App ID
which you can see in the About
section, take note of this for later
use in the Actions workflow.
On the General
settings page for the application, at the bottom there is a Private keys
section that you can use to
generate a private key that can be utilized to authenticate as the application.
Generate a new private key and store the information for later use.
Note: the private keys can and should be rotated periodically to limit the risks of them being exposed in use.
Once you have the GitHub Application defined, you will need to install the application on the target organization or repository/ repositories that you want it to have access to. These will be any repositories that you want to gather information from or want the application to modify as per the scopes that were defined when the application was installed.
Note: The GitHub Application will need to be installed on the organization and or repository that you are executing the GitHub Actions workflow from, as the implementation requires this to be able to generate the access tokens.
To use the action in a workflow, it is recommended that you store the GitHub Application Private key in GitHub Secrets. This can be done at a repository or organization level (provided that the actions workflow has access to the secret).
When storing the Private key, you can store the raw PEM encoded certificate contents that the GitHub Application generates for you or Base64 encode it in the secret.
application_id
: The GitHub Application ID that you wil be getting the access token forapplication_private_key
: A private key generated for the GitHub Application so that you can authenticate (PEM format or base64 encoded)permissions
: The optional limited permissions to request, specifying this allows you to request a subset of the permissions for the underlying GitHub Application. Defaults to all permissions available to the GitHub Application when not specified. Must be provided in a comma separated list of token permissions e.g.issues:read, secrets:write, packages:read
organization
: An optional organization name if the GitHub Application is installed at the Organization level (instead of the repository).github_api_base_url
: An optional URL to the GitHub API, this will be read and loaded from the runner environment by default, but you might be bridging access to a secondary GHES instance or from GHES to GHEC, you can utilize this to make sure the Octokit library is talking to the right GitHub instance.https_proxy
: An optional proxy to use for connecting with the GitHub instance. If the runner hasHTTP_PROXY
orHTTPS_PROXY
specified as environment variables it will attempt to use those if this parameter is not specified.revoke_token
: An optional booleantrue
orfalse
value to revoke the access token as part of the post job steps in the actions workflow. To preserve backwards compatibility on this action, it defaults tofalse
.
Get a token with all the permissions of the GitHub Application:
jobs:
get-temp-token:
runs-on: ubuntu-latest
steps:
- name: Get Token
id: get_workflow_token
uses: peter-murray/workflow-application-token-action@v4
with:
application_id: ${{ secrets.APPLICATION_ID }}
application_private_key: ${{ secrets.APPLICATION_PRIVATE_KEY }}
- name: Use Application Token to create a release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ steps.get_workflow_token.outputs.token }}
with:
....
Get a token with a limited subset of the permissions of the Github Application, in this case just the actions:write
permission:
jobs:
get-temp-token:
runs-on: ubuntu-latest
steps:
- name: Get Token
id: get_workflow_token
uses: peter-murray/workflow-application-token-action@v4
with:
application_id: ${{ secrets.APPLICATION_ID }}
application_private_key: ${{ secrets.APPLICATION_PRIVATE_KEY }}
permissions: "actions:write"
- name: Use Application Token to create a release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ steps.get_workflow_token.outputs.token }}
with:
....
Get a token with all the permissions of the Github Application that is installed on an organization:
jobs:
get-temp-token:
runs-on: ubuntu-latest
steps:
- name: Get Token
id: get_workflow_token
uses: peter-murray/workflow-application-token-action@v4
with:
application_id: ${{ secrets.APPLICATION_ID }}
application_private_key: ${{ secrets.APPLICATION_PRIVATE_KEY }}
organization: octodemo
- name: Use Application Token to create a release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ steps.get_workflow_token.outputs.token }}
with:
....
You can specify a proxy server directory using the https_proxy
parameter in your with
settings, or by falling back to
using any environment variables used to provide a proxy reference; HTTP_PROXY
or HTTPS_PROXY
(or lowercase variants e.g. http_proxy
).
If defined, the request will use the proxy to route the connection to the GitHub instance.
jobs:
get-temp-token:
runs-on: ubuntu-latest
steps:
- name: Get Token
id: get_workflow_token
uses: peter-murray/workflow-application-token-action@v4
with:
application_id: ${{ secrets.APPLICATION_ID }}
application_private_key: ${{ secrets.APPLICATION_PRIVATE_KEY }}
organization: octodemo
https_proxy: http://my-squid-proxy:3128
....
In version 2.1.0
of this action support has been added for no_proxy
environment variables that might be present in the workflows or actions runner.
If the https_proxy
input variable is specified for the action, then any no_proxy
setting will be ignored as the proxy in this case has been explicitly set and
this action views that as being entirely intentional.
If on the other hand the proxy server is being detected using environment variables, http_proxy
, HTTP_PROXY
, https_proxy
, HTTPS_PROXY
and no_proxy
is present
then it will be parsed for hostname matches as to whether or not to use the proxy when access the GitHub API.
The format that is supported for no_proxy
environment variable is a comma separated list of host names, e.g. api.github.com,www.google.com
of when to not use the proxy server.
To provide additional options for security around the access token and waiting on it to expire, you can leverage the revoke_token
input set to true
so that at the end of the
job run, a post actions step will revoke the access token, invalidating it so that is is immediately invalid and cannot be used.