- 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.
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; }
}
VexAdvisoryLink
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
-
CVE identifiers remain unchanged as they are globally authoritative:
CVE-2024-1234 → CVE-2024-1234 -
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
- Case normalization: All identifiers are normalized to uppercase internally
- Stable ordering: Links are ordered by original first, then alphabetically
- Deduplication: Duplicate aliases are removed during canonicalization
- 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
Related Contracts
- VEX Lens Contract - Uses advisory keys for linkset correlation
- Risk Scoring Contract - References advisory IDs in findings