Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- 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.
187 lines
4.9 KiB
Markdown
187 lines
4.9 KiB
Markdown
# 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.
|
|
|
|
```csharp
|
|
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.
|
|
|
|
```csharp
|
|
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
|
|
|
|
```csharp
|
|
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
|
|
|
|
```csharp
|
|
var cve = canonicalizer.ExtractCveFromAliases(
|
|
new[] { "GHSA-xxxx-xxxx-xxxx", "CVE-2024-1234" });
|
|
// cve = "CVE-2024-1234"
|
|
```
|
|
|
|
## JSON Serialization
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
## Related Contracts
|
|
|
|
- [VEX Lens Contract](./vex-lens.md) - Uses advisory keys for linkset correlation
|
|
- [Risk Scoring Contract](./risk-scoring.md) - References advisory IDs in findings
|