gromnan / composer-keychain-auth
Store Composer authentication credentials in the system keychain (macOS Keychain or Linux Secret Service) instead of an auth.json file
Package info
github.com/GromNaN/composer-keychain-auth
Type:composer-plugin
pkg:composer/gromnan/composer-keychain-auth
Requires
- php: ^7.4 || ^8.0
- composer-plugin-api: ^2.8
Requires (Dev)
- composer/composer: dev-feature/auth-provider-capability
- friendsofphp/php-cs-fixer: ^3.59
- phpstan/phpstan: ^2.1
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^9.6
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Store your Composer authentication credentials in the
system keychain instead of a plain text auth.json file.
Supported stores:
- macOS Keychain, through the
/usr/bin/securitycommand - Linux Secret Service (libsecret), through the
secret-toolcommand
Why
Composer stores credentials for private package repositories, GitHub, GitLab,
Bitbucket and Forgejo in ~/.composer/auth.json. These files hold plain text
tokens and passwords. This plugin moves that data into the encrypted keychain of
the machine, so no secret ever sits on disk in the clear.
Installation
Install the plugin globally so every Composer command uses it:
composer global require gromnan/composer-keychain-auth
Add the plugin package to the allow-plugins list of your global Composer
configuration if Composer asks for permission.
Usage
Migrate an existing auth.json into the keychain, then remove the file:
composer keychain:import --delete
Store a credential:
composer keychain:add http-basic packages.example.org
composer keychain:add github-oauth github.com ghp_xxxxxxxxx
Once a credential is stored, running composer install or composer update
uses it transparently, without prompting and without writing any auth.json.
Manage the stored credentials:
composer keychain:list
composer keychain:remove http-basic packages.example.org
composer keychain:clear --yes
composer keychain:export --file auth.json
If several developers share a machine, or you need to move credentials to
another machine, composer keychain:export writes a standard auth.json that
plain Composer can read.
How it works
Write path
At plugin activation the Config auth sources of Composer are replaced with a
ConfigSourceInterface implementation that persists in the keychain. Every
credential write goes through those sources: the interactive prompt storage in
AuthHelper, and the GitHub, GitLab, Bitbucket and Forgejo OAuth flows. The
default store-auths setting is kept as-is, persistence simply lands in the
keychain.
When Composer prompts for a login interactively, for example a GitHub token,
the token is validated by Composer and then stored directly in the keychain
through those same sources. No auth.json file is written.
Read path
When running on a Composer version with the AuthenticationProvider capability, the plugin provides that capability and credentials are fetched from the keychain on demand.
On Composer versions before that capability, the plugin falls back to preloading every keychain credential into the Composer IO instance at activation. Both paths cover HTTP downloads, dist archives and git clone operations.
Credentials are stored per host origin as the exact per-origin values Composer
would read from an auth.json, keyed under the service composer-auth with the
origin as account.
Precedence
Credentials are resolved in this order, from highest to lowest priority:
COMPOSER_AUTHenvironment variable- project
auth.json - global
auth.json - system keychain
- nothing, Composer prompts interactively
Because auth.json files are read before plugins activate, a reversed
auth.json still wins over the keychain. Use composer keychain:import --delete
after migrating to avoid this.
Known limitations
composer config --auth --globalwrites the globalauth.jsonfile directly, bypassing the plugin. Use thekeychain:*commands for writes instead.- The first installation of a private repository, which is needed to download
and activate the plugin itself, still requires an
auth.json. Import it withcomposer keychain:importonce the plugin is active. - The keychain may prompt once to authorize access. In CI, unlock the keychain
once beforehand, for example with
security unlock-keychain.
Development
This repository is under development against the
AuthenticationProvider capability PR.
Its dev composer/composer dependency is resolved from the
user fork repository declared in
composer.json, which carries the capability branch. After the PR is merged
into Composer, switch the require-dev constraint back to a released
composer/composer version.
composer install
composer test
composer phpstan
composer cs
The integration tests touch the real keychain and are opt-in:
KEYCHAIN_INTEGRATION=1 vendor/bin/phpunit --testsuite Integration