{ "$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" } ] } ] }