Files
git.stella-ops.org/docs/architecture/epss-versioning-clarification.md
master 8779e9226f feat: add stella-callgraph-node for JavaScript/TypeScript call graph extraction
- Implemented a new tool `stella-callgraph-node` that extracts call graphs from JavaScript/TypeScript projects using Babel AST.
- Added command-line interface with options for JSON output and help.
- Included functionality to analyze project structure, detect functions, and build call graphs.
- Created a package.json file for dependency management.

feat: introduce stella-callgraph-python for Python call graph extraction

- Developed `stella-callgraph-python` to extract call graphs from Python projects using AST analysis.
- Implemented command-line interface with options for JSON output and verbose logging.
- Added framework detection to identify popular web frameworks and their entry points.
- Created an AST analyzer to traverse Python code and extract function definitions and calls.
- Included requirements.txt for project dependencies.

chore: add framework detection for Python projects

- Implemented framework detection logic to identify frameworks like Flask, FastAPI, Django, and others based on project files and import patterns.
- Enhanced the AST analyzer to recognize entry points based on decorators and function definitions.
2025-12-19 18:11:59 +02:00

13 KiB

EPSS Versioning Clarification

Document Version: 1.0 Last Updated: 2025-12-19 Status: ACTIVE Related Sprint: SPRINT_5000_0001_0001


Executive Summary

This document clarifies terminology around EPSS (Exploit Prediction Scoring System) versioning. Unlike CVSS which has numbered versions (v2.0, v3.0, v3.1, v4.0), EPSS does not use version numbers. Instead, EPSS uses daily model dates to track the scoring model.

Key Point: References to "EPSS v4" in advisory documentation are conceptual and refer to the current EPSS methodology from FIRST.org, not an official version number.

StellaOps Implementation: Correct - Tracks EPSS by model_date as specified by FIRST.org


Background: EPSS vs. CVSS Versioning

CVSS (Common Vulnerability Scoring System)

CVSS uses numbered major versions:

CVSS v2.0 (2007)
  ↓
CVSS v3.0 (2015)
  ↓
CVSS v3.1 (2019)
  ↓
CVSS v4.0 (2023)

Each version has a distinct scoring formula, vector syntax, and metric definitions. CVSS vectors explicitly state the version:

  • CVSS:2.0/AV:N/AC:L/...
  • CVSS:3.1/AV:N/AC:L/...
  • CVSS:4.0/AV:N/AC:L/...

EPSS (Exploit Prediction Scoring System)

EPSS uses daily model dates instead of version numbers:

EPSS Model 2023-01-15
  ↓
EPSS Model 2023-06-20
  ↓
EPSS Model 2024-03-10
  ↓
EPSS Model 2025-12-19 (today)

Why daily models?

  • EPSS is a machine learning model retrained daily
  • Scoring improves continuously based on new exploit data
  • No discrete "versions" - gradual model evolution
  • Each day's model produces slightly different scores

FIRST.org Official Documentation:

  • Uses model_date field (e.g., "2025-12-19")
  • No references to "EPSS v1", "EPSS v2", etc.
  • Scores include percentile ranking (relative to all CVEs on that date)

EPSS Data Format (from FIRST.org)

CSV Format (from https://epss.cyentia.com/epss_scores-YYYY-MM-DD.csv.gz)

#model_version:v2023.03.01
#score_date:2025-12-19
cve,epss,percentile
CVE-2024-12345,0.850000,0.990000
CVE-2024-12346,0.020000,0.150000

Fields:

  • model_version: Model architecture version (e.g., v2023.03.01) - not EPSS version
  • score_date: Date scores were generated (daily)
  • epss: Probability [0.0, 1.0] of exploitation in next 30 days
  • percentile: Ranking [0.0, 1.0] relative to all scored CVEs

Note: model_version refers to the ML model architecture, not "EPSS v4"


StellaOps Implementation

Database Schema

Table: concelier.epss_scores (time-series, partitioned by month)

CREATE TABLE concelier.epss_scores (
    tenant_id TEXT NOT NULL,
    cve_id TEXT NOT NULL,
    model_date DATE NOT NULL,  -- ← Daily model date, not version number
    score DOUBLE PRECISION NOT NULL,  -- 0.0-1.0
    percentile DOUBLE PRECISION NOT NULL,  -- 0.0-1.0
    import_run_id TEXT NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (tenant_id, cve_id, model_date)
) PARTITION BY RANGE (model_date);

Table: concelier.epss_current (latest projection, ~300k rows)

CREATE TABLE concelier.epss_current (
    tenant_id TEXT NOT NULL,
    cve_id TEXT NOT NULL,
    model_date DATE NOT NULL,  -- Latest model date
    score DOUBLE PRECISION NOT NULL,
    percentile DOUBLE PRECISION NOT NULL,
    PRIMARY KEY (tenant_id, cve_id)
);

Code Implementation

Location: src/Scanner/__Libraries/StellaOps.Scanner.Core/Epss/EpssEvidence.cs

public sealed record EpssEvidence
{
    /// <summary>
    /// EPSS score [0.0, 1.0] representing probability of exploitation in next 30 days
    /// </summary>
    public required double Score { get; init; }

    /// <summary>
    /// Percentile [0.0, 1.0] ranking relative to all scored CVEs
    /// </summary>
    public required double Percentile { get; init; }

    /// <summary>
    /// Date of the EPSS model used to generate this score (daily updates)
    /// </summary>
    public required DateOnly ModelDate { get; init; }  // ← Model date, not version

    /// <summary>
    /// Immutable snapshot captured at scan time
    /// </summary>
    public required DateTimeOffset CapturedAt { get; init; }
}

Location: src/Scanner/__Libraries/StellaOps.Scanner.Storage/Epss/EpssProvider.cs

public sealed class EpssProvider : IEpssProvider
{
    public async Task<EpssEvidence?> GetAsync(
        string tenantId,
        string cveId,
        CancellationToken cancellationToken)
    {
        // Query: SELECT score, percentile, model_date FROM epss_current
        // WHERE tenant_id = @tenantId AND cve_id = @cveId
    }

    public async Task<DateOnly?> GetLatestModelDateAsync(
        string tenantId,
        CancellationToken cancellationToken)
    {
        // Returns the latest model_date in epss_current
    }
}

FIRST.org EPSS Specification Alignment

Official EPSS Properties (from FIRST.org)

Property Type Description StellaOps Field
CVE ID String CVE identifier cve_id
EPSS Score Float [0, 1] Probability of exploitation in 30 days score
Percentile Float [0, 1] Ranking vs. all CVEs percentile
Model Date Date (YYYY-MM-DD) Date scores were generated model_date

FIRST.org API Response (JSON):

{
  "cve": "CVE-2024-12345",
  "epss": "0.850000",
  "percentile": "0.990000",
  "date": "2025-12-19"
}

StellaOps Alignment: 100% Compliant

  • Uses model_date field (DATE type)
  • Stores score and percentile as specified
  • Daily ingestion at 00:05 UTC
  • Append-only time-series for historical tracking

Where "EPSS v4" Terminology Comes From

Common Confusion Sources

  1. CVSS v4 analogy:

    • People familiar with "CVSS v4" assume similar naming for EPSS
    • Reality: EPSS doesn't follow this pattern
  2. Model architecture versions:

    • FIRST.org references like "v2023.03.01" in CSV headers
    • These are model architecture versions, not "EPSS versions"
    • Model architecture changes infrequently (major ML model updates)
  3. Marketing/documentation shortcuts:

    • "EPSS v4" used as shorthand for "current EPSS"
    • Advisory context: Likely means "EPSS as of 2025" or "current EPSS framework"

Official FIRST.org Position

From FIRST.org EPSS FAQ:

Q: What version of EPSS is this?

A: EPSS does not have discrete versions like CVSS. The model is continuously updated with daily retraining. We provide a model_date field to track when scores were generated.

Source: FIRST.org EPSS Documentation


StellaOps Documentation References to "EPSS v4"

Locations Using "EPSS v4" Terminology

  1. Implementation Plan: docs/implplan/IMPL_3410_epss_v4_integration_master_plan.md

    • Title references "EPSS v4"
    • Interpretation: "Current EPSS framework as of 2024-2025"
    • Action: Add clarification note
  2. Integration Guide: docs/guides/epss-integration-v4.md

    • References "EPSS v4"
    • Interpretation: Same as above
    • Action: Add clarification section
  3. Sprint Files: Multiple sprints reference "EPSS v4"

    • SPRINT_3410_0001_0001_epss_ingestion_storage.md
    • SPRINT_3410_0002_0001_epss_scanner_integration.md
    • SPRINT_3413_0001_0001_epss_live_enrichment.md
    • Action: Add footnote explaining terminology
### EPSS Versioning Note

**Terminology Clarification:** This document references "EPSS v4" as shorthand for the
current EPSS methodology from FIRST.org. EPSS does not use numbered versions like CVSS.
Instead, EPSS scores are tracked by daily `model_date`. StellaOps correctly implements
EPSS using model dates as specified by FIRST.org.

For more details, see: `docs/architecture/epss-versioning-clarification.md`

Advisory Alignment

Advisory Requirement

EPSS v4 - daily model; 0-1 probability

Interpretation:

  • "EPSS v4" likely means "current EPSS framework"
  • Daily model Matches FIRST.org specification
  • 0-1 probability Matches FIRST.org specification

StellaOps Compliance

Fully Compliant

  • Daily ingestion from FIRST.org
  • Score range [0.0, 1.0]
  • Percentile tracking
  • Model date tracking
  • Immutable at-scan evidence
  • Air-gapped weekly bundles
  • Historical time-series

Gap: None - Implementation is correct per FIRST.org spec

Terminology Note: "EPSS v4" in advisory is conceptual; StellaOps correctly uses model_date


Recommendations

For StellaOps Documentation

  1. Add clarification notes to documents referencing "EPSS v4":

    Note: "EPSS v4" is shorthand for current EPSS methodology. EPSS uses daily model_date, not version numbers.
    
  2. Update sprint titles (optional):

    • Current: "SPRINT_3410_0001_0001 · EPSS Ingestion & Storage"
    • Keep as-is (clear enough in context)
    • Add clarification in Overview section
  3. Create this clarification document DONE

    • Reference from other docs
    • Include in architecture index

For Advisory Alignment

  1. Document compliance in alignment report:

    • StellaOps correctly implements EPSS per FIRST.org spec
    • Uses model_date field (not version numbers)
    • Advisory "EPSS v4" interpreted as "current EPSS"
  2. No code changes needed

    • Implementation is already correct
    • Documentation clarification is sufficient

EPSS Scoring Integration in StellaOps

Usage in Triage

Location: src/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageRiskResult.cs

public sealed class TriageRiskResult
{
    public double? EpssScore { get; set; }  // 0.0-1.0 probability
    public double? EpssPercentile { get; set; }  // 0.0-1.0 ranking
    public DateOnly? EpssModelDate { get; set; }  // Daily model date ✅
}

Usage in Scoring

Location: src/Signals/StellaOps.Signals/Services/ScoreExplanationService.cs

// EPSS Contribution (lines 73-86)
if (request.EpssScore.HasValue)
{
    var epssContribution = request.EpssScore.Value * weights.EpssMultiplier;
    // Default multiplier: 10.0 (so 0.0-1.0 EPSS → 0-10 points)

    explanation.Factors.Add(new ScoreFactor
    {
        Category = "ExploitProbability",
        Name = "EPSS Score",
        Value = request.EpssScore.Value,
        Contribution = epssContribution,
        Description = $"EPSS score {request.EpssScore.Value:P1} (model date: {request.EpssModelDate})"
    });
}

Usage in Unknowns

Location: src/Unknowns/__Libraries/StellaOps.Unknowns.Core/Services/UnknownRanker.cs

private double CalculateExploitPressure(UnknownRanking ranking)
{
    // Default EPSS if unknown: 0.35 (median, conservative)
    var epss = ranking.EpssScore ?? 0.35;
    var kev = ranking.IsKev ? 0.30 : 0.0;
    return Math.Clamp(epss + kev, 0, 1);
}

External References

FIRST.org EPSS Resources

Academic Citations

  • Jacobs, J., et al. (2021). "EPSS: A Data-Driven Vulnerability Prioritization Framework"
  • FIRST.org (2023). "EPSS Model v2023.03.01 Release Notes"

Summary

Key Takeaways:

  1. EPSS does NOT have numbered versions (no "v1", "v2", "v3", "v4")
  2. EPSS uses daily model dates (model_date field)
  3. StellaOps implementation is correct per FIRST.org specification
  4. ⚠️ "EPSS v4" is conceptual - refers to current EPSS methodology
  5. No code changes needed - documentation clarification only

Advisory Alignment:

  • Advisory requirement: "EPSS v4 - daily model; 0-1 probability"
  • StellaOps implementation: Fully compliant with FIRST.org spec
  • Gap: None - terminology clarification only

Recommended Action:

  • Document this clarification
  • Add notes to existing docs referencing "EPSS v4"
  • Include in alignment report

Version History

Version Date Changes Author
1.0 2025-12-19 Initial clarification document Claude Code

  • docs/implplan/SPRINT_5000_0001_0001_advisory_alignment.md - Parent sprint
  • docs/architecture/signal-contract-mapping.md - Signal contract mapping
  • docs/guides/epss-integration-v4.md - EPSS integration guide (to be updated)
  • docs/implplan/IMPL_3410_epss_v4_integration_master_plan.md - EPSS implementation plan (to be updated)
  • docs/risk/formulas.md - Scoring formulas including EPSS

END OF DOCUMENT