6.7 KiB
SPDX 3.0.1 Security Profile Integration
Sprint: SPRINT_20260107_004_004_BE Status: Active Last Updated: 2026-01-08
Overview
The SPDX 3.0.1 Security profile captures vulnerability assessment information in a standardized format. StellaOps VexLens integrates this profile to export VEX consensus data in SPDX 3.0.1 format, enabling interoperability with SPDX-compatible tooling.
This creates a unified security assessment format that:
- Aligns with OpenVEX semantics
- Integrates with existing SBOM documents
- Supports CVSS and EPSS scoring
- Enables combined Software+Security profile documents
Security Profile Elements
Vulnerability Element
The Spdx3Vulnerability element represents a security vulnerability:
{
"@type": "security_Vulnerability",
"spdxId": "urn:stellaops:vuln:CVE-2026-1234",
"name": "CVE-2026-1234",
"summary": "Remote code execution in example library",
"security_publishedTime": "2026-01-01T00:00:00Z",
"security_modifiedTime": "2026-01-05T12:00:00Z",
"externalIdentifier": [{
"externalIdentifierType": "cve",
"identifier": "CVE-2026-1234",
"identifierLocator": ["https://nvd.nist.gov/vuln/detail/CVE-2026-1234"]
}]
}
VEX Assessment Relationships
VEX assessments are modeled as relationships between vulnerabilities and products:
| OpenVEX Status | SPDX 3.0.1 Type | Relationship |
|---|---|---|
| affected | VexAffectedVulnAssessmentRelationship | Affects |
| not_affected | VexNotAffectedVulnAssessmentRelationship | DoesNotAffect |
| fixed | VexFixedVulnAssessmentRelationship | FixedIn |
| under_investigation | VexUnderInvestigationVulnAssessmentRelationship | UnderInvestigationFor |
Example affected assessment:
{
"@type": "security_VexAffectedVulnAssessmentRelationship",
"spdxId": "urn:stellaops:vex/CVE-2026-1234/pkg-abc",
"security_assessedElement": "urn:stellaops:pkg/abc",
"from": "urn:stellaops:vuln:CVE-2026-1234",
"to": ["urn:stellaops:pkg/abc"],
"relationshipType": "affects",
"security_vexVersion": "1.0.0",
"security_statusNotes": "Vulnerable code path is exposed",
"security_actionStatement": "Upgrade to version 2.0.0",
"security_actionStatementTime": "2026-01-15T00:00:00Z"
}
Justification Types
For not_affected status, SPDX 3.0.1 supports these justification types:
| OpenVEX Justification | SPDX 3.0.1 JustificationType |
|---|---|
| component_not_present | ComponentNotPresent |
| vulnerable_code_not_present | VulnerableCodeNotPresent |
| vulnerable_code_cannot_be_controlled_by_adversary | VulnerableCodeCannotBeControlledByAdversary |
| vulnerable_code_not_in_execute_path | VulnerableCodeNotInExecutePath |
| inline_mitigations_already_exist | InlineMitigationsAlreadyExist |
API Usage
Mapping VEX Consensus
Use VexToSpdx3Mapper to convert VEX consensus to SPDX 3.0.1:
var mapper = new VexToSpdx3Mapper(timeProvider);
var consensus = new VexConsensus
{
DocumentId = "urn:stellaops:vex:doc-12345",
Author = "security-team@example.com",
Statements = statements
};
var options = new VexToSpdx3Options
{
SpdxIdPrefix = "https://stellaops.io/spdx",
IncludeCvss = true,
IncludeEpss = true,
ProductFilter = null // All products
};
var document = await mapper.MapConsensusAsync(consensus, options);
Combined SBOM+VEX Documents
Use CombinedSbomVexBuilder to merge Software and Security profiles:
var document = CombinedSbomVexBuilder.Create(timeProvider)
.WithDocumentId("https://stellaops.io/spdx/combined/12345")
.WithName("Combined SBOM and VEX Data")
.WithSoftwareProfile(sbom)
.WithSecurityProfile(consensus, spdxIdPrefix)
.Build();
// Or use the extension method
var combined = sbom.WithVexData(
consensus,
documentId: "https://stellaops.io/spdx/combined/12345",
spdxIdPrefix: "https://stellaops.io/spdx");
Linked Security Profile
When combining SBOM and VEX, product IDs (PURLs) are automatically linked to SPDX Package IDs:
var combined = CombinedSbomVexBuilder.Create()
.WithDocumentId(documentId)
.WithSoftwareProfile(sbom) // Extracts PURL->SPDX ID mapping
.WithLinkedSecurityProfile(statements, spdxIdPrefix) // Rewrites product IDs
.Build();
CVSS Integration
CVSS v3 scores are mapped to CvssV3VulnAssessmentRelationship:
{
"@type": "security_CvssV3VulnAssessmentRelationship",
"spdxId": "urn:stellaops:cvss/CVE-2026-1234",
"security_assessedElement": "urn:stellaops:pkg/abc",
"from": "urn:stellaops:vuln:CVE-2026-1234",
"to": ["urn:stellaops:pkg/abc"],
"security_score": 9.8,
"security_severity": "Critical",
"security_vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
}
Severity is automatically calculated from score:
- 0.0: None
- 0.1-3.9: Low
- 4.0-6.9: Medium
- 7.0-8.9: High
- 9.0-10.0: Critical
EPSS Integration
EPSS (Exploit Prediction Scoring System) data is mapped to EpssVulnAssessmentRelationship:
{
"@type": "security_EpssVulnAssessmentRelationship",
"spdxId": "urn:stellaops:epss/CVE-2026-1234",
"security_assessedElement": "urn:stellaops:pkg/abc",
"from": "urn:stellaops:vuln:CVE-2026-1234",
"to": ["urn:stellaops:pkg/abc"],
"security_probability": 0.85,
"security_percentile": 0.97
}
Parsing Security Profile
The Spdx3Parser can parse SPDX 3.0.1 documents containing Security profile elements:
var parser = new Spdx3Parser(contextResolver, logger);
var result = await parser.ParseAsync(stream);
if (result.IsSuccess)
{
var vulnerabilities = result.Document.Elements
.OfType<Spdx3Vulnerability>();
var vexAssessments = result.Document.Relationships
.OfType<Spdx3VulnAssessmentRelationship>();
}
OpenVEX Interoperability
VexLens maintains full interoperability between OpenVEX and SPDX 3.0.1:
| Feature | OpenVEX | SPDX 3.0.1 Security |
|---|---|---|
| Status values | 4 statuses | 4 relationship types |
| Justifications | 5 types | 5 justification types |
| Action statements | Supported | Supported |
| Timestamps | Supported | Supported |
| CVSS | Embedded | Separate relationship |
| EPSS | Custom extension | Separate relationship |
Offline Support
The Security profile integration supports air-gapped environments:
- All mapping operations are local
- No network calls required for document generation
- Documents can be bundled for offline transport