Skip to main content

Composer Protocol

Cargoman implements the Composer Repository Protocol v2 for seamless integration with the Composer client.

Endpoints

Package Index

GET /packages.json

Returns the repository metadata:

{
"packages": {},
"metadata-url": "/p2/%package%.json",
"providers-lazy-url": "/p/%package%.json"
}

Package Metadata (v2)

GET /p2/{vendor}/{package}.json

Returns package metadata for a specific package:

{
"packages": {
"vendor/package": [
{
"name": "vendor/package",
"version": "2.0.0",
"version_normalized": "2.0.0.0",
"dist": {
"type": "zip",
"url": "https://packages.example.com/dist/vendor/package/2.0.0.zip",
"shasum": "abc123..."
},
"require": {
"php": ">=8.1"
},
"autoload": {
"psr-4": {
"Vendor\\Package\\": "src/"
}
}
}
]
}
}

Package Archive

GET /dist/{vendor}/{package}/{version}.zip

Returns the package archive (zip file).

Security Advisories

GET /security-advisories.json
GET /api/security-advisories/{vendor}/{package}.json

Returns known security advisories for packages. Integrates with OSV, GitHub Security Advisory, and PHP Security Advisory databases. Available on Pro edition and higher.

Proxy Archive (Packagist Mirror)

GET /dist-proxy/{vendor}/{package}/{version}/{reference}.zip

Serves cached Packagist archives through the private proxy. Available on Pro edition and higher. See the Packagist Proxy guide for configuration.

Custom Response Headers

Cargoman includes bandwidth and storage tracking headers on archive downloads:

HeaderDescription
X-Bandwidth-UsedBandwidth consumed this month (bytes)
X-Bandwidth-LimitMonthly bandwidth limit (bytes, 0 = unlimited)
X-Storage-UsedStorage consumed (bytes)
X-Storage-LimitStorage limit (bytes, 0 = unlimited)

Authentication

Composer uses HTTP Basic Auth. Configure your credentials:

composer config http-basic.packages.example.com token YOUR_TOKEN

Or in auth.json:

{
"http-basic": {
"packages.example.com": {
"username": "token",
"password": "YOUR_TOKEN"
}
}
}

Repository Configuration

Add Cargoman as a Composer repository:

{
"repositories": [
{
"type": "composer",
"url": "https://packages.example.com"
}
]
}

Or via CLI:

composer config repositories.cargoman composer https://packages.example.com

Priority

To prefer your private packages over Packagist:

{
"repositories": [
{
"type": "composer",
"url": "https://packages.example.com"
},
{
"packagist.org": false
}
]
}

Access Control

The Composer endpoints enforce customer access:

  • Only packages granted to the customer are visible
  • Version constraints are enforced (e.g., ^2.0 only shows 2.x versions)
  • Frozen customers only see their frozen versions
  • Suspended/expired customers receive 403 errors
  • Token package scopes further restrict visibility

Error Responses

401 Unauthorized

composer install

[Composer\Downloader\TransportException]
The "https://packages.example.com/packages.json" URL could not be
accessed: HTTP/1.1 401 Unauthorized

Solution: Configure authentication credentials.

403 Forbidden

[Composer\Downloader\TransportException]
Access denied to package vendor/package

Solution: Customer doesn't have access to this package, or the token scope doesn't include it.

404 Not Found

[Composer\Downloader\TransportException]
Package vendor/package not found

Solution: Package doesn't exist in the registry.

Caching

Composer caches package metadata. To force a refresh:

composer clear-cache
composer update --prefer-dist

CI/CD Integration

GitHub Actions

- name: Configure Composer
run: |
composer config http-basic.packages.example.com token ${{ secrets.COMPOSER_TOKEN }}

- name: Install dependencies
run: composer install --no-dev --prefer-dist

GitLab CI

before_script:
- composer config http-basic.packages.example.com token $COMPOSER_TOKEN

install:
script:
- composer install --no-dev --prefer-dist

Next Steps