Each PURL type definition (types/<type>.json, ECMA-427 Clause 6) currently documents two characteristics of a type:
- Identification — the
namespace/name/version definitions and qualifiers list: how a purl of this type is structured.
- Resolution (optional) — the
repository object: how a purl of this type can be resolved to a location to retrieve the package.
Proposal
Add a third, optional characteristic: self-identification — whether, and how, a package of this type can declare its own purl inside its native metadata/manifest, so the purl can be recovered directly from the artifact without external registry or build-time context.
It matters increasingly for supply-chain tooling — SLSA provenance, VEX, and SBOMs all use PURL as a subject identifier, but nothing today lets a verifier check "does the artifact agree with what the attestation claims it is?" directly against the artifact itself.
Concretely, this would be a new self_identification object in the type JSON Schema, structured like the existing repository object:
"self_identification": {
"type": "object",
"properties": {
"supported": {
"type": "boolean",
"description": "Whether this type has a documented convention for a package to declare its own purl in its native metadata."
},
"documentation": {
"type": "array",
"items": { "type": "string", "format": "uri" },
"description": "Official or semi-official documentation of the manifest format referenced above (mirrors the documentation field proposed for repository in #<link>)."
},
"note": { "type": "string" }
}
}
Two examples to establish this is workable, not exhaustive — full ecosystem coverage is explicitly out of scope for this issue (see below):
maven: META-INF/MANIFEST.MF already tolerates arbitrary headers, so a Purl: header fits the same slot as Implementation-Version.
npm: package.json tolerates unknown top-level keys, so a bare "purl" key fits alongside name/version.
Not every type will have an equally natural fit — some have closed schemas that need a nested extension point (Cargo's [package.metadata]), and some have no natural fit at all (golang, where the module path already serves as the identifier). That variation is exactly why per-type population belongs in separate issues rather than this one.
Scope of this issue
This issue is only about introducing the axis and its schema shape. Once (if) that's agreed, populating self_identification for each registered type — deciding manifest/field/documentation per ecosystem, which in
several cases will involve real debate (see the closed-schema and reserved-namespace cases above) — should happen as separate, per-type issues so each can be reviewed on its own merits rather than as one large PR.
Each PURL type definition (
types/<type>.json, ECMA-427 Clause 6) currently documents two characteristics of a type:namespace/name/versiondefinitions andqualifierslist: how a purl of this type is structured.repositoryobject: how a purl of this type can be resolved to a location to retrieve the package.Proposal
Add a third, optional characteristic: self-identification — whether, and how, a package of this type can declare its own purl inside its native metadata/manifest, so the purl can be recovered directly from the artifact without external registry or build-time context.
It matters increasingly for supply-chain tooling — SLSA provenance, VEX, and SBOMs all use PURL as a subject identifier, but nothing today lets a verifier check "does the artifact agree with what the attestation claims it is?" directly against the artifact itself.
Concretely, this would be a new
self_identificationobject in the type JSON Schema, structured like the existingrepositoryobject:Two examples to establish this is workable, not exhaustive — full ecosystem coverage is explicitly out of scope for this issue (see below):
maven:META-INF/MANIFEST.MFalready tolerates arbitrary headers, so aPurl:header fits the same slot asImplementation-Version.npm:package.jsontolerates unknown top-level keys, so a bare"purl"key fits alongsidename/version.Not every type will have an equally natural fit — some have closed schemas that need a nested extension point (Cargo's
[package.metadata]), and some have no natural fit at all (golang, where the module path already serves as the identifier). That variation is exactly why per-type population belongs in separate issues rather than this one.Scope of this issue
This issue is only about introducing the axis and its schema shape. Once (if) that's agreed, populating
self_identificationfor each registered type — deciding manifest/field/documentationper ecosystem, which inseveral cases will involve real debate (see the closed-schema and reserved-namespace cases above) — should happen as separate, per-type issues so each can be reviewed on its own merits rather than as one large PR.