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:

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 StatusSPDX 3.0.1 TypeRelationship
affectedVexAffectedVulnAssessmentRelationshipAffects
not_affectedVexNotAffectedVulnAssessmentRelationshipDoesNotAffect
fixedVexFixedVulnAssessmentRelationshipFixedIn
under_investigationVexUnderInvestigationVulnAssessmentRelationshipUnderInvestigationFor

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 JustificationSPDX 3.0.1 JustificationType
component_not_presentComponentNotPresent
vulnerable_code_not_presentVulnerableCodeNotPresent
vulnerable_code_cannot_be_controlled_by_adversaryVulnerableCodeCannotBeControlledByAdversary
vulnerable_code_not_in_execute_pathVulnerableCodeNotInExecutePath
inline_mitigations_already_existInlineMitigationsAlreadyExist

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:

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:

FeatureOpenVEXSPDX 3.0.1 Security
Status values4 statuses4 relationship types
Justifications5 types5 justification types
Action statementsSupportedSupported
TimestampsSupportedSupported
CVSSEmbeddedSeparate relationship
EPSSCustom extensionSeparate relationship

Offline Support

The Security profile integration supports air-gapped environments: