Files
git.stella-ops.org/docs/contracts/advisory-key.md
master cc69d332e3
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Add unit tests for RabbitMq and Udp transport servers and clients
- Implemented comprehensive unit tests for RabbitMqTransportServer, covering constructor, disposal, connection management, event handlers, and exception handling.
- Added configuration tests for RabbitMqTransportServer to validate SSL, durable queues, auto-recovery, and custom virtual host options.
- Created unit tests for UdpFrameProtocol, including frame parsing and serialization, header size validation, and round-trip data preservation.
- Developed tests for UdpTransportClient, focusing on connection handling, event subscriptions, and exception scenarios.
- Established tests for UdpTransportServer, ensuring proper start/stop behavior, connection state management, and event handling.
- Included tests for UdpTransportOptions to verify default values and modification capabilities.
- Enhanced service registration tests for Udp transport services in the dependency injection container.
2025-12-05 19:01:12 +02:00

4.9 KiB

Advisory Key Canonicalization Contract

Contract ID: CONTRACT-ADVISORY-KEY-001 Version: 1.0 Status: Published Last Updated: 2025-12-05

Overview

This contract defines the canonicalization rules for advisory and vulnerability identifiers used throughout StellaOps. It ensures consistent correlation of VEX observations, policy findings, and risk assessments across different identifier formats.

Implementation Reference

Source: src/Excititor/__Libraries/StellaOps.Excititor.Core/Canonicalization/VexAdvisoryKeyCanonicalizer.cs

Data Model

VexCanonicalAdvisoryKey

The canonical advisory key structure returned by the canonicalizer.

public sealed record VexCanonicalAdvisoryKey
{
    /// <summary>
    /// The canonical advisory key used for correlation and storage.
    /// </summary>
    public string AdvisoryKey { get; }

    /// <summary>
    /// The scope/authority level of the advisory.
    /// </summary>
    public VexAdvisoryScope Scope { get; }

    /// <summary>
    /// Original and alias identifiers preserved for traceability.
    /// </summary>
    public ImmutableArray<VexAdvisoryLink> Links { get; }
}

Represents a link to an original or alias advisory identifier.

public sealed record VexAdvisoryLink
{
    /// <summary>
    /// The advisory identifier value.
    /// </summary>
    public string Identifier { get; }

    /// <summary>
    /// The type of identifier (cve, ghsa, rhsa, dsa, usn, msrc, other).
    /// </summary>
    public string Type { get; }

    /// <summary>
    /// True if this is the original identifier provided at ingest time.
    /// </summary>
    public bool IsOriginal { get; }
}

VexAdvisoryScope

The scope/authority level of an advisory.

Value Code Description Examples
Global 1 Global identifiers CVE-2024-1234
Ecosystem 2 Ecosystem-specific GHSA-xxxx-xxxx-xxxx
Vendor 3 Vendor-specific RHSA-2024:1234, ADV-2024-1234
Distribution 4 Distribution-specific DSA-1234-1, USN-1234-1
Unknown 0 Unclassified Custom identifiers

Canonicalization Rules

Identifier Patterns

Pattern Regex Scope Type
CVE ^CVE-\d{4}-\d{4,}$ Global cve
GHSA ^GHSA-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}$ Ecosystem ghsa
RHSA ^RH[A-Z]{2}-\d{4}:\d+$ Vendor rhsa
DSA ^DSA-\d+(-\d+)?$ Distribution dsa
USN ^USN-\d+(-\d+)?$ Distribution usn
MSRC ^(ADV|CVE)-\d{4}-\d+$ Vendor msrc
Other * Unknown other

Canonical Key Format

  1. CVE identifiers remain unchanged as they are globally authoritative:

    CVE-2024-1234 → CVE-2024-1234
    
  2. Non-CVE identifiers are prefixed with a scope indicator:

    GHSA-xxxx-xxxx-xxxx → ECO:GHSA-XXXX-XXXX-XXXX
    RHSA-2024:1234      → VND:RHSA-2024:1234
    DSA-1234-1          → DST:DSA-1234-1
    custom-id           → UNK:CUSTOM-ID
    

Scope Prefixes

Scope Prefix
Ecosystem ECO:
Vendor VND:
Distribution DST:
Unknown UNK:

Usage

Canonicalizing an Identifier

var canonicalizer = new VexAdvisoryKeyCanonicalizer();

// Simple canonicalization
var result = canonicalizer.Canonicalize("CVE-2024-1234");
// result.AdvisoryKey = "CVE-2024-1234"
// result.Scope = VexAdvisoryScope.Global

// With aliases
var result = canonicalizer.Canonicalize(
    "GHSA-xxxx-xxxx-xxxx",
    aliases: new[] { "CVE-2024-1234" });
// result.AdvisoryKey = "ECO:GHSA-XXXX-XXXX-XXXX"
// result.Links contains both identifiers

Extracting CVE from Aliases

var cve = canonicalizer.ExtractCveFromAliases(
    new[] { "GHSA-xxxx-xxxx-xxxx", "CVE-2024-1234" });
// cve = "CVE-2024-1234"

JSON Serialization

{
  "advisory_key": "CVE-2024-1234",
  "scope": "global",
  "links": [
    {
      "identifier": "CVE-2024-1234",
      "type": "cve",
      "is_original": true
    },
    {
      "identifier": "GHSA-xxxx-xxxx-xxxx",
      "type": "ghsa",
      "is_original": false
    }
  ]
}

Determinism Guarantees

  1. Case normalization: All identifiers are normalized to uppercase internally
  2. Stable ordering: Links are ordered by original first, then alphabetically
  3. Deduplication: Duplicate aliases are removed during canonicalization
  4. Idempotence: Canonicalizing the same input always produces the same output

Unblocks

This contract unblocks the following tasks:

  • EXCITITOR-POLICY-20-001
  • EXCITITOR-POLICY-20-002
  • EXCITITOR-VULN-29-001
  • EXCITITOR-VULN-29-002
  • EXCITITOR-VULN-29-004
  • CONCELIER-VEXLENS-30-001