-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Alexios Zavras (zvr) <[email protected]>
- Loading branch information
Showing
6 changed files
with
1,644 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# Annex H: SPDX Lite | ||
|
||
## H.1 Definition of the Lite profile <a name="H.1"></a> | ||
|
||
The Lite profile is designed to make it quick and easy to start a Software Bill of Materials in situations where a company may have limited capacity for introducing new items into its process. | ||
The Lite profile captures the minimum set of information required for license compliance in the software supply chain. It contains information about the creation of the SBOM, package lists with licensing and other related items, and their relationships. | ||
|
||
All elements in Lite profile are essential for complying with licenses. It is easy to use a SPDX document with the Lite profile for anyone who does not have enough knowledge about licensing information and easy to import license information from former versions of SPDX Lite format files. | ||
The Lite profile offers the flexibility to be used either alone or in combination with other SPDX profiles as a SPDX document in the software supply chain. | ||
|
||
## H.2 Table of the Lite profile elements <a name="H.2"></a> | ||
|
||
A SPDX document with the Lite profile must include properties for each class listed in **Table H.1**. And ```Cardinality 1..1``` means a **REQUIRED** element, and the others **SHOULD** be filled in as much as possible if necessary. | ||
|
||
**Table H.1 — the Lite profile elements** | ||
|
||
1. For a /Core/SpdxDocument to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Core/SpdxDocument/spdxId | 1..1 | | | ||
| 2 | /Core/SpdxDocument/name | 0..1 | | | ||
| 3 | /Core/SpdxDocument/comment | 0..1 | | | ||
| 4 | /Core/SpdxDocument/creationInfo | 1..1 | | | ||
| 5 | /Core/SpdxDocument/verifiedUsing | 0..1 | This should be an object of /Core/Hash | | ||
| 6 | /Core/SpdxDocument/element | 1..* | MUST have at least one element | | ||
| 7 | /Core/SpdxDocument/rootElement | 1..1 | This should be an object of /Core/Sbom | | ||
| 8 | /Core/SpdxDocument/namespaceMap | 0..* | | | ||
| 9 | /Core/SpdxDocument/dataLicense | 0..1 | | | ||
|
||
2. For a /Core/NameSpaceMap to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Core/NameSpaceMap/prefix | 1..1 | | | ||
| 2 | /Core/NameSpaceMap/namespace | 1..1 | | | ||
|
||
3. For a /Software/Sbom to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Software/Sbom/spdxId | 1..1 | | | ||
| 2 | /Software/Sbom/creationInfo | 1..1 | | | ||
| 3 | /Software/Sbom/element | 1..* | MUST have at least one element | | ||
| 4 | /Software/Sbom/rootElement | 1..1 | This should be an object of /Software/Package | | ||
| 5 | /Software/Sbom/sbomType | 0..1 | | | ||
|
||
4. For a /Core/CreationInfo to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Core/CreationInfo/specVersion | 1..1 | This should be a fixed string, “3.0”. | | ||
| 2 | /Core/CreationInfo/comment | 0..1 | | | ||
| 3 | /Core/CreationInfo/created | 1..1 | | | ||
| 4 | /Core/CreationInfo/createdBy | 1..1 | This should be an object of /Core/Agent | | ||
|
||
5. For a /Core/Agent (createdBy, suppliedBy, originatedBy) to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Core/Agent/spdxId | 1..1 | | | ||
| 2 | /Core/Agent/name | 1..1 | | | ||
| 3 | /Core/Agent/creationInfo | 1..1 | This should be “BlankNode” | | ||
| 4 | /Core/Agent/externalIdentifier | 0..1 | | | ||
|
||
6. For a /Core/ExternalIdentifier to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Core/ExternalIdentifier/externalIdentifierType | 1..1 | | | ||
| 2 | /Core/ExternalIdentifier/identifier | 1..1 | | | ||
|
||
7. For a /Software/Package to be conformant with this profile, the following has to hold: | ||
And all /Software/Package objects MUST have “downloadLocation” OR “packageUrl” if present. | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Software/Package/spdxId | 1..1 | | | ||
| 2 | /Software/Package/name | 1..1 | | | ||
| 3 | /Software/Package/comment | 0..1 | | | ||
| 4 | /Software/Package/creationInfo | 1..1 | | | ||
| 5 | /Software/Package/verifiedUsing | 0..1 | This should be an object of /Core/Hash | | ||
| 6 | /Software/Package/originatedBy | 0..* | This should be an object of /Core/Agent | | ||
| 7 | /Software/Package/suppliedBy | 1..1 | This should be an object of /Core/Agent | | ||
| 8 | /Software/Package/builtTime | 0..1 | | | ||
| 9 | /Software/Package/releaseTime | 0..1 | | | ||
| 10 | /Software/Package/validUntilTime | 0..1 | | | ||
| 11 | /Software/Package/supportLevel | 0..1 | | | ||
| 12 | /Software/Package/copyrightText | 1..1 | | | ||
| 13 | /Software/Package/attributionText | 0..1 | | | ||
| 14 | /Software/Package/packageVersion | 1..1 | | | ||
| 15 | /Software/Package/downloadLocation | 0..1 | | | ||
| 16 | /Software/Package/packageUrl | 0..1 | | | ||
| 17 | /Software/Package/homepage | 0..1 | | | ||
|
||
8. For a /Core/Hash to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Core/Hash/algorithm | 1..1 | | | ||
| 2 | /Core/Hash/hashValue | 1..1 | | | ||
| 3 | /Core/Hash/comment | 0..1 | | | ||
|
||
9. For a /Core/Relationship to be conformant with this profile, the following has to hold: | ||
|
||
1. for every /Software/Package object MUST exist exactly one /Core/Relationship object of type ```concludedLicense``` having that element as its ```from``` property and an /SimpleLicensing/AnyLicenseInfo as its ```to``` property. | ||
2. for every /Software/Package object MUST exist exactly one /Core/Relationship object of type ```declaredLicense``` having that element as its ```from``` property and /SimpleLicensing/AnyLicenseInfo object as its ```to``` property. | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /Core/Relationship/spdxId | 1..1 | | | ||
| 2 | /Core/Relationship/creationInfo | 1..1 | | | ||
| 3 | /Core/Relationship/from | 1..1 | | | ||
| 4 | /Core/Relationship/to | 1..* | | | ||
| 5 | /Core/Relationship/relationshipType | 1..1 | | | ||
|
||
10. For a /SimpleLicensing/LicenseExpression to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /SimpleLicensing/LicenseExpression/spdxId | 1..1 | | | ||
| 2 | /SimpleLicensing/LicenseExpression/creationInfo | 1..1 | | | ||
| 3 | /SimpleLicensing/LicenseExpression/licenseExpression | 1..1 | | | ||
| 4 | /SimpleLicensing/LicenseExpression/licenseListVersion | 0..1 | | | ||
|
||
11. For a /SimpleLicensing/SimpleLicensingText to be conformant with this profile, the following has to hold: | ||
|
||
| # | Property Name | Cardinality | Comments | | ||
|:-:|:--|:--|:--| | ||
| 1 | /SimpleLicensing/SimpleLicensingText/spdxId | 1..1 | | | ||
| 2 | /SimpleLicensing/SimpleLicensingText/creationInfo | 1..1 | | | ||
| 3 | /SimpleLicensing/SimpleLicensingText/licenseText | 1..1 | | | ||
| 4 | /SimpleLicensing/SimpleLicensingText/comment | 0..1 | | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
# Annex I: Cross referencing in SPDX 3 (Informative) | ||
|
||
This document will walk though how to refer to SPDX Elements across documents | ||
(e.g. cross reference). | ||
|
||
If you do would like to construct the complete example documents from this | ||
Markdown file, use the following command: | ||
|
||
```shell | ||
cat cross-reference.md | awk 'BEGIN{flag=0} /^```json/, $0=="```" { if (/^---$/){flag++} else if ($0 !~ /^```.*/ ) print $0 > "doc-" flag ".spdx.json"}' | ||
``` | ||
|
||
## Linking via spdxId | ||
|
||
It is frequently desired (and necessary) to reference an SPDX 3 | ||
[Element][Class_Element] that lives in one document from another. Since SPDX | ||
documents are valid [JSON-LD][JSON_LD] documents, linking elements together can | ||
be as simple as referencing the spdxId of one element from another (in the same | ||
way that doing so within a document links Elements together. For example, | ||
assume we have this document that contains a [Person][Class_Person] we want to | ||
reference in another document: | ||
|
||
```json | ||
{ | ||
"@context": "https://spdx.org/rdf/3.0.0/spdx-context.jsonld", | ||
"@graph": [ | ||
{ | ||
"type": "Person", | ||
"spdxId": "https://spdx.org/spdxdocs/Person/JoshuaWatt-0ef7e15a-5628-4bd9-8485-a3eace6dcc4f", | ||
"creationInfo": "_:creationinfo", | ||
"name": "Joshua Watt", | ||
"externalIdentifier": [ | ||
{ | ||
"type": "ExternalIdentifier", | ||
"externalIdentifierType": "email", | ||
"identifier": "[email protected]" | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "CreationInfo", | ||
"@id": "_:creationinfo", | ||
"specVersion": "3.0.0", | ||
"createdBy": [ | ||
"https://spdx.org/spdxdocs/Person/JoshuaWatt-0ef7e15a-5628-4bd9-8485-a3eace6dcc4f" | ||
], | ||
"created": "2024-03-06T00:00:00Z" | ||
}, | ||
{ | ||
"type": "SpdxDocument", | ||
"spdxId": "https://spdx.org/spdxdocs/Document1-7bd25aaf-64b7-4ccc-aa85-84695cef4c17", | ||
"creationInfo": "_:creationinfo", | ||
"profileConformance": [ | ||
"core" | ||
], | ||
"rootElement": [ | ||
"https://spdx.org/spdxdocs/Person/JoshuaWatt-0ef7e15a-5628-4bd9-8485-a3eace6dcc4f" | ||
] | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Now, in our new document we can reference the "Joshua Watt" person by simply | ||
referring to it by its spdxId. For example, to indicate that this new document | ||
was also written by the same person, we can reference it in the creation info | ||
(note the [createdBy][Property_createdBy] property): | ||
|
||
```json | ||
--- | ||
{ | ||
"@context": "https://spdx.org/rdf/3.0.0/spdx-context.jsonld", | ||
"@graph": [ | ||
{ | ||
"type": "CreationInfo", | ||
"@id": "_:creationinfo1", | ||
"specVersion": "3.0.0", | ||
"createdBy": [ | ||
"https://spdx.org/spdxdocs/Person/JoshuaWatt-0ef7e15a-5628-4bd9-8485-a3eace6dcc4f" | ||
], | ||
"created": "2024-05-08T00:00:00Z" | ||
}, | ||
``` | ||
|
||
## Imports | ||
|
||
This is sufficient to link documents in JSON-LD, but it is missing some useful | ||
information that SPDX requires you to specify. Namely, since spdxIds are _not_ | ||
necessarily resolvable URLs, this gives no indication as to where the | ||
[Person][Class_Person] can be found. In order to provide this information, SPDX | ||
requires that all externally referenced spdxIds be enumerated in the | ||
[imports][Property_imports] property of the local | ||
[SpdxDocument][Class_SpdxDocument]. Lets start by writing the preamble for the | ||
SpdxDocument: | ||
|
||
```json | ||
{ | ||
"type": "SpdxDocument", | ||
"spdxId": "https://spdx.org/spdxdocs/Document2-72d52ac3-3642-47be-9f83-8fbef6a962b4", | ||
"creationInfo": "_:creationinfo1", | ||
"profileConformance": [ | ||
"core", | ||
"software" | ||
], | ||
"imports": [ | ||
``` | ||
|
||
The [imports][Property_imports] property is a list of | ||
[ExternalMap][Class_ExternalMap] objects, one for each external spdxId being | ||
referenced. The class has one required property called | ||
[externalSpdxId][Property_externalSpdxId] which is the external spdxId being | ||
described: | ||
|
||
```json | ||
{ | ||
"type": "ExternalMap", | ||
"externalSpdxId": "https://spdx.org/spdxdocs/Person/JoshuaWatt-0ef7e15a-5628-4bd9-8485-a3eace6dcc4f", | ||
|
||
``` | ||
|
||
In addition to this, there are a few optional fields. The first is the | ||
[locationHint][Property_locationHint] property which is a URI that indicates | ||
where the document that contains the external spdxId may be located. Since this | ||
is an actual resolvable URI, consumers of the document can use locate the | ||
unresolved spdxId. While optional, this field is recommended: | ||
|
||
```json | ||
"locationHint": "http://downloads.example.com/Document1.spdx.json", | ||
``` | ||
|
||
In addition to the location, the [verifiedUsing][Property_verifiedUsing] | ||
property indicates how a user can verify the integrity of the external document | ||
to ensure it has not been tampered with. It can be 0 or more | ||
[IntegrityMethod][Class_IntegrityMethod] objects. While also optional, it is | ||
recommended to include at least one: | ||
|
||
```json | ||
"verifiedUsing": [{ | ||
"type": "Hash", | ||
"algorithm": "sha256", | ||
"hashValue": "3ba8c249c1ba1b6fe20582de88a5123b317632a5a94ba27199d01724df4eb149" | ||
}], | ||
``` | ||
|
||
Finally, the [definingArtifact][Property_definingArtifact] allows a much richer | ||
expression of information about the document that contains the external spdxId | ||
by linking to a complete [Artifact][Class_Artifact] element. This field is also | ||
optional, but if you need the impressive expressive power of the `Artifact` | ||
class, it is also recommended: | ||
|
||
```json | ||
"definingArtifact": "https://spdx.org/spdxdocs/Artifact-4762f4c5-3362-47e9-9595-5182235ef577" | ||
``` | ||
|
||
It should be noted that it is reasonable for the `definingArtifact` itself to | ||
be an external spdxId, as long as it also has the relevant entry in `imports`. | ||
|
||
We also need to add an import for the [SpdxDocument][Class_SpdxDocument] that | ||
contains the author, as we will be referencing it later, so lets do that now: | ||
|
||
```json | ||
}, | ||
{ | ||
"type": "ExternalMap", | ||
"externalSpdxId": "https://spdx.org/spdxdocs/Document1-7bd25aaf-64b7-4ccc-aa85-84695cef4c17", | ||
"locationHint": "http://downloads.example.com/Document1.spdx.json", | ||
"verifiedUsing": [{ | ||
"type": "Hash", | ||
"algorithm": "sha256", | ||
"hashValue": "3ba8c249c1ba1b6fe20582de88a5123b317632a5a94ba27199d01724df4eb149" | ||
}], | ||
"definingArtifact": "https://spdx.org/spdxdocs/Artifact-4762f4c5-3362-47e9-9595-5182235ef577" | ||
} | ||
``` | ||
|
||
And that is it! By providing this information you are explaining to consumer of | ||
the document how they can resolve the external spdxIds. | ||
|
||
Lets close out our SpdxDocument | ||
|
||
```json | ||
] | ||
}, | ||
``` | ||
|
||
Since we are using an [Artifact][Class_Artifact] that describes the SpdxDocument | ||
containing the external spdxId, we need to write that now: | ||
|
||
```json | ||
{ | ||
"type": "software_File", | ||
"spdxId": "https://spdx.org/spdxdocs/Artifact-4762f4c5-3362-47e9-9595-5182235ef577", | ||
"creationInfo": "_:creationinfo1", | ||
"software_fileKind": "file", | ||
"software_primaryPurpose": "file", | ||
"software_contentType": "application/spdx+json", | ||
"verifiedUsing": [{ | ||
"type": "Hash", | ||
"algorithm": "sha256", | ||
"hashValue": "3ba8c249c1ba1b6fe20582de88a5123b317632a5a94ba27199d01724df4eb149" | ||
}], | ||
"originatedBy": [ | ||
"https://spdx.org/spdxdocs/Person/JoshuaWatt-0ef7e15a-5628-4bd9-8485-a3eace6dcc4f" | ||
], | ||
"suppliedBy": "https://spdx.org/spdxdocs/Person/JoshuaWatt-0ef7e15a-5628-4bd9-8485-a3eace6dcc4f", | ||
"releaseTime": "2024-03-06T00:00:00Z", | ||
"builtTime": "2024-03-06T00:00:00Z" | ||
}, | ||
``` | ||
|
||
Finally, since we are using an [Artifact][Class_Artifact], we need to add a | ||
[Relationship][Class_Relationship] with type `serailizedInArtifact` to link the | ||
artifact and the serialized [SpdxDocument][Class_SpdxDocument]. Note that this | ||
is where the `spdxId` of the `SpdxDocument` is referenced which is why we | ||
needed to import it earlier: | ||
|
||
```json | ||
{ | ||
"spdxId": "https://spdx.org/spdxdocs/Relationship/serializedInArtifact-141ec767-40f2-4aad-9658-ac2703f3a7d9", | ||
"type": "Relationship", | ||
"creationInfo": "_:creationinfo1", | ||
"relationshipType": "serializedInArtifact", | ||
"from": "https://spdx.org/spdxdocs/Document1-7bd25aaf-64b7-4ccc-aa85-84695cef4c17", | ||
"to": [ | ||
"https://spdx.org/spdxdocs/Artifact-4762f4c5-3362-47e9-9595-5182235ef577" | ||
] | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Happy Linking! | ||
|
||
[Class_Artifact]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Artifact | ||
[Class_Element]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Element | ||
[Class_ExternalMap]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/ExternalMap | ||
[Class_IntegrityMethod]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/IntegrityMethod | ||
[Class_Person]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Person | ||
[Class_SpdxDocument]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/SpdxDocument | ||
[Class_Relationship]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Relationship | ||
[JSON_LD]: https://json-ld.org/ | ||
[Property_createdBy]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Properties/createdBy | ||
[Property_definingArtifact]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Properties/definingArtifact | ||
[Property_externalSpdxId]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Properties/externalSpdxId | ||
[Property_imports]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Properties/imports | ||
[Property_verifiedUsing]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Properties/verifiedUsing | ||
[Property_locationHint]: https://spdx.github.io/spdx-spec/v3.0/model/Core/Properties/locationHint |
Oops, something went wrong.