Skip to content

Composer

The proxy implements the Composer repository protocol, so any client that speaks it can install through ShieldedStack.

Endpoint: <proxy-url>/composer

Authentication: the API key, sent as the password in HTTP basic auth. The username is not checked; _ is the conventional placeholder.

Composer is the one ecosystem where the registry does not host the packages. Packagist stores metadata and points at the code host, normally a GitHub archive URL, and Composer downloads from there. The proxy rewrites those archive URLs into its own namespace so downloads are policy-checked like every other ecosystem, and it removes the source entry that Composer would otherwise clone from when a download fails.

Terminal window
composer config repositories.shieldedstack composer <proxy-url>/composer
composer config repositories.packagist.org false

The second command is the half that matters. With Packagist still enabled, Composer can satisfy any package from either source and the proxy is advisory only.

Disabling Packagist governs what Composer resolves. It does not retroactively govern what is already written down, and it does not cover repositories declared separately. For strict enforcement, all three have to hold:

  1. Regenerate the lock file through the proxy. An existing composer.lock already contains dist and source URLs pointing straight at GitHub, and composer install uses those verbatim without consulting any repository. Delete composer.lock and run composer update once with the proxy configured, then commit the result. Until that happens, installs bypass the proxy entirely and nothing appears in the Control Plane.
  2. Remove or vet other repository entries. vcs, git, package, path, and artifact repositories in composer.json resolve on their own and never reach the proxy. Composer has no setting that forces them through it, so enforcement here is a review rule, not a configuration.
  3. Do not use --prefer-source. Covered under Troubleshooting below.

Credentials go in auth.json rather than composer.json:

Terminal window
composer config --auth http-basic.<proxy-host> _ YOUR_API_KEY_HERE

For CI, set the whole auth block as an environment variable instead of writing a file:

Terminal window
export COMPOSER_AUTH='{"http-basic":{"<proxy-host>":{"username":"_","password":"'"${SHIELDEDSTACK_API_KEY}"'"}}}'

Over plain HTTP, or against a self-signed certificate, add composer config secure-http false for the former and install the CA for the latter. Prefer installing the CA.

The repositories block in composer.json is shareable and should be committed, since it is what points the whole team at the proxy. auth.json holds the API key and must not be. Add it to .gitignore, or use COMPOSER_AUTH in CI so no file is written.

composer.lock records the proxy’s archive URLs, which is expected and is what makes the lock file itself enforcing. It also means a checkout without proxy access cannot install from that lock file, so CI runners need the same credentials as developer machines.

Terminal window
composer require monolog/monolog

The installed packages appear under Packages in the Control Plane, attributed to the project name on the API key.

composer install --prefer-source bypasses the proxy. Expected, and it is the reason the proxy strips source from metadata. A lock file written through the proxy has no source URL to clone, so --prefer-source fails rather than silently fetching from GitHub. A lock file written before the proxy was configured still carries its original source URLs and will clone from them, which is why step 1 above matters. Use --prefer-dist, which is the default.

A package fails with “Could not resolve an upstream archive”. The package is hosted somewhere other than GitHub, which the proxy does not serve today, or Packagist has re-published that version against a different commit than the one in your lock file. Run composer update <vendor>/<package> to pick up the current reference.

composer audit reports nothing. Expected. The proxy removes Packagist’s advisory API from the repository configuration because it is served from a host the proxy does not forward to. Advisory enforcement happens in the proxy itself and the results are in the Control Plane.

Check what Composer thinks is configured. composer config --list shows the merged configuration, including which repositories are active.

Stale metadata. composer clear-cache.