Add unit tests for RabbitMq and Udp transport servers and clients
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
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.
This commit is contained in:
186
docs/contracts/advisory-key.md
Normal file
186
docs/contracts/advisory-key.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user