Files
git.stella-ops.org/docs/modules/vex-lens/security-profile.md
2026-01-08 20:46:43 +02:00

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