Skip to content

Commit 7bf378e

Browse files
committed
docs: new field of license table
1 parent 5a4c127 commit 7bf378e

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# 00009. Create New Field in License
2+
3+
Date: 2025-07-27
4+
5+
## Status
6+
7+
DRAFT
8+
9+
## Context
10+
11+
In the new license search requirements, there is a section called license summary, which requires collecting usage statistics for all licenses that appear, including how many packages and SBOMs use each license.
12+
13+
## The Current Status of Licenses in Trustify
14+
15+
Currently, Trustify's support for licenses is as follows:
16+
17+
In SPDX, there are two types of licenses: licenseDeclared and licenseConcluded, and the representation is mainly in the form of license expressions, which can include custom license references (licenseRef).
18+
19+
CycloneDX uses only one type, licenseDeclared, but offers three ways to represent it:
20+
21+
- ID: This is a standard SPDX license ID.
22+
- License expression: Similar to SPDX, it supports license expressions.
23+
- Name: This is similar to a custom license reference, allowing for user-defined license names.
24+
25+
In Trustify, the handling is as follows:
26+
27+
When processing SPDX, Trustify parses the license expression into standard SPDX license IDs and exceptions, and stores them in spdx_licenses and spdx_license_exceptions. All custom license references (LicenseRef) are filtered out, while the original expression is preserved in the text field.
28+
29+
When processing CycloneDX, there are three scenarios:
30+
31+
- If the license is an ID, the value is saved directly in the text field and spdx_licenses.
32+
- If the license is a name: The value is saved directly in the text field, stores them in spdx_licenses.
33+
- If the license is an expression: Trustify parses it into standard SPDX license IDs and exceptions, stores them in spdx_licenses and spdx_license_exceptions, and also preserves the original expression in the text field.
34+
35+
## The Current Issue
36+
37+
- In SPDX, when a license expression contains a custom license ID, Trustify also saves it only in a text field, and filters out the custom license ID during the process of parsing it into standard SPDX license IDs and exceptions.
38+
- In SPDX, when a license expression includes a custom license ID, the custom license ID itself is meaningless and only has significance within the current SBOM, so it cannot be used for statistics or searches.
39+
40+
## Decision
41+
42+
Add a new field named `custom_license_refs` to the license table. Its type is a list, which includes licenses of type name appearing in CycloneDX, as well as license expressions that contain custom licenses in SPDX.
43+
44+
```sql
45+
ALTER TABLE license ADD COLUMN custom_license_refs text[];
46+
ALTER TABLE license ADD COLUMN custom_document_license_refs text[];
47+
```
48+
### The current table structure vs. the changed table structure
49+
50+
- Current table structure
51+
```rust
52+
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, serde::Serialize)]
53+
#[sea_orm(table_name = "license")]
54+
pub struct Model {
55+
#[sea_orm(primary_key)]
56+
pub id: Uuid,
57+
pub text: String,
58+
pub spdx_licenses: Option<Vec<String>>,
59+
pub spdx_license_exceptions: Option<Vec<String>>,
60+
}
61+
```
62+
63+
- Changed table structure
64+
65+
```rust
66+
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, serde::Serialize)]
67+
#[sea_orm(table_name = "license")]
68+
pub struct Model {
69+
#[sea_orm(primary_key)]
70+
pub id: Uuid,
71+
pub text: String,
72+
pub spdx_licenses: Option<Vec<String>>,
73+
pub spdx_license_exceptions: Option<Vec<String>>,
74+
pub custom_license_refs: Option<Vec<String>>,
75+
}
76+
```
77+
78+
### SPDX
79+
80+
License expression:
81+
82+
```json
83+
{
84+
"SPDXID": "SPDXRef-2a02a923-8a04-489d-9cbc-80f2d23de5ea",
85+
"copyrightText": "NOASSERTION",
86+
"downloadLocation": "https://access.redhat.com/downloads/content/package-browser",
87+
"externalRefs": [
88+
{
89+
"referenceCategory": "PACKAGE_MANAGER",
90+
"referenceLocator": "pkg:rpm/redhat/[email protected]?arch=src",
91+
"referenceType": "purl"
92+
}
93+
],
94+
"filesAnalyzed": false,
95+
"licenseConcluded": "NOASSERTION",
96+
"licenseDeclared": "LicenseRef-2 AND LicenseRef-11 AND LicenseRef-BSD",
97+
"name": "foreman-bootloaders-redhat",
98+
"originator": "NOASSERTION",
99+
"packageFileName": "foreman-bootloaders-redhat-202102220000-1.el8sat.src.rpm",
100+
"supplier": "Organization: Red Hat",
101+
"versionInfo": "202102220000-1.el8sat"
102+
}
103+
```
104+
105+
Custom licenses:
106+
107+
```json
108+
[
109+
{
110+
"comment": "External License Info is obtained from a build system which predates the SPDX specification and is not strict in accepting valid SPDX licenses.",
111+
"extractedText": "The license info found in the package meta data is: GPLv2+. See the specific package info in this SPDX document or the package itself for more details.",
112+
"licenseId": "LicenseRef-2",
113+
"name": "GPLv2+"
114+
},
115+
{
116+
"comment": "External License Info is obtained from a build system which predates the SPDX specification and is not strict in accepting valid SPDX licenses.",
117+
"extractedText": "The license info found in the package meta data is: GPLv3+. See the specific package info in this SPDX document or the package itself for more details.",
118+
"licenseId": "LicenseRef-11",
119+
"name": "GPLv3+"
120+
},
121+
{
122+
"comment": "External License Info is obtained from a build system which predates the SPDX specification and is not strict in accepting valid SPDX licenses.",
123+
"extractedText": "The license info found in the package meta data is: BSD. See the specific package info in this SPDX document or the package itself for more details.",
124+
"licenseId": "LicenseRef-BSD",
125+
"name": "BSD"
126+
}
127+
]
128+
```
129+
130+
`custom_license_refs`: should be a JSONB mapping all custom license identifiers to their descriptions or SPDX expressions.
131+
132+
```json
133+
{
134+
"LicenseRef-2": "GPLv2+",
135+
"LicenseRef-11": "GPLv3+",
136+
"LicenseRef-BSD": "BSD"
137+
}
138+
```
139+
140+
## Consequences
141+
- Positive: Enables complete license statistics and search functionality
142+
- Negative: Increases storage overhead and requires data migration handling
143+
144+
## Alternatives Considered
145+
- Using JSONB to store complete license mappings (rejected: high query complexity)
146+
- Maintaining status quo without handling custom licenses (rejected: fails business requirements)
147+
148+
## Success Metrics
149+
- Ability to count packages containing custom licenses
150+
- Support for searching by custom license ID
151+
152+
153+
## Known Issues
154+
155+
There are two types of custom licenses:
156+
157+
- Ones that are defined within the current SBOM, for example those with the "LicenseRef" prefix.
158+
- Ones that reference other SBOM documents, for example those with the "DocumentRef" prefix.
159+
160+
Previously, we only handled the first type of custom license. The second type cannot be processed currently.
161+
If we want to handle the second type, we need to add a new field, `custom_document_license_refs`, to store the complete reference, such as "DocumentRef-spdx-tool-1.2:LicenseRef-BSD"[1], in this field.
162+
163+
[1] Where "DocumentRef" is the prefix and "spdx-tool-1.2" refers to another SPDX SBOM, "LicenseRef-BSD" is the custom license reference within that SBOM.

0 commit comments

Comments
 (0)