Service Accounts
To use GitHub APIs from your own automation you need one of:
- GitHub Action Token – a short-lived access token available to GitHub Action workflows.
- Deploy Key – an SSH key with read or write access to a single repository.
- GitHub App – to generate short-lived access tokens with limited permissions on-demand.
- Your Fine-Grained Access Token – your access token but with limited permissions & scope.
- Machine User Access Token – an access token for a GitHub account with limited permissions.
Attempt these options in this order – i.e. only consider (2) if (1) isn’t suitable; only consider (3) if (2) isn’t suitable, etc.
Requirements
You must:
- Least Privilege: Configure the minimum access possible – limited permissions, on limited repositories, for a limited time.
- Transport & Storage: Store and transport the credentials securely. Use mechanisms approved by your divisional security team for in-house systems. For 3rd parties, their security assessment score must be low risk.
- Ownership: Document who owns and supports the integration.
- Access & Rotation: Rotate credentials and review privileges at least once every year.
- Ease of Use: Optimise for ease of use not just reduced risk.
Example: Jenkins
A Jenkins instance requires read access to a set of repositories in Flutter-Global for CI/CD.
- ❌ A GitHub Action Workflow Token isn’t available outside a workflow.
- ❌ A Deploy Key can only provide access to one repository.
- ✅ A GitHub App can provide read-only access to specific content.
A GitHub App meets the requirements because:
- Least Privilege: The GitHub App limits permission to read-only access to specific repos.
- Transport & Storage: Jenkins stores the app private key in Jenkins Credentials, and uses short-lived access keys & SSL to access GitHub APIs.
- Ownership: Flutter-Global org owners document the justification for the app and the contact details of the team who support Jenkins.
- Access & Rotation: Org owners create a reminder for an annual private key rotation and access permission review.
- Ease of Use: The app has read access to all inner source repositories by default. This reduces the effort of repo access additions, but is low-risk given the intended wide visibility of these repos already.
GitHub Action Token
A GitHub Action workflow can use an automatic access token provided in the GITHUB_TOKEN
environment variable. GitHub document this here.
- Only available to GitHub Action workflows.
- Can only access the repository on which the workflow is running.
- Configure the desired permissions like this.
For read access to other repositories, in Flutter-Global you can use the pre-configured cross repo read access to clone another inner source repository.
Deploy Key
A deploy key is an SSH key granted read or write access to the content of a single repository.
- You can create one yourself.
- Use a read-only deploy key to clone a repo and use the content.
- Use a write deploy key to commit changes to the content. This write is an “admin” commit so can bypass branch protection if configured to do so.
How to use a deploy key in a GitHub Action workflow.
- name: Setup SSH agent to use deploy key env: 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 env: SSH_AUTH_SOCK: /tmp/ssh_agent.sock run: git clone --depth 1 git@github.com:Flutter-Global/my-repo.git my-repo # ... # make any changes required (if a write use-case) # ... - name: Push repo changes using deploy key working-directory: my-repo env: SSH_AUTH_SOCK: /tmp/ssh_agent.sock run: | if [ ! -z "$(git status --porcelain=v1 2>/dev/null)" ] then git config user.name "github-actions" git config user.email github-actions@github.com git pull --no-edit git add -A git commit -m 'my commit message' git push fi
A deploy key can be securely stored in GitHub secrets for use in a workflow.
GitHub App
GitHub Apps can generate short-lived access tokens on-demand. An app has permissions and scope settings the same as a fine-grained access token which is useful to test with first.
- The inner-source team manage and install GitHub Apps as Flutter-Global org owners. Contact them to set one up.
- You generated tokens on-demand from an app private key.
- In GitHub Action workflows, use actions/create-github-app-token:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
Always protect the token in a GitHub environment to use it in a GitHub Action workflow.
Your Fine-Grained Access Token
A fine-grained personal access token represents your GitHub account with restricted scope (i.e. limited repositories) and restricted permissions (i.e. what it can do). At present this is a beta product from GitHub – everything works OK apart from these tokens can’t authenticate with GitHub Packages.
- You can create a fine-grained access token yourself in your GitHub settings.
- Apply the principle of least privilege and limit the token as much as you can. You can create several tokens for different use-cases and restrict each differently.
- You must set an expiry date – we recommend 3 to 6 months.
- Protect the token in a GitHub environment to use it in a GitHub Action workflow.
A common question is:
Isn’t this fragile/bad? What if I leave or change roles?
A personal fine-grained access token is less robust than a GitHub App, but for minor point-to-point automation often more convenient. The ability to limit the scope and permissions means you aren’t leaking your other account permissions. Yes, you need to change the ownership of the token if you leave or change role – but you need to rotate these tokens regularly anyway. We recommend a short token expiry (e.g. 3 months) so that you are regularly reminded of it exists and make you more likely to document it!
⚠️ Don’t confuse “FINE-GRAINED” access tokens with “CLASSIC” personal access tokens. Classic access tokens have no restrictions on scope (which repositories) and only crude permissions (i.e. the what it can do). If you need to use a classic access token, you must use a machine user (see below) to limit the scope and permissions via that user.
Machine User
A machine user is a GitHub account used exclusively for system automation. You use it by creating fine-grained or classic access tokens for the user.
- Your divisional GitHub owner manages the creation and regular review of these users. Contact them if you need to create one.
- Grant access to a Flutter-Global team that contains the machine user rather than directly to the user itself. This allows faster incident recovery if the machine user is mistakenly ejected from the org and easier rotation between machine users.
- Protect any fine-grained or classic tokens in a GitHub environment to use it in a GitHub Action workflow.