Skip to content

Differences between V3.0 and V2.3

SPDX meaning

In previous editions of the specification, SPDX meant "Software Package Data Exchange".

Starting with V3.0, the scope of SPDX has expanded beyond software and now means "System Package Data Exchange".

Structural Differences

These are the most significant breaking changes requiring a change in logic to handle a different model or structure for the information.

Each structural difference will describe the change, describe an approach to translate from 2.3 to 3.0, and provide a rationale for the change.

External Document Reference

Description of Change

The purpose of the SPDX 2.3 structure “ExternalDocumentRef” is now covered by two separate structures:

  • NamespaceMap which maps short identifiers used in serializations to full namespace URI’s to support terseness in serialization of element identifiers
  • ExternalMap which maps an element identifier for an element defined externally to verification and location information

The externalDocumentRef property on the SpdxDocument has been replaced by import property and namespace property.

Another change is the SPDX document checksum field has been replaced with a “verifiedUsing” property on the ElementCollection. The “verifiedUsing” which has 0 or more “IntegrityMethod” which should be the checksum of the SPDX document.

Translating from 2.3 to 3.0

Each ExternalDocumentRef instance will translate as follows:

  • An entry would be created in the Namespace map for the external document namespace
  • The value of the DocumentRef-[idstring] would be used for the prefix property in the NamespaceMap.
  • The value of the documentNamespace appended with a “#” would be used for the namespace in the NamespaceMap.
  • An entry would be created in the ExternalMap for the external document ref
  • A string identifier consisting of the DocumentRef-[idstring] (the same value as the prefix in the NamespaceMap) concatenated with a “:” and then concatenated with “SPDXRef-DOCUMENT” would be used for the externalSpdxId in the ExternalMap.
  • An integrity method of “Hash” will be created with the same information as the checksum property and will be referenced using the “verifiedUsing” property on the ExternalMap entry.
  • An entry would be created in the ExternalMap for each element referenced in the current SpdxDocument that is originally specified in the referenced SpdxDocument.
  • A string identifier consisting of the DocumentRef-[idstring] (the same value as the prefix in the NamespaceMap) concatenated with a “:” and then concatenated with the local portion of the element identifier would be used for the externalSpdxId in the ExternalMap
  • A “definingDocument” property would be specified containing a string identifier consisting of the DocumentRef-[idstring] concatenated with a “:” and then concatenated with “SPDXRef-DOCUMENT”. This is a shortcut linkage to tie the referenced element to its defining SpdxDocument for verification and location information.

Rationale

A key difference between SPDX 2.3 and SPDX 3.0 is that in SPDX 2.3 elements are always expressed within or referenced in relation to a single enclosing SpdxDocument while in SPDX 3.0 a key design principle is that all elements may be expressed and referenced independent of any other element including SpdxDocument. This independence is required to support a variety of content exchange and analysis use cases.

For example, in SPDX 2.3 if you wish to express even a single package you specify it within an SpdxDocument and its identifier namespace is restricted to the namespace of the SpdxDocument. In SPDX 3.0 you could specify a single package within an SpdxDocument element (or any other subclass of ElementCollection such as Bundle, Bom, Sbom, etc.) but you could also simply specify it on its own without any enclosing collection element. In addition, in SPDX 3.0 the identifier of the package may share a namespace with an enclosing collection element such as SpdxDocument if desired but it is equally valid for it to have any namespace desired unconstrained by any other element namespace whether it is expressed within a collection element such as SpdxDocument or not.

In this example, in SPDX 2.3 if you referenced the package within the same SpdxDocument that it is defined in you would utilize the local portion of its identifier and presume that the namespace is the same as the SpdxDocument namespace. If you referenced it from an SpdxDocument other than the one it is defined in you would use an ExternalDocumentRef to specify a prefix name for the other SpdxDocument to be used within the current SpdxDocument, the URI namespace/identifier for the other SpdxDocument, and a checksum for the other SpdxDocument. To reference the package you would then use an identifier combining the external document ref prefix and the local portion of the identifier.

The ExternalDocumentRef structure in SPDX 2.3 is based on the presumptions that elements are always defined within SpdxDocuments, that external elements can always be referenced via a containing SpdxDocument and that element identifiers have a namespace from their original containing SpdxDocument. None of these three presumptions hold true for SPDX 3.0 so a slightly modified structure is necessary to support the two use cases previously covered by ExternalDocumentRef in SPDX 2.3: 1) the ability to specify identifier namespace prefixes and accompanying namespaces for SPDX elements to support more terse serialized expression of content with integrity across serialization forms, 2) the ability to specify which elements in the current subclass of ElementCollection (e.g., SpdxDocument) are only referenced from that collection and defined elsewhere, along with details regarding their verification and location.

The Namespace map structure in SPDX 3.0 fully supports the namespace prefixing use case for SpdxDocuments previously covered by ExternalDocumentRef but also equally covers the same use case capability for all element types and for any number of element identifier namespaces (in SPDX 3.0 all elements within an SpdxDocument are not required to have the same namespace and can actually be any desired mix of namespaces) to support this capability required in SPDX 3.0.

The ExternalMap structure in SPDX 3.0 fully supports the external element (including SpdxDocument elements) referencing use case for SpdxDocuments previously covered by ExternalDocumentRef but also equally covers the same use case capability for any elements whether they were originally defined within an SpdxDocument or not to support this capability required in SPDX 3.0.

The ExternalMap structure in SPDX 3.0 provides the ability to specify verification and location details for any element, not just SpdxDocuments, if appropriate but also provides simple linkage, using the “definingDocument” property, from element entries in the ExternalMap to SpdxDocument entries in the ExternalMap where the elements were defined within the SpdxDocument and verification of the elements can be achieved via proxy to the SpdxDocument “verifiedUsing” information (this is how the SPDX 2.3 ExternalDocumentRef structure currently works).

Agent

Description of Change

The creator property in SPDX 2.3 has been replaced by createdBy and createdUsing properties with a type Agent and Tool resp. The supplier property has been replaced by a property suppliedBy with a type Agent. Additional suppliers can be provided with a a relationship to an availableFrom relationship. The originator property type has been replaced with the originatedBy property with a type Agent.

An Agent can be a Person, Organization, or Software Agent. It can also just be an Agent if it is not known what specific type an Agent is.

Translating from 2.3 to 3.0

The SPDX 2.3 creator string would be parsed and the appropriate Person, Organization or Tool would be created depending on if the prefix is “Person:”, “Organization:” or “Tool:” resp. The required createdBy field for Agent or Tool may point to itself if no other information is available. The createdUsing property would be used for Tool whereas the createdBy property would be used for Person and Organization. The name would map to the “name” property. If an email address is present, it would translate to an external identifier.

Note that in 3.0 the createdBy is a required field. There will be situations where only a Tool is provided. In that case, createdBy should point to a SoftwareAgent should be created using the same information as the Tool.

Rationale

The 3.0 format is more machine readable and structured (e.g. you do not need to parse the type from the string value). It is also more flexible in that an Agent can be used even if it is not known what the Agent type is.

File Contributor

Description of Change

The fileContributor property on File has been replaced by the originatedBy property on Artifact.

Translating from 2.3 to 3.0

For each fileContributor string in SPDX 2.3, an Person should be created and added to the originatedBy list for the File artifact.

Rationale

The Artifact property originatedBy should be used to describe file contributor information in place of the fileContributor property.

File Type

Description of Change

The FileType enumeration has been replaced by two fields, the media type string as maintained by IANA for the content of the file and an enumeration of SoftwarePurpose for the purpose of the file.

The property name fileType has been replaced by a property name contentType.

Translating from 2.3 to 3.0

Rationale

One of the things that we identified is that FileType was being used for two things:

  1. Describing the purpose of the file.
  2. Describing the type of content in the file.

For SPDX 3.0 we split this into two properties:

  • SoftwarePurpose to capture the purpose (which is of type SoftwarePurpose).
  • ContentType to capture the type of content (which is of type MediaType).

The name ContentType was chosen to mirror the Content-Type header in HTTP (which is also of type MediaType) and to express that this is describing the type of content (as opposed to metadata, headers, or something else). For example, if (and not saying we would) we extended File in the future to be able to capture the type of executable header a file has (e.g. ELF), that could also be of type MediaType but the property name might be ExecutableHeaderType.

An example conversion table from SPDX 2.3 FileType to SPDX 3.0 contentType or softwarePurpose can look like this:

SPDX 2 File Type SPDX 3 Software Purpose SPDX 3 Content Type
ARCHIVE Archive
BINARY application/octet-stream
SOURCE Source
TEXT text/plain
APPLICATION Application
AUDIO audio/*
IMAGE image/*
VIDEO video/*
DOCUMENTATION Documentation
SPDX text/spdx
OTHER Other

Package File Name

Description of Change

The packageFileName property and packageChecksum property has been replaced by a relationship from a Package to a File. A relationship type of hasDistributionArtifact should be used.

Translating from 2.3 to 3.0

Create an SPDX File with the name from the packageFileName and a verifiedUsing value from the packageChecksum for a single file. If the packageFileName is a directory, then the SPDX File is created with the directory name and is verified using the contentIdentifier property on the File and a fileKind of directory. Create a hasDistributionArifact relationship from the SPDX Package to the SPDX File.

Rationale

Providing a File relationship to the download location will include more detailed and complete information about the package file name used.

External Identifiers

Description of Change

In SPDX 3.0, a properties externalIdentifier and contentIdentifier with types ExternalIdentifier and ContentIdentifier were introduced. This is in addition to retaining the ExternalRef property and classes.

In SPDX 2.3, both identifiers and references were captured in the externalRef property for packages.

In addition to the structural changes, the “url” ExternalRef type was removed and is replaced by the “securityOther” ExternalRef type.

Translating from 2.3 to 3.0

The following ExternalRef Types should be converted to ExternalIdentifiers:

  • cpe22Type
  • cpe23Type
  • swid
  • purl

The following ExternalRef Types should be converted to ContentIdentifers:

  • gitoid
  • swh

All other ExternalRef types should remain as ExternalRef’s.

The url ExternalRef type should be converted to a “securityOther”.

Rationale

Distinguishing identifiers from references is key to several integrity and provenance use cases. Creating a separate property and type enables easier identification of identifiers.

Package URL

Description of Change

In SPDX 3.0, Package URL is a new property for Artifact which is a superclass of Package.

Package URL is an External Ref type in SPDX 2.3.

Translating from 2.3 to 3.0

If there is a single ExternalReference of type purl without the optional ExternalRef comment property, place that in the packageUrl property.

Rationale

Package URL is a very common method of identifying software packages. Moving this to a property makes it significantly simpler to find and correlate Package URL identifiers.

Annotation

Description of Change

Annotations are now subclasses of Element, so it inherits a number of new optional properties including names, annotations, and its own relationships.

Annotations are no longer a property of an Element. It is now a standalone element with a “subject” field which points to the Element being annotated.

Translating from 2.3 to 3.0

A new Annotation element would be created for every annotation property in an element (Package, File or Snippet). The subject property would point to the Element which has the Annotation as a property.

The annotator from SPDX 2.3 should be translated to one of the creators for the creationInfo for the Annotation and the annotationDate should be translated to the created field in the same creationInfo. The creationInfo for the Annotation should be the creationInfo of the SPDX 2.3 document.

The SPDX 2.3 “comment” should use the statement field in SPDX 3.0.

Rationale

Changing from a property to a standalone element allows for relationships to exist outside the element itself (e.g. you can now create an amended SPDX document which has a new annotation for an element defined in the original document). This also supports third parties' ability to assert Annotations on Elements that they did not create.

Relationship

Description of Change

The structure of the Relationship class has changed to have a single direction and allow more than one related SPDX Elements. Relationships are now subclasses of Element, so it inherits a number of new optional properties including names, annotations, and its own relationships.

Relationships are no longer a property of an Element. It is now a standalone element with a “from” and “to” field.

A new property “completeness” complements the use of NONE and NOASSERTION for the related SPDX elements.

Translating from 2.3 to 3.0

The “from” property would be populated by the SPDX Element which has the relationship property. The “to” property will be the relatedSpdxElement.

When translating the relationshipType, the “from” and “to” may need to be swapped - the table below will have a “Y” in the “Swap to and from?” column when this is necessary.

The completeness property would be constructed based on the following:

  • “to” value is NONE: complete
  • “to” value is NOASSERTION: noAssertion
  • “to” value is an SPDX element: No value for the completeness - uses the default

The following table reflects the translation for relationship types from SPDX 2.3 to SPDX 3.0:

SPDX 2.3 Relationship Type SPDX 3.0 Relationship Type Swap to and from? LifecycleScopeType
AMENDS amendedBy Y
ANCESTOR_OF ancestorOf
BUILD_DEPENDENCY_OF dependsOn Y build
BUILD_TOOL_OF usesTool Y build
CONTAINED_BY contains Y
CONTAINS contains
COPY_OF copiedTo Y
DATA_FILE_OF hasDataFile Y
DEPENDENCY_MANIFEST_OF hasDependencyManifest Y
DEPENDENCY_OF dependsOn Y various lifecycle scope
DEPENDS_ON dependsOn various lifecycle scope
DESCENDANT_OF descendantOf
DESCRIBED_BY describes Y
DESCRIBES describes
DEV_DEPENDENCY_OF dependsOn Y development
DEV_TOOL_OF usesTool Y development
DISTRIBUTION_ARTIFACT hasDistributionArtifact
DOCUMENTATION_OF hasDocumentation Y
DYNAMIC_LINK hasDynamicLink Y build, runtime
EXAMPLE_OF hasExample Y
EXPANDED_FROM_ARCHIVE expandsTo Y
FILE_ADDED hasAddedFile Y
FILE_DELETED hasDeletedFile Y
FILE_MODIFIED modifiedBy
GENERATED_FROM generates Y
GENERATES generates
HAS_PREREQUISITE hasPrerequisite various lifecycle scope
METAFILE_OF hasMetadata Y
OPTIONAL_COMPONENT_OF hasOptionalComponent Y
OPTIONAL_DEPENDENCY_OF hasOptionalDependency Y various lifecycle scope
OTHER other
PACKAGE_OF packagedBy Y
PATCH_FOR patchedBy Y
PATCH_APPLIED patchedBy Y
PREREQUISITE_FOR hasPrerequisite Y various lifecycle scope
PROVIDED_DEPENDENCY_OF hasProvidedDependency Y various lifecycle scope
REQUIREMENT_DESCRIPTION_FOR hasRequirement Y various lifecycle scope
RUNTIME_DEPENDENCY_OF dependsOn Y runtime
SPECIFICATION_FOR hasSpecification Y various lifecycle scope
STATIC_LINK hasStaticLink various lifecycle scope
TEST_CASE_OF hasTestCase Y
TEST_DEPENDENCY_OF dependsOn Y test
TEST_OF hasTest Y various lifecycle scope
TEST_TOOL_OF usesTool Y test
VARIANT_OF hasVariant Y

Rationale

The addition of the completeness attribute is clearer than the use of NONE and NOASSERTION.

Changing from a property to a standalone element allows for relationships to exist outside the element itself (e.g. you can now create an amended SPDX document which has a new relationship for an element defined in the original document). This enables primary Element creating parties as well as third parties to express significantly greater contextual detail among content they create as well as content created by others.

Snippet

Description of Change

Byte and line range types have been changed from a StartEndPointer type to a PositiveIntegerRange. Byte range is now optional.

Translating from 2.3 to 3.0

Iterate through the “ranges” property. Any startPointer and endPointer with a property of “offset” would be translated to a snippetByteRange property. Any startPointer and endPointer with a property of “lineNumber” would translate to a snippetLineRange property.

A new Relationship would be created with the “from” pointing to the snippetFromFile and the “to” pointing to the Snippet. The relationshipType would be CONTAINS.

Rationale

Using the W3C Pointer standard introduced significant complexity in the SPDX 2.X specification. Although there may be some benefit in using a published standard, we have not found any instances where the W3C Pointer ontology was useful for SPDX use cases.

Changing the snippetFromFile from a property to a relationship [to be filled in].

SpecVersion

Description of Change

The type of SpecVersion is changed from a simple string without constraints to a SemVer string which must follow the Semantic Versioning format.

This adds a constraint where a patch version is required. Previous usage of the SpecVersiononly included the major and minor version.

Translating from 2.3 to 3.0

Add a patch version of “0” to any previous spec version.

Rationale

The additional constraints align with best practices for versioning strings

LicenseListVersion

Description of Change

The type of LicenseListVersion is changed from a simple string without constraints to a SemVer string which must follow the Semantic Versioning format.

This adds a constraint where a patch version is required. Previous usage of the SPDX License List only included the major and minor version.

Translating from 2.3 to 3.0

Add a patch version of “0” to any previous License List version.

Rationale

The additional constraints align with best practices for versioning strings.

Properties Removed

Below is a list of properties present in 2.3 and not present in 3.0. The Range / Where used is where the property was used in the SPDX 2.3 model.

example

SPDX 2.3 Model Name

example

Tag/Value Name

Not used

Range / Where Used

LicenseException

Rationale

This field has not been used.

LicenseInfoInFiles

SPDX 2.3 Model Name

licenseInfoInFiles

Tag/Value Name

LicenseInfoInFiles

Range / Where Used

Package

Rationale

This field is redundant with the declaredLicense property in the Files contained in the Package. It is recommended that the licenseInfoInFiles can be added as an Annotation to the Package in the format: “SPDX 2.X LicenseInfoInFiles: [expression1], [expression2]” where the [expressions] are the string representation of the license expressions.

FilesAnalyzed

SPDX 2.3 Model Name

filesAnalyzed

Tag/Value Name

FilesAnalyzed

Range / Where Used

Package

Rationale

Many users of the SPDX 2.X spec reported this property as very confusing.

NOTE: There is no longer a way to specific checksums are required for files. This is being tracked in Issue #84.

Naming Differences

Below is a list of properties and classes where the name has been changed from 2.3 to 3.0. The Range / Where used is where the property was used in the SPDX 2.3 model.

Release Date

SPDX 2.3 Model Name

releaseDate

Tag/Value Name

ReleaseDate

New Name

releaseTime

Range / Where Used

Package

Rationale

Better reflects the granularity of the field.

Build Date

SPDX 2.3 Model Name

buildDate

Tag/Value Name

BuildDate

New Name

buildTime

Range / Where Used

Package

Rationale

Better reflects the granularity of the field.

Valid Until Date

SPDX 2.3 Model Name

validUntilDate

Tag/Value Name

ValidUntilDate

New Name

validUntilTime

Range / Where Used

Package

Rationale

Better reflects the granularity of the field.

External Document Reference

SPDX 2.3 Model Name

externalDocumentRef

Tag/Value Name

ExternalDocumentRef

New Name

import

Range / Where Used

SpdxDocument (Creation Information)

Rationale

Feedback from SPDX 2.X usage is that externalDocumentRef is confusing due to the similar externalRef property.

NOTE: See structural changes related to this property

Checksum Class / Data Type

SPDX 2.3 Model Name

Checksum class name and checksum property name

Tag/Value Name

FileChecksum, PackageChecksum

New Name

verifiedUsing property and Hash class

Range / Where Used

Package, File

Rationale

More general concept allowing for different verification algorithms for different scenarios.

Checksum Algorithm

SPDX 2.3 Model Name

checksumAlgorithm

Tag/Value Name

N/A - parsed from a string following the Checksum: keyword.

New Name

hashAlgorithm

Range / Where Used

Package, File

Rationale

The term “hash” better represents the intent of this property which is to validate the integrity of the data whereas the term “checksum” is typically for the purpose of error checking.

Name

SPDX 2.3 Model Name

packageName, fileName

Tag/Value Name

PackageName, FileName

New Name

name

Range / Where Used

Package, File

Rationale

In the SPDX 2.3 RDF Ontology, both spdx:fileName and spdx:packageName are sub-properties of spdx:name. The OWL has a restriction that spdx:File has exactly one spdx:fileName and spdx:Package has exactly one spdx:packageName.

Changing these restrictions to just spdx:name would simplify the model.

Version

SPDX 2.3 Model Name

versionInfo

Tag/Value Name

PackageVersion

New Name

packageVersion

Range / Where Used

Package

Rationale

This change would make the Tag/Value and RDF values consistent.

Home Page

SPDX 2.3 Model Name

doap:homepage

Tag/Value Name

PackageHomePage

New Name

homePage

Range / Where Used

Rationale

Uses a consistent namespace for SPDX properties.

Annotation Comment

SPDX 2.3 Model Name

rdfs:comment

Tag/Value Name

AnnotationComment

New Name

statement

Range / Where Used

Element (Package, File, Snippet)

Rationale

The rdfs:comment property is optional and has slightly different semantics in other uses (e.g. comments on Elements). Changing the property name clearly distinguishes this usage as a mandatory property for an Annotation.

With Exception Operator

SPDX 2.3 Model Name

WithExceptionOperator

member property in WithExceptionOperator

licenseException property in WithExceptionOperator

Tag/Value Name

With (part of License Expression)

New Name

WithAdditionOperator

subjectLicense

subjectAddition

Range / Where Used

Package, File, Snippet

Rationale

Custom Additions have been added in SPDX 3.0 which operate in a similar manner to listed License Exceptions. The new type and property names are more general to accommodate both custom additions and listed License Exceptions.

License Exception

SPDX 2.3 Model Name

LicenseException

licenseExceptionId property in LicenseException

licenseExceptionText property in LicenseException

name property in LicenseException

Tag/Value Name

Not used in Tag/Value

New Name

ListedLicenseException

additionId

additionText

additionName

Range / Where Used

Package, File, Snippet

Rationale

Custom Additions have been added in SPDX 3.0 which operate in a similar manner to listed License Exceptions. The new type and property names are more general to accommodate both custom additions and listed License Exceptions.

ExtractedLicenseInfo

SPDX 2.3 Model Name

ExtractedLicenseInfo

Tag/Value Name

ExtractedText

New Name

CustomLicense

Range / Where Used

Package, File, Snippet, Document

Rationale

The SPDX 2.X term implied that the only property was text when in fact there are several properties in common with the listed licenses. See model issue #233 for context.

licenseName

SPDX 2.3 Model Name

licenseName

Tag/Value Name

LicenseName

New Name

name

Range / Where Used

License, ListedLicense, ExtractedText

Rationale

“name” is used in the Element class. Since License is a type of (subclass of) Element, it should use the same field otherwise there would be redundant fields for the same purpose.

LicenseComment

SPDX 2.3 Model Name

licenseComment

Tag/Value Name

LicenseComment

New Name

comment

Range / Where Used

License, ListedLicense

Rationale

“comment” is used in the Element class. Since License is a type of (subclass of) Element, it should use the same field otherwise there would be redundant fields for the same purpose.

LicenseID

SPDX 2.3 Model Name

licenseId

Tag/Value Name

LicenseId

New Name

spdxId

Range / Where Used

License, ListedLicense

Rationale

“spdxId” is used in the Element class. Since License is a type of (subclass of) Element, it should use the same field otherwise there would be redundant fields for the same purpose.

Range / Where Used

License, ListedLicense

Rationale

Primary Package Purpose

SPDX 2.3 Model Name

primaryPackagePurpose

Tag/Value Name

PrimaryPackagePurpose

New Name

primaryPurpose

Range / Where Used

Package

Rationale

The purpose property is now available for files and snippets in addition to Package resulting in a more general name of primaryPurpose.

Note that additional purposes can be added using the additionalPurpose property.

Serialization Formats

SPDX 3.0 implements a JSON-LD format which has consistent class and property names with the model.

See the SPDX 3.0 JSON Schema for the format specifics.

The Tag/Value, YAML, RDF/XML and Spreadsheet formats are not supported.

Additional serialization formats are being considered for the SPDX 3.1 release.