Files
git.stella-ops.org/docs/schemas/risk-scoring.schema.json
StellaOps Bot 05597616d6 feat: Add Go module and workspace test fixtures
- Created expected JSON files for Go modules and workspaces.
- Added go.mod and go.sum files for example projects.
- Implemented private module structure with expected JSON output.
- Introduced vendored dependencies with corresponding expected JSON.
- Developed PostgresGraphJobStore for managing graph jobs.
- Established SQL migration scripts for graph jobs schema.
- Implemented GraphJobRepository for CRUD operations on graph jobs.
- Created IGraphJobRepository interface for repository abstraction.
- Added unit tests for GraphJobRepository to ensure functionality.
2025-12-06 20:04:03 +02:00

365 lines
9.9 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stellaops.io/schemas/risk-scoring.v1.json",
"title": "RiskScoring",
"description": "Risk scoring contract for vulnerability prioritization - job requests, results, and profiles",
"type": "object",
"$defs": {
"RiskScoringJobRequest": {
"type": "object",
"description": "Request to create a risk scoring job",
"required": ["tenantId", "contextId", "profileId", "findings"],
"properties": {
"tenantId": {
"type": "string",
"description": "Tenant identifier"
},
"contextId": {
"type": "string",
"description": "Context/snapshot identifier"
},
"profileId": {
"type": "string",
"description": "Risk profile to use for scoring"
},
"findings": {
"type": "array",
"items": {
"$ref": "#/$defs/FindingInput"
},
"minItems": 1
},
"priority": {
"$ref": "#/$defs/JobPriority"
},
"correlationId": {
"type": "string",
"description": "Optional correlation ID for tracing"
},
"requestedAt": {
"type": "string",
"format": "date-time",
"description": "Request timestamp (defaults to now)"
}
}
},
"FindingInput": {
"type": "object",
"required": ["findingId", "componentPurl", "advisoryId", "trigger"],
"properties": {
"findingId": {
"type": "string",
"description": "Finding identifier"
},
"componentPurl": {
"type": "string",
"description": "Package URL of affected component",
"examples": ["pkg:npm/lodash@4.17.20", "pkg:maven/org.apache.log4j/log4j-core@2.14.1"]
},
"advisoryId": {
"type": "string",
"description": "Advisory/CVE identifier",
"examples": ["CVE-2024-1234"]
},
"trigger": {
"$ref": "#/$defs/ScoringTrigger"
}
}
},
"ScoringTrigger": {
"type": "string",
"description": "Event that triggered rescoring",
"enum": ["created", "updated", "enriched", "vex_applied"]
},
"JobPriority": {
"type": "string",
"description": "Job priority level",
"enum": ["low", "normal", "high", "emergency"],
"default": "normal"
},
"RiskScoringJob": {
"type": "object",
"description": "A queued or completed risk scoring job",
"required": ["jobId", "tenantId", "contextId", "profileId", "status"],
"properties": {
"jobId": {
"type": "string",
"description": "Unique job identifier"
},
"tenantId": {
"type": "string"
},
"contextId": {
"type": "string"
},
"profileId": {
"type": "string"
},
"profileHash": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "SHA-256 hash of profile for reproducibility"
},
"findings": {
"type": "array",
"items": {
"$ref": "#/$defs/FindingInput"
}
},
"priority": {
"$ref": "#/$defs/JobPriority"
},
"status": {
"$ref": "#/$defs/JobStatus"
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"startedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"correlationId": {
"type": "string"
},
"errorMessage": {
"type": "string"
}
}
},
"JobStatus": {
"type": "string",
"description": "Job execution status",
"enum": ["queued", "running", "completed", "failed", "cancelled"]
},
"RiskScoringResult": {
"type": "object",
"description": "Result of scoring a single finding",
"required": ["findingId", "profileId", "profileVersion", "rawScore", "normalizedScore", "severity", "scoredAt"],
"properties": {
"findingId": {
"type": "string"
},
"profileId": {
"type": "string"
},
"profileVersion": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+$"
},
"rawScore": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Unweighted sum of signal values"
},
"normalizedScore": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Weighted and clamped final score"
},
"severity": {
"$ref": "#/$defs/Severity"
},
"signalValues": {
"type": "object",
"description": "Individual signal values",
"additionalProperties": {
"oneOf": [
{"type": "number"},
{"type": "boolean"}
]
},
"examples": [{"cvss": 7.5, "kev": true, "reachability": 0.9}]
},
"signalContributions": {
"type": "object",
"description": "Weighted contribution of each signal",
"additionalProperties": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"overrideApplied": {
"type": "string",
"description": "Name of override rule if applied"
},
"overrideReason": {
"type": "string",
"description": "Human-readable reason for override"
},
"scoredAt": {
"type": "string",
"format": "date-time"
}
}
},
"Severity": {
"type": "string",
"description": "Risk severity level",
"enum": ["critical", "high", "medium", "low", "informational"]
},
"RiskProfileModel": {
"type": "object",
"description": "Risk profile defining scoring rules",
"required": ["id", "version", "signals", "weights"],
"properties": {
"id": {
"type": "string",
"description": "Profile identifier",
"examples": ["default-profile", "critical-only"]
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+$"
},
"description": {
"type": "string"
},
"extends": {
"type": "string",
"description": "Parent profile to inherit from"
},
"signals": {
"type": "array",
"items": {
"$ref": "#/$defs/RiskSignal"
},
"minItems": 1
},
"weights": {
"type": "object",
"description": "Signal name to weight mapping (must sum to 1.0)",
"additionalProperties": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"overrides": {
"$ref": "#/$defs/RiskOverrides"
},
"metadata": {
"type": "object",
"additionalProperties": true
}
}
},
"RiskSignal": {
"type": "object",
"description": "Definition of a scoring signal",
"required": ["name", "source", "type"],
"properties": {
"name": {
"type": "string",
"examples": ["cvss", "kev", "reachability", "fix_available"]
},
"source": {
"type": "string",
"examples": ["nvd", "cisa", "scanner", "vex"]
},
"type": {
"$ref": "#/$defs/SignalType"
},
"path": {
"type": "string",
"description": "JSON Pointer to evidence value",
"examples": ["/cvss/base_score", "/kev/in_catalog"]
},
"transform": {
"type": "string",
"description": "Normalization transform to apply",
"examples": ["normalize_10", "invert", "threshold_0.5"]
},
"unit": {
"type": "string",
"examples": ["score", "percent", "days"]
}
}
},
"SignalType": {
"type": "string",
"description": "Signal data type",
"enum": ["boolean", "numeric", "categorical"]
},
"RiskOverrides": {
"type": "object",
"description": "Override rules for severity and decisions",
"properties": {
"severity": {
"type": "array",
"items": {
"$ref": "#/$defs/SeverityOverride"
}
},
"decisions": {
"type": "array",
"items": {
"$ref": "#/$defs/DecisionOverride"
}
}
}
},
"SeverityOverride": {
"type": "object",
"required": ["when", "set"],
"properties": {
"when": {
"type": "object",
"description": "Condition to match (signal name to value/expression)",
"additionalProperties": true
},
"set": {
"$ref": "#/$defs/Severity"
}
}
},
"DecisionOverride": {
"type": "object",
"required": ["when", "action"],
"properties": {
"when": {
"type": "object",
"additionalProperties": true
},
"action": {
"$ref": "#/$defs/DecisionAction"
},
"reason": {
"type": "string"
}
}
},
"DecisionAction": {
"type": "string",
"description": "Policy decision action",
"enum": ["allow", "review", "deny"]
}
},
"examples": [
{
"jobId": "job-12345",
"tenantId": "default",
"contextId": "ctx-abcde",
"profileId": "default-profile",
"profileHash": "sha256:abc123def456...",
"status": "completed",
"findings": [
{
"findingId": "finding-001",
"componentPurl": "pkg:npm/lodash@4.17.20",
"advisoryId": "CVE-2024-1234",
"trigger": "created"
}
]
}
]
}