Use the purl type that matches where the library actually came from. A Conan package gets the conan type, a vcpkg port gets vcpkg, a distribution package gets deb, rpm or apk, a source tree pinned from a repository can use github, and anything else falls back to generic. Never invent a type.
Why C and C++ is awkward
Most ecosystems have one registry and one identifier scheme. C and C++ have several package managers, operating system packages and plain source copies, often in the same product. A single SBOM may need all of them.
The package URL specification keeps an index of registered types. The index includes conan, vcpkg, generic, github, deb, rpm and apk, so a recognised type exists for each common source of a native library.
Decision table
| Where the library came from | Type |
|---|---|
| Conan package | conan |
| vcpkg port | vcpkg |
| Operating system package on Debian family | deb |
| Operating system package on a Red Hat family distribution | rpm |
| Alpine package in a container image | apk |
| Source pinned from a public repository on GitHub | github |
| Vendored source, downloaded archive or anything unlisted | generic |
If you are new to the format, what is a purl explains the parts.
Rules that save trouble
- Describe the source you consumed, not the upstream project's other channels. A library installed from an OS package is a deb or rpm component with the distribution's version string, even if upstream is on GitHub.
- Keep the version string exactly as that channel reports it. Distribution versions often carry a suffix for the distribution's own patches.
- Use generic only when nothing else fits, and add extra data (a download location or a checksum) so the component can still be matched.
- Use one identifier per component. If the same library is present twice from two sources, list both and say which one the binary links.
Why this matters for matching
Advisories are published against particular identifiers. A component with a wrong type may match nothing, or match the wrong package. A distribution may also have fixed an issue under a version that looks old, which is why the distribution type matters. See fixed version or backported fix.
Scanners differ in how they treat generic components, so test with a known vulnerable library and check what your tooling reports.
Try it yourself
Open the demo and look at how each component carries a name and version. Imagine each row with the right type attached.
Click through it at your own pace, or open it full screen.
Quick check
Is there one purl type for all C++ libraries?
No. Pick the type for the channel you used: conan, vcpkg, an operating system type, github or generic.
When is generic acceptable?
When no registered type fits, for example a copied source tree. Add a location or checksum to keep it matchable.
Safeguard's SBOM and dependency scanning can build an inventory of the components in a repository, and the free scan at gold.safeguard.sh/scan is a quick way to see what turns up.
Sources
Last reviewed: 19 October 2026.