100% off usage fees for 3 months with code “BLACKFRIDAY100”

Guide

Composer license keys explained

How license keys work with Composer: auth.json, HTTP Basic authentication, CI with COMPOSER_AUTH, version limits, expiry and rotating a leaked key.

Last updated

When you buy a commercial PHP package, the vendor usually gives you a license key and asks you to add a private repository to Composer. This guide explains what that key does, how Composer sends it, and how vendors use it to control access.

How Composer authenticates with a private repository

Composer supports several authentication methods for private repositories. Most licensed packages use HTTP Basic authentication: the username is your email address (or a fixed value the vendor gives you) and the password is your license key.

You add the repository and credentials once per project:

composer config repositories.acme composer https://acme.privato.pub/composer
composer config --auth http-basic.acme.privato.pub "[email protected]" "YOUR-LICENSE-KEY"

The first command adds the repository to composer.json. The second writes the credentials to auth.json, keyed by the repository's hostname:

{
    "http-basic": {
        "acme.privato.pub": {
            "username": "[email protected]",
            "password": "YOUR-LICENSE-KEY"
        }
    }
}

From then on, Composer sends those credentials with every request to that host, and composer require and composer update work as normal.

Using a license key in CI and deployments

Don't commit auth.json. In CI, store the key as a secret and pass it through the COMPOSER_AUTH environment variable, which takes the same JSON:

export COMPOSER_AUTH='{"http-basic":{"acme.privato.pub":{"username":"[email protected]","password":"YOUR-LICENSE-KEY"}}}'
composer install --no-dev

Laravel Forge, GitHub Actions, GitLab CI and most other platforms let you set it as a secret environment variable.

What a license key controls

Behind the key, the repository decides what to show you. A well-designed licensing system can:

  • Limit packages. A key only lists the packages its owner bought.
  • Limit versions. A key for version 2 sees 2.x releases but not 3.0, using a constraint such as ^2.0.
  • Limit time. A key that includes a year of updates only sees releases published during that year.
  • Limit stability. Beta testers can see pre-release versions that other customers can't.

In Privato these rules come from the license's release channel. When a license expires, the channel either revokes access or restricts it to releases published before the expiry date, so customers who stop paying keep a working project.

Why every customer needs their own key

A single shared password, which is how many self-hosted Satis setups work, can't tell customers apart. You can't see who installed what, you can't limit one customer to older versions, and revoking one customer means changing the password for everyone. Per-customer keys solve all three. See Licensing for how Privato creates and manages them.

Rotating a leaked key

License keys sometimes end up in a public repository or a shared CI log. With Privato, customers can roll their key from the customer portal. The old key stops working immediately and they update auth.json with the new one.

License keys for npm packages

The same idea works for JavaScript. npm reads credentials for a private registry from .npmrc, and Privato accepts the same email address and license key for npm packages, encoded for npm's _auth setting.

Selling a package with license keys

If you're on the other side and want to sell your own package, Privato creates a license key for every Stripe purchase and emails it to the customer. Read how to sell Composer packages to get started.

Frequently asked questions

Where does Composer store license keys?

In auth.json. Running composer config --auth writes to the auth.json in your project, and adding --global writes to the one in your Composer home directory. Composer also reads credentials from the COMPOSER_AUTH environment variable.

Should I commit auth.json?

No. auth.json contains secrets, so add it to .gitignore and use the COMPOSER_AUTH environment variable or your CI provider's secrets in pipelines.

What happens when a license key expires?

That depends on the vendor. In Privato, each release channel decides: either the key stops working, or it keeps working but only for versions released before the license expired.

What should I do if a license key leaks?

Rotate it. In Privato, customers can roll a new key from the customer portal, and the old key stops working immediately.

Ready to start shipping your private packages?

Sign up and give it a try.

Sign up for free