Service Accounts

When automating GitHub processes you will need to use GitHub credentials in your automation. These credentials are usually attached to shared “service accounts”. This page describes the options available to you and recommended best practice for these situations.

Service account options in order of preference are:

  1. Deploy Key – an SSH key that grants read or write access to a single repository.
  2. GitHub App – an internal GitHub “app” configured with appropriate permissions and repository access.
  3. Divisional Machine User – a GitHub account on-boarded by your division that is designed to be used as a service account. This should be avoided if possible.

Deploy key (1) or GitHub app (2) are recommended where possible. This mirrors GitHub’s own security hardening advice.


The provision of service account access must consider:

  1. Least Privilege: The credentials should be limited to the minimum GitHub permissions across the minimum number of repositories in Flutter-Global to fulfill the purpose of the automation.
  2. Transport & Storage: The credentials should be stored and transported securely. For in-house automation this means using mechanisms reviewed and approved by your divisional security team. For 3rd party access, this means they have been reviewed and achieved a low risk score through the the 3rd party security assessment process.
  3. Ownership: All service accounts must be owned, with clear accountability for who will support the account and its usage.
  4. Access & Rotation: The credentials should be rotated along with a review of the need for any individuals who have direct access at least once every 6 months.
  5. Ease of Use: Ease of use should be optimised and any support overhead reduced where it makes little practical difference to the risk profile of its use.

Example (Jenkins)

A divisionally maintained Jenkins deployment requires access to a subset of the repositories in Flutter-Global for CI/CD:

  • Least privilege requires the credentials to have the minimum read-only permissions to only the required content. A GitHub App can be configured to limit the permissions and repository access in this way.
  • The credentials are stored securely in a divisionally approved Hashicorp Vault deployment which is integrated with Jenkins.
  • Named GitHub App Managers are configured who own the GitHub app service account. They are responsible for rotating private keys and reviewing credential access at least every 6 months.
  • To optimise ease of use, the GitHub app is configured with read access to all “Internal” visibility repositories by default. This reduces the overhead of repo access configuration but is low-risk given the “Internal” visibility of these repos already.

Deploy Key

A deploy key is an SSH key that grants access to a single repository. It is useful when your use-case is limited to read or write access to the content of a single repository. If your use-case is more complex, use a GitHub app instead.

  • Keys are created as documented by GitHub here. You can do this yourself if you have admin permissions on your repository.
  • Read-only deploy keys can be used to clone repositories.
  • Optionally, write access can be granted which allows commits to be pushed to the repository. This push is treated as an “admin” commit so can be configured to bypass branch protection.

The deploy key is an SSH key rather than an oAuth token, so it can be used in a GitHub Action workflow like:

- name: Setup SSH agent to use deploy key
    SSH_AUTH_SOCK: /tmp/ssh_agent.sock
    SSH_PRIVATE_KEY: ${{ secrets.MY_DEPLOY_KEY }}
  run: |
    ssh-agent -a $SSH_AUTH_SOCK > /dev/null
    ssh-add - <<< "$SSH_PRIVATE_KEY"
- name: Checkout the repo using deploy key
    SSH_AUTH_SOCK: /tmp/ssh_agent.sock
  run: git clone --depth 1 my-repo
# ...
# make any changes required (if a write use-case)
# ...
- name: Push repo changes using deploy key
  working-directory: my-repo
    SSH_AUTH_SOCK: /tmp/ssh_agent.sock
  run: |
    if [ ! -z "$(git status --porcelain=v1 2>/dev/null)" ]
      git config "github-actions"
      git config
      git pull --no-edit
      git add -A
      git commit -m 'my commit message'
      git push

If using Github Action workflows, a deploy key should be securely stored in secrets as recommended here.

GitHub App

GitHub Apps can be installed on selected repositories with granular permissions on the resources within them. For service account access a GitHub App is created internal to Flutter-Global and granted access to the repositories required with the minimum permissions needed. They are suitable for almost all use-cases.

  • GitHub apps must be created by org owners, so please contact the Inner Source Team to begin this process.
  • Owners of the service account can be configured as “GitHub App Managers” to maintain it directly (e.g. regular key rotation).
  • Configuration is the same as fine-grained personal access tokens so these can be used to test the suitability and permissions required.

A GitHub App is authenticated via private keys, and short-lived access tokens need to be generated on-demand for most use-cases. For use in GitHub Action workflows, an action helper is provided by Flutter-Tech/github-app-token:

- name: Get access token from GitHub app
  id: app
  uses: Flutter-Tech/github-app-token@v2
    APP_PEM: ${{ secrets.GITHUB_APP_PEM }}
    APP_ID: 123

Then use the access token as desired, e.g. to checkout a repository:

- name: Clone a repo using the GitHub app
  uses: actions/checkout@v3
    repository: Flutter-Global/your-repo-name
    token: ${{ }}

If using Github Action workflows, the GitHub app private key should be securely stored in secrets as recommended here.

Divisional Machine User

You can create a new account on and treat it as a service account that will be used exclusively for automation. This is managed by your division so you would need to discuss this with your divisional GitHub owner to onboard such an account and manage ownership. This option is NOT recommended, you should use a GitHub App instead.

The machine user can be granted access to repositories like any other user. We recommend granting repository access to a GitHub team that contains the machine user rather than directly to the machine account itself. This allows faster incident recovery if the machine account is mistakenly ejected from the org and easier rotation between personal & machine accounts if required.

You will need to generate a fine-grained personal access token for the machine user to use within your automation. You should not use a “classic” personal access token. If using Github Action workflows the token should be securely stored as recommended here.