//
// Copyright (c) StellaOps. Licensed under the BUSL-1.1.
//
using StellaOps.Spdx3.Model;
namespace StellaOps.VexLens.Spdx3;
///
/// Interface for mapping VEX consensus results to SPDX 3.0.1 Security profile documents.
/// Sprint: SPRINT_20260107_004_004 Task SP-005
///
public interface IVexToSpdx3Mapper
{
///
/// Maps a VEX consensus result to an SPDX 3.0.1 document with Security profile.
///
/// The VEX consensus containing statements.
/// Mapping options.
/// Cancellation token.
/// The mapped SPDX 3.0.1 document.
Task MapConsensusAsync(
VexConsensus consensus,
VexToSpdx3Options options,
CancellationToken cancellationToken = default);
///
/// Maps individual VEX statements to SPDX 3.0.1 elements.
///
/// The VEX statements to map.
/// Prefix for generating SPDX IDs.
/// The mapped elements including vulnerabilities and assessment relationships.
VexMappingResult MapStatements(
IEnumerable statements,
string spdxIdPrefix);
}
///
/// Options for VEX to SPDX 3.0.1 mapping.
///
public sealed record VexToSpdx3Options
{
///
/// Gets the SPDX ID prefix for generated elements.
///
public required string SpdxIdPrefix { get; init; }
///
/// Gets the document name.
///
public string? DocumentName { get; init; }
///
/// Gets whether to include CVSS scores.
///
public bool IncludeCvss { get; init; } = true;
///
/// Gets whether to include EPSS scores.
///
public bool IncludeEpss { get; init; } = true;
///
/// Gets the tool identifier to include in creation info.
///
public string ToolId { get; init; } = "StellaOps VexLens";
///
/// Gets a filter for specific products (null = all).
///
public IReadOnlyList? ProductFilter { get; init; }
///
/// Gets a filter for specific CVEs (null = all).
///
public IReadOnlyList? VulnerabilityFilter { get; init; }
}
///
/// Result of mapping VEX statements to SPDX 3.0.1 elements.
///
public sealed record VexMappingResult
{
///
/// Gets the vulnerability elements.
///
public required IReadOnlyList Vulnerabilities { get; init; }
///
/// Gets the VEX assessment relationships.
///
public required IReadOnlyList Assessments { get; init; }
///
/// Gets the CVSS assessment relationships.
///
public IReadOnlyList CvssAssessments { get; init; } = Array.Empty();
///
/// Gets the EPSS assessment relationships.
///
public IReadOnlyList EpssAssessments { get; init; } = Array.Empty();
///
/// Gets all elements combined.
///
public IEnumerable AllElements =>
Vulnerabilities
.Concat(Assessments)
.Concat(CvssAssessments)
.Concat(EpssAssessments);
}
///
/// Represents a VEX consensus containing multiple statements.
///
public sealed record VexConsensus
{
///
/// Gets the document identifier.
///
public required string DocumentId { get; init; }
///
/// Gets the document version.
///
public string? Version { get; init; }
///
/// Gets the statements in this consensus.
///
public required IReadOnlyList Statements { get; init; }
///
/// Gets the supplier/author.
///
public string? Author { get; init; }
///
/// Gets the timestamp.
///
public DateTimeOffset? Timestamp { get; init; }
}
///
/// Represents an OpenVEX statement.
///
public sealed record OpenVexStatement
{
///
/// Gets the vulnerability ID (e.g., CVE-2026-1234).
///
public required string VulnerabilityId { get; init; }
///
/// Gets the product ID (e.g., PURL).
///
public required string ProductId { get; init; }
///
/// Gets the VEX status.
///
public required VexStatus Status { get; init; }
///
/// Gets the justification for not_affected status.
///
public VexJustification? Justification { get; init; }
///
/// Gets the status notes.
///
public string? StatusNotes { get; init; }
///
/// Gets the impact statement.
///
public string? ImpactStatement { get; init; }
///
/// Gets the action statement for affected status.
///
public string? ActionStatement { get; init; }
///
/// Gets the action statement deadline.
///
public DateTimeOffset? ActionStatementTime { get; init; }
///
/// Gets the statement timestamp.
///
public DateTimeOffset? Timestamp { get; init; }
///
/// Gets the supplier/author.
///
public string? Supplier { get; init; }
///
/// Gets CVSS v3 data if available.
///
public CvssV3Data? CvssV3 { get; init; }
///
/// Gets EPSS data if available.
///
public EpssData? Epss { get; init; }
}
///
/// VEX status values.
///
public enum VexStatus
{
/// The product is affected by the vulnerability.
Affected,
/// The product is not affected by the vulnerability.
NotAffected,
/// The vulnerability is fixed in the product.
Fixed,
/// The status is under investigation.
UnderInvestigation
}
///
/// VEX justification values for not_affected status.
///
public enum VexJustification
{
/// The component is not present.
ComponentNotPresent,
/// The vulnerable code is not present.
VulnerableCodeNotPresent,
/// The vulnerable code cannot be controlled by an adversary.
VulnerableCodeCannotBeControlledByAdversary,
/// The vulnerable code is not in the execute path.
VulnerableCodeNotInExecutePath,
/// Inline mitigations already exist.
InlineMitigationsAlreadyExist
}
///
/// CVSS v3 scoring data.
/// Sprint: SPRINT_20260107_004_004 Task SP-007
///
public sealed record CvssV3Data
{
/// Gets the CVSS v3 base score (0.0-10.0).
public decimal? BaseScore { get; init; }
/// Gets the CVSS v3 vector string.
public string? VectorString { get; init; }
/// Gets the temporal score if available.
public decimal? TemporalScore { get; init; }
/// Gets the environmental score if available.
public decimal? EnvironmentalScore { get; init; }
/// Gets when the score was published.
public DateTimeOffset? PublishedTime { get; init; }
/// Gets when the score was modified.
public DateTimeOffset? ModifiedTime { get; init; }
/// Gets the source of the CVSS data.
public string? Source { get; init; }
}
///
/// EPSS (Exploit Prediction Scoring System) data.
/// Sprint: SPRINT_20260107_004_004 Task SP-007
///
public sealed record EpssData
{
/// Gets the EPSS probability (0.0-1.0).
public decimal? Probability { get; init; }
/// Gets the EPSS percentile (0.0-1.0).
public decimal? Percentile { get; init; }
/// Gets the date of the EPSS score.
public DateTimeOffset? ScoreDate { get; init; }
}