Model and serializations
Overview
This document defines the data model of the SPDX standard, describing every piece of information about systems with software components. The data model is based on the Resource Description Framework (RDF) extensible knowledge representation data model, which provides a flexible and extensible way to represent and exchange information.
The data may be serialized in a variety of formats for storage and transmission.
RDF serialization
Since the data model is based on RDF, any SPDX data can be serialized in any of the multiple RDF serialization formats, including but not limited to:
- JSON-LD format as defined in JSON-LD 1.1;
- Turtle (Terse RDF Triple Language) format as defined in RDF 1.1 Turtle;
- N-Triples format as defined in RDF 1.1 N-Triples; and
- RDF/XML format as defined in RDF 1.1 XML Syntax.
The SPDX specification is accompanied by a JSON-LD context definition file that can be used to serialize SPDX in a much simpler and more human-readable JSON-LD format.
Namespace and IRIs
SPDX data can be serialized in RDF. This can be saved in a variety of formats, like XML, JSON-LD, Turtle, etc.
-
The namespace for SPDX is
https://spdx.org/rdf/3/terms -
IRIs for a namespace/profile are of the form:
https://spdx.org/rdf/3/terms/{Namespacename} -
IRIs for a class are of the form:
https://spdx.org/rdf/3/terms/{Namespacename}/{Classname} -
IRIs for a property are of the form:
https://spdx.org/rdf/3/terms/{Namespacename}/{Propertyname} -
IRIs for a vocabulary (an enumerated value list) are of the form:
https://spdx.org/rdf/3/terms/{Namespacename}/{Vocabularyname} -
IRIs for an enumerated value are of the form:
https://spdx.org/rdf/3/terms/{Namespacename}/{Vocabularyname}/{Entryname} -
IRIs for an individual value are of the form:
https://spdx.org/rdf/3/terms/{Namespacename}/{Individualname}
Please note that entries appearing in the SPDX License List are not under this namespace.
Resources
For a minor version X of the SPDX spec:
-
The ontology is available at:
https://spdx.org/rdf/3.X/spdx-model.ttl -
The JSON-LD serialization annotations file is available at:
https://spdx.org/rdf/3.X/spdx-json-serialize-annotations.ttl -
The JSON-LD context definition is available at:
https://spdx.org/rdf/3.X/spdx-context.jsonld -
The JSON schema is available at:
https://spdx.org/schema/3.X/spdx-json-schema.json
Canonical serialization
Canonical serialization is a single, consistent, normalized, deterministic, and reproducible form.
Such a canonical form normalizes things like ordering and formatting.
The content of the canonical serialization is exactly the same as the JSON-LD serialization of RDF data, just represented in a consistent way.
Canonical serialization is in JSON format, as defined in RFC 8259 (IETF STD 90), with the following additional characteristics:
- No line breaks
- Key names shall be wrapped in double quotes
- No whitespace outside of strings
true,falseandnull: the literal names shall be lowercase; no other literal names are allowed- Integers: represented in base 10 using decimal digits. This designates an integer component that may be prefixed with an optional minus sign. Leading zeros are not allowed.
- Strings: UTF-8 representation without specific normalization. A string begins and ends with quotation marks (%x22). Any Unicode characters may be placed within the quotation marks, except for the two characters that shall be escaped by a reverse solidus: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F).
- Arrays: An array structure is represented as square brackets surrounding zero or more items. Items are separated by commas.
- Objects: An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string containing only ASCII characters (0x21-0x7F). The names within an object shall be unique. A single colon comes after each name, separating the name from the value. A single comma separates a value from a following name. The name/value pairs are ordered by name.
Serialization information
A collection of elements may be serialized in multiple formats.
An SpdxDocument element represents a collection of elements across all serialization data formats within the model.
The actual serialized bytes is represented by an Artifact element within the model.
A Relationship of type serializedInArtifact links an SpdxDocument to one or more serialized forms of itself.
When serializing a physical SpdxDocument, any property of the logical element
that can be natively represented within the chosen serialization format
(e.g., @context prefixes in JSON-LD instead of the namespaceMap) may utilize
these native mechanisms. All remaining properties shall be serialized within
the SpdxDocument element itself.
A serialization shall not contain more than one SpdxDocument.
A given instance of serialization shall not define more than one SpdxDocument element.
Serialization in SPDX 3 JSON
A strict subset of JSON-LD
The SPDX 3 JSON format is a strict subset of JSON-LD. It requires data to be serialized according to the defined serialization specification and validated against the SPDX 3 JSON Schema. It may be parsed – not serialized – using standard JSON-LD libraries.
SpdxDocument
The following SpdxDocument properties are mapped to native JSON-LD mechanisms defined within the JSON-LD syntax specifications. Any properties not listed below should be serialized as part of the SpdxDocument element itself within the JSON-LD serialized data.
Deserialization of any JSON-LD serialized SPDX content MUST expand the inverse of these native mappings such that the logical SpdxDocument element directly contains its full set of properties.
namespaceMap
The namespaceMap uses the term to IRI mapping in the JSON-LD context.
element
The graph objects @graph
lists the elements for the SpdxDocument.
The RDF graph of an instance of the SPDX model shall contain all Element nodes (i.e. objects that are subclasses of Element) as a list on top-level under the "@graph" key. This means that all references to Element nodes have to use the URI of the referenced Element.
Inlining/Embedding of Element nodes into other nodes is not allowed.
Non-element data (like those of type "ExternalReference" or similar complex data classes) may be inlined or included as a blank node on top-level under the "@graph".
JSON-LD serialization annotations
To assist implementers in developing software bindings and serialization tooling, a serialization annotations file is provided. While the core RDF model defines the semantic data relationships, this file provides supplementary metadata to guide how specific elements should be structured in code and subsequently serialized.
For example, the annotations are used to instruct serialization logic to:
- Map logical identifier properties of core model elements to specific JSON-LD field names.
- Flag designated extension classes as extensible, indicating that software implementations should permit the inclusion of custom or arbitrary properties.
The SPDX JSON-LD serialization annotations file is available at: https://spdx.org/rdf/3.1/spdx-json-serialize-annotations.ttl
JSON-LD context file
JSON-LD contexts allow JSON documents to use simple, human-readable, locally defined terms while ensuring data interoperability across different systems.
The SPDX global JSON-LD context file shall be used universally for all SPDX documents in JSON-LD format that adhere to a specific SPDX version.
SPDX global JSON-LD context file is available at: https://spdx.org/rdf/3.1/spdx-context.jsonld
All SPDX documents in JSON-LD format shall include a reference to the SPDX global context file at the top level. This reference is achieved using the following JSON construct:
{ "@context": "https://spdx.org/rdf/3.1/spdx-context.jsonld" }
The SPDX context file defines aliases for specific JSON-LD properties to improve compatibility with the SPDX model. These aliases are:
spdxId: An alias for the@idproperty.type: An alias for the@typeproperty.
Additional namespace mappings may be defined within a separate object within the context.
JSON-LD validation
An SPDX serialization in JSON-LD format is considered conformant to the SPDX specification if it adheres to the following two validation criteria:
- Structural validation: The JSON-LD document shall structurally validate against the SPDX 3 JSON Schema. This schema defines the expected structure of the JSON-LD document, including the required elements, data types, and permissible values.
- Semantic validation: The JSON-LD document shall successfully validate against the SPDX 3 OWL ontology. This ontology defines the expected relationships and constraints between SPDX elements. The SPDX 3 OWL ontology also incorporates SHACL shape restrictions to further specify these constraints.
The SPDX 3 JSON Schema is available at: https://spdx.org/schema/3.1/spdx-json-schema.json
The SPDX 3 OWL ontology is available at: https://spdx.org/rdf/3.1/spdx-model.ttl
Examples
Informational JSON-LD serialization examples can be found at: https://github.com/spdx/spdx-examples
Reading JSON serialization
Parsing JSON-LD as JSON
This is a description of how to deserialize JSON-LD as a pure JSON format without any knowledge of RDF. On top-level, JSON-LD has two keys, "@context" and "@graph".
Parsing "@context"
The context is a list of a string and an object. You can ignore the string. The object consists of key-value pairs that allow the shortening of IDs and which we will call "namespace map" in the following.
For deserialization purposes, follow this process:
- For every string that is an ID (that includes values of the keys "spdxId" and "@id", as well as all strings where you would expect objects according to the SPDX 3 model), split that string at the first colon into "prefix:suffix".
- If the suffix does not start with "//" and the prefix is a key in the namespace map, replace "prefix:" with the value found under that key in the namespace map.
- Else do nothing to that string.
After you are done applying this process to all IDs, you can ignore the "@context".
Parsing "@graph"
You will find an array of objects under the "@graph" key. Every one of these objects has a "type" key that tells you the class of the SPDX 3 model that the object is an instance of. The rest of the keys then correspond to the properties of that SPDX class. Take special note of the "spdxId" key which specifies the ID by which the object can be referenced from other places.
One thing to note is that not all objects in that list have to be subclasses of Element. As only Elements have an spdxId, there is no "spdxId" key in these cases but an "@id" key. However, the value of "@id" serves the same function of identifying and referencing that object from within other objects.
Last but not least, whenever you encounter a string where you would expect an object according to the SPDX 3 model, you can substitute that string with the object that has that string as its "spdxId" or "@id".
File naming
It should be easy to recognize an SPDX 3 file in a file system without opening the file.
A suggested naming convention is:
| Format | Extension |
|---|---|
| JSON-LD | *.spdx3.json |
| RDF/XML | *.spdx3.rdf |