packagist icon indicating copy to clipboard operation
packagist copied to clipboard

Add support for PURL (Package URL)

Open valentijnscholten opened this issue 11 months ago • 2 comments

More and more tools use PURL to identify packages in a standardized way.

A purl or package URL is an attempt to standardize existing approaches to reliably identify and locate software packages.

A purl is a URL string used to identify and locate a software package in a mostly universal and uniform way across programming languages, package managers, packaging conventions, tools, APIs and databases.

Such a package URL is useful to reliably reference the same software package using a simple and expressive syntax and conventions based on familiar URLs.

Check also this short purl presentation (with video) at FOSDEM 2018 https://fosdem.org/2018/schedule/event/purl/ for an overview.

It's heavily used in SBOMs and SCA tooling. An example tool is Dependency Track. Currently it's based around official standards, and only supports PURL (or CPE) to idenfity packages. So currently it doesn't index vulnerabilities from packagist (or specific repository instances such as https://packages.drupal.org/files/packages/8.

The request here is to support PURLs in packagist composer respositores. Use cases / features affected by this based on my limited knowledge of the ecosystem (not exhaustive):

  • Allow metadata retrieval by PURL, i.e. GET https://repo.packagist.org/p2/<PURL>
  • Return PURL in metadata responses
  • List vulnerabilities by PURL, i.e. GET https://packagist.org/api/security-advisories/?&packages[]=[<PURL>]

Is this something that could be considered?

valentijnscholten avatar Dec 15 '24 18:12 valentijnscholten

Adding support for PURL on packagist.org alone seems doable. However, I'm wondering what how this should look like when consider the whole composer ecosystem. A package name and its version is not sufficient to uniquely identify a package, when considering custom repositories. Nothing forbids repositories to reuse the same package name or version for different packages, as long as they are not registered at the same time in a project (if you register both packages and the first one is not registered as canonical, weird things will happen due to the "conflicting" definitions). And this case is not theoretical. Drupal relied on that to provide separate repositories for Drupal 7 and for Drupal 8+, because in the past, packages were dual-versioned based on the supported Drupal major version and their own semver version. But on the other hand, some repositories are mirroring packages from packagist.org, and this should probably not change their PURL to properly keep it associated to security advisories.

stof avatar Dec 16 '24 11:12 stof

@stof the first part is covered by the repository_url query param e.g.

pkg:docker/customer/dockerimage@sha256:244fd47e07d1004f0aed9c?repository_url=gcr.io

Though can't find any info though about how package mirroring would be displayed.

glaubinix avatar Dec 16 '24 12:12 glaubinix

I don't think we really need mirroring info to be in the package.. It's still the same package after all. So adding a repository_url qualifier sounds good enough to me.

https://github.com/package-url/packageurl-php has some examples like pkg:composer/symfony/[email protected]?vcs_url=git+https://github.com/symfony/[email protected]

That seems like a reasonable usage to me. For the drupal case with multiple versions maybe the solution would also be to have a ?drupal_version=8 qualifier or something, then you can refer to those specifically in advisories if needed.

Anyway outputting a PURL on the package page sounds reasonable, adding one in the metadata at the top level perhaps, but I'd rather not have one new field per version, that seems overkill and you can just take the package's PURL + add the /version to it if you want a version specific PURL, right? But TBH I am not so sure I see even the point of adding it there, given it is really easy to construct yourself.

Adding metadata / security advisories retrieval by purl also sounds doable altho not really a huge fan as that is even more API surface we need to maintain, cache, etc. I don't really see a huge need nor benefit consider you'd anyway already need to know that for pkg:composer/foo/bar you need to talk to packagist.org/p2/.. then at that point you might as well extract the foo/bar and pass it to us, it's just a tiny bit more work.

For advisories I would say why not add support for it on our end as that is already served by php code, there it adds very little maintenance cost.

Seldaek avatar Aug 28 '25 14:08 Seldaek

See https://github.com/composer/packagist/pull/1574 - happy to get feedback on this..

Seldaek avatar Aug 28 '25 15:08 Seldaek