By Nic Wortel
This guide shows how you can use GitHub's fine-grained personal access tokens with Composer to securely download public and private packages from GitHub.
In this guide
When using Composer (the dependency manager for PHP) to download packages from GitHub you might run into situations where you need to authenticate to the GitHub API, for example because you are exceeding GitHub rate limits for unauthenticated requests or because you are trying to download private packages maintained by yourself or your organization. Instead of using your GitHub username and password to authenticate, which give full control over your GitHub account, you should be using a personal access token (PAT), a randomly generated secret token that is tied to your GitHub account but only grants limited access to your account.
Traditionally, you would generate a personal access token with a set of scopes to define the access granted to an application using the token. If you only needed to circumvent the rate limit for public repositories, it would be enough to generate a token without any scopes. Such a token would allow you to circumvent the public rate limit, without granting any additional access to (private) repositories. However, if you wanted to use the token to also download private Composer packages, you'd have to select the repo
scope to allow the token access to private repositories you have access to. That meant that the token didn't just allow you to download the private repository, but would grant full control of all private repositories you can access - including read and write access to the code, commit statuses, collaborators, and webhooks. Much more permissions than we needed to simply download a private package, and a clear violation of the principle of least privilege.
In 2022 GitHub introduced fine-grained personal access tokens. As the name implies, these allow much more fine-grained control over the granted permissions than the classic personal access tokens. Instead of selecting broad scopes that apply to your whole GitHub account and all repositories you have access to, you can now choose whether the token should allow access to your personal repositories or to a specific organization, and you can limit the repositories the token has access to (only public repositories, all repositories, or selected repositories), the level of access (read-only or read & write access), and the specific permissions to permit access to (such as repository contents, metadata, issues, etc.).
In order to generate a fine-grained personal access token, go to Fine-grained tokens (under Developer settings) and click on Generate new token.
It's a good idea to give the token a recognizable name and description so that you can determine its use in the future. As fine-grained tokens are scoped to either your personal account or to an organization you're a member of, you will need to select the Resource owner accordingly. This is only necessary if you want to download private packages, as tokens can always access public repositories.
It is recommended to give the token an expiration date, which will ensure that a leaked token can only be used for a limited amount of time. Note that this means that you will need to regenerate the token after its expiration date.
If you only use Composer to install public packages from public GitHub repositories, you can create a token with the default repository access (Public repositories) and no additional permissions:
If you also want to install private Composer packages hosted on GitHub, you will need to grant the token access to private repositories. To do so, use this link to create a new token with the required settings pre-configured or manually set Repository access to either All repositories or Only select repositories and add the Contents repository permission with Read-only access.
Don't forget to select the correct resource owner depending on whether the private repositories are owned by your personal account or by an organization.
Finally, click on the green Generate token button to generate the token. You will see the token, which starts with github_pat_
, on the screen. Copy it now, because this is the only time GitHub will show it to you and you'll have to regenerate it if you lose it.
Now you can store the generated token in Composer as described in the Composer documentation:
composer config --global github-oauth.github.com <token>
This will create or update a file named auth.json
in your Composer home directory.
If you have lost a token or when a token has expired, you will have to regenerate it. To do so, go to the list of fine-grained tokens, click on the name of the token you want to regenerate, and click on the Regenerate token button. After regenerating the token, copy it and store the token in Composer again:
composer config --global github-oauth.github.com <token>
As tokens can only be linked to a single resource owner, you cannot use a single token to download private repositories from both your personal account and an organization or from multiple organizations. If you want to use Composer to download private packages from different resource owners you will need to create separate fine-grained access tokens for each resource owner and store them locally in your Composer projects by running the composer config
command without the --global
flag. This will store the token in a file named auth.json
in your project, so make sure that you add this file to your .gitignore
to avoid accidentally committing it to Git!
Organization owners can apply policies to control the use of fine-grained and classic tokens. In the organization settings, under Thirt-party access, there is a new section Personal access tokens where organization owners can allow or restrict access via personal access tokens, and optionally require approval before a fine-grained personal access token can be used to access resources within the organization. Organization owners can also enforce here that personal access tokens with access to their organization have an expiration date, and set a maximum lifetime for tokens.
From a security perspective, it is a good idea to allow the use of fine-grained personal access tokens within your organization as they are the most secure way to grant Composer access to private packages. Additionally, it's a good idea to enforce expiration of the tokens with a maximum lifetime which is neither too long nor too short.
Are you looking to implement Composer or GitHub in your project or team? As a PHP consultant I can save you time and money by guiding you through the process and helping you avoid costly mistakes.