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.
6.2 KiB
6.2 KiB
Risk Scoring Contract (66-002)
Contract ID: CONTRACT-RISK-SCORING-002
Version: 1.0
Status: Published
Last Updated: 2025-12-05
Overview
This contract defines the risk scoring interface used by the Policy Engine to calculate and prioritize vulnerability findings. It covers job requests, results, risk profiles, and signal definitions.
Implementation References
- Scoring Models:
src/Policy/StellaOps.Policy.Engine/Scoring/RiskScoringModels.cs - Risk Profile:
src/Policy/StellaOps.Policy.RiskProfile/Models/RiskProfileModel.cs - Attestation Schema:
src/Attestor/StellaOps.Attestor.Types/schemas/stellaops-risk-profile.v1.schema.json
Data Models
RiskScoringJobRequest
Request to create a risk scoring job.
{
"tenant_id": "string",
"context_id": "string",
"profile_id": "string",
"findings": [
{
"finding_id": "string",
"component_purl": "pkg:npm/lodash@4.17.20",
"advisory_id": "CVE-2024-1234",
"trigger": "created|updated|enriched|vex_applied"
}
],
"priority": "low|normal|high|emergency",
"correlation_id": "string (optional)",
"requested_at": "2025-12-05T00:00:00Z (optional)"
}
RiskScoringJob
A queued or completed risk scoring job.
{
"job_id": "string",
"tenant_id": "string",
"context_id": "string",
"profile_id": "string",
"profile_hash": "sha256:...",
"findings": [...],
"priority": "normal",
"status": "queued|running|completed|failed|cancelled",
"requested_at": "2025-12-05T00:00:00Z",
"started_at": "2025-12-05T00:00:01Z (optional)",
"completed_at": "2025-12-05T00:00:02Z (optional)",
"correlation_id": "string (optional)",
"error_message": "string (optional)"
}
RiskScoringResult
Result of scoring a single finding.
{
"finding_id": "string",
"profile_id": "string",
"profile_version": "1.0.0",
"raw_score": 0.75,
"normalized_score": 0.85,
"severity": "high",
"signal_values": {
"cvss": 7.5,
"kev": true,
"reachability": 0.9
},
"signal_contributions": {
"cvss": 0.4,
"kev": 0.3,
"reachability": 0.3
},
"override_applied": "kev-boost (optional)",
"override_reason": "Known Exploited Vulnerability (optional)",
"scored_at": "2025-12-05T00:00:02Z"
}
Risk Profile Model
RiskProfileModel
Defines how findings are scored and prioritized.
{
"id": "default-profile",
"version": "1.0.0",
"description": "Default risk profile for vulnerability prioritization",
"extends": "base-profile (optional)",
"signals": [
{
"name": "cvss",
"source": "nvd",
"type": "numeric",
"path": "/cvss/base_score",
"transform": "normalize_10",
"unit": "score"
},
{
"name": "kev",
"source": "cisa",
"type": "boolean",
"path": "/kev/in_catalog"
},
{
"name": "reachability",
"source": "scanner",
"type": "numeric",
"path": "/reachability/score"
}
],
"weights": {
"cvss": 0.4,
"kev": 0.3,
"reachability": 0.3
},
"overrides": {
"severity": [
{
"when": { "kev": true },
"set": "critical"
}
],
"decisions": [
{
"when": { "kev": true, "reachability": { "$gt": 0.8 } },
"action": "deny",
"reason": "KEV with high reachability"
}
]
},
"metadata": {}
}
Signal Types
| Type | Description | Value Range |
|---|---|---|
boolean |
True/false signal | true / false |
numeric |
Numeric signal | 0.0 to 1.0 (normalized) |
categorical |
Categorical signal | String values |
Severity Levels
| Level | JSON Value | Priority |
|---|---|---|
| Critical | "critical" |
1 (highest) |
| High | "high" |
2 |
| Medium | "medium" |
3 |
| Low | "low" |
4 |
| Informational | "informational" |
5 (lowest) |
Decision Actions
| Action | Description |
|---|---|
allow |
Finding is acceptable, no action required |
review |
Finding requires manual review |
deny |
Finding is not acceptable, blocks promotion |
Scoring Algorithm
Score Calculation
raw_score = Σ(signal_value × weight) for all signals
normalized_score = clamp(raw_score, 0.0, 1.0)
VEX Gate Provider
The VEX gate provider short-circuits scoring when a VEX denial is present:
if (signals.HasVexDenial)
return 0.0; // Fully mitigated
return Math.Max(signals.Values); // Otherwise, max signal
CVSS + KEV Provider
score = clamp01((cvss / 10.0) + kevBonus)
where kevBonus = kev ? 0.2 : 0.0
API Endpoints
Submit Scoring Job
POST /api/v1/risk/jobs
Content-Type: application/json
{
"tenant_id": "...",
"context_id": "...",
"profile_id": "...",
"findings": [...]
}
Response: 202 Accepted
{
"job_id": "...",
"status": "queued"
}
Get Job Status
GET /api/v1/risk/jobs/{job_id}
Response: 200 OK
{
"job_id": "...",
"status": "completed",
"results": [...]
}
Get Finding Score
GET /api/v1/risk/findings/{finding_id}/score
Response: 200 OK
{
"finding_id": "...",
"normalized_score": 0.85,
"severity": "high",
...
}
Finding Change Events
Events that trigger rescoring:
| Event | JSON Value | Description |
|---|---|---|
| Created | "created" |
New finding discovered |
| Updated | "updated" |
Finding metadata changed |
| Enriched | "enriched" |
New signals available |
| VEX Applied | "vex_applied" |
VEX status changed |
Determinism Guarantees
- Reproducible scores: Same inputs always produce same outputs
- Profile versioning: Profile hash included in results for traceability
- Signal ordering: Signals processed in deterministic order
- Timestamp precision: UTC ISO-8601 with millisecond precision
Unblocks
This contract unblocks the following tasks:
- LEDGER-RISK-67-001
- LEDGER-RISK-68-001
- LEDGER-RISK-69-001
- POLICY-RISK-67-003
- POLICY-RISK-68-001
- POLICY-RISK-68-002
Related Contracts
- Advisory Key Contract - Advisory ID canonicalization
- VEX Lens Contract - VEX evidence for scoring
- Export Bundle Contract - Score digest in exports