Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Added IPackRunIncidentModeService interface for managing incident mode activation, deactivation, and status retrieval. - Created PackRunIncidentModeService class implementing the service interface with methods for activating, deactivating, and escalating incident modes. - Introduced incident mode status model (PackRunIncidentModeStatus) and related enums for escalation levels and activation sources. - Developed retention policy, telemetry settings, and debug capture settings models to manage incident mode configurations. - Implemented SLO breach notification handling to activate incident mode based on severity. - Added in-memory store (InMemoryPackRunIncidentModeStore) for testing purposes. - Created comprehensive unit tests for incident mode service, covering activation, deactivation, status retrieval, and SLO breach handling.
607 lines
16 KiB
JSON
607 lines
16 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://stella-ops.org/schemas/risk-api.schema.json",
|
|
"title": "StellaOps Risk API Schema",
|
|
"description": "Schema for Risk API endpoints, scoring models, and factor weights. Unblocks DOCS-RISK-67-002 through 68-002 (5+ tasks).",
|
|
"type": "object",
|
|
"definitions": {
|
|
"RiskScore": {
|
|
"type": "object",
|
|
"description": "Computed risk score",
|
|
"required": ["score", "rating", "computed_at"],
|
|
"properties": {
|
|
"score": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 100,
|
|
"description": "Numeric risk score (0-100)"
|
|
},
|
|
"rating": {
|
|
"type": "string",
|
|
"enum": ["critical", "high", "medium", "low", "info", "none"],
|
|
"description": "Risk rating category"
|
|
},
|
|
"computed_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"confidence": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"description": "Confidence level in the score (0-1)"
|
|
},
|
|
"factors": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/RiskFactor"
|
|
}
|
|
},
|
|
"trend": {
|
|
"$ref": "#/definitions/RiskTrend"
|
|
}
|
|
}
|
|
},
|
|
"RiskFactor": {
|
|
"type": "object",
|
|
"description": "Individual risk factor contribution",
|
|
"required": ["factor_id", "name", "value", "weight", "contribution"],
|
|
"properties": {
|
|
"factor_id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"category": {
|
|
"type": "string",
|
|
"enum": ["vulnerability", "exposure", "asset", "context", "temporal", "environmental"]
|
|
},
|
|
"value": {
|
|
"type": "number",
|
|
"description": "Raw factor value"
|
|
},
|
|
"normalized_value": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"description": "Normalized value (0-1)"
|
|
},
|
|
"weight": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"description": "Factor weight in scoring model"
|
|
},
|
|
"contribution": {
|
|
"type": "number",
|
|
"description": "Contribution to final score"
|
|
},
|
|
"source": {
|
|
"type": "string",
|
|
"description": "Data source for this factor"
|
|
},
|
|
"evidence": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Evidence supporting this factor"
|
|
}
|
|
}
|
|
},
|
|
"RiskTrend": {
|
|
"type": "object",
|
|
"description": "Risk score trend over time",
|
|
"properties": {
|
|
"direction": {
|
|
"type": "string",
|
|
"enum": ["improving", "stable", "degrading"]
|
|
},
|
|
"change_percent": {
|
|
"type": "number",
|
|
"description": "Percent change from previous period"
|
|
},
|
|
"period": {
|
|
"type": "string",
|
|
"enum": ["24h", "7d", "30d"]
|
|
},
|
|
"previous_score": {
|
|
"type": "number"
|
|
}
|
|
}
|
|
},
|
|
"RiskProfile": {
|
|
"type": "object",
|
|
"description": "Risk profile configuration",
|
|
"required": ["profile_id", "name"],
|
|
"properties": {
|
|
"profile_id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"description": {
|
|
"type": "string"
|
|
},
|
|
"scoring_model": {
|
|
"$ref": "#/definitions/ScoringModel"
|
|
},
|
|
"thresholds": {
|
|
"$ref": "#/definitions/RiskThresholds"
|
|
},
|
|
"factor_weights": {
|
|
"type": "object",
|
|
"additionalProperties": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1
|
|
}
|
|
},
|
|
"enabled_factors": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
}
|
|
}
|
|
},
|
|
"ScoringModel": {
|
|
"type": "object",
|
|
"description": "Risk scoring model configuration",
|
|
"required": ["model_id", "name"],
|
|
"properties": {
|
|
"model_id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"version": {
|
|
"type": "string"
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["weighted_sum", "geometric_mean", "max_severity", "custom"],
|
|
"description": "Scoring algorithm type"
|
|
},
|
|
"base_score_source": {
|
|
"type": "string",
|
|
"enum": ["cvss_v3", "cvss_v4", "epss", "custom"],
|
|
"description": "Primary score source"
|
|
},
|
|
"modifiers": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/ScoreModifier"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"ScoreModifier": {
|
|
"type": "object",
|
|
"description": "Score modifier rule",
|
|
"required": ["modifier_id", "condition", "adjustment"],
|
|
"properties": {
|
|
"modifier_id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"condition": {
|
|
"type": "string",
|
|
"description": "Condition expression (e.g., 'kev == true')"
|
|
},
|
|
"adjustment": {
|
|
"type": "number",
|
|
"description": "Score adjustment (can be positive or negative)"
|
|
},
|
|
"adjustment_type": {
|
|
"type": "string",
|
|
"enum": ["absolute", "percent", "multiply"],
|
|
"default": "absolute"
|
|
},
|
|
"priority": {
|
|
"type": "integer",
|
|
"description": "Order of modifier application"
|
|
}
|
|
}
|
|
},
|
|
"RiskThresholds": {
|
|
"type": "object",
|
|
"description": "Risk rating thresholds",
|
|
"properties": {
|
|
"critical": {
|
|
"type": "number",
|
|
"default": 90,
|
|
"description": "Score >= this is Critical"
|
|
},
|
|
"high": {
|
|
"type": "number",
|
|
"default": 70,
|
|
"description": "Score >= this is High"
|
|
},
|
|
"medium": {
|
|
"type": "number",
|
|
"default": 40,
|
|
"description": "Score >= this is Medium"
|
|
},
|
|
"low": {
|
|
"type": "number",
|
|
"default": 10,
|
|
"description": "Score >= this is Low"
|
|
},
|
|
"info": {
|
|
"type": "number",
|
|
"default": 0,
|
|
"description": "Score >= this is Info"
|
|
}
|
|
}
|
|
},
|
|
"RiskAssessmentRequest": {
|
|
"type": "object",
|
|
"description": "Request to compute risk for an entity",
|
|
"required": ["entity_type", "entity_id"],
|
|
"properties": {
|
|
"entity_type": {
|
|
"type": "string",
|
|
"enum": ["vulnerability", "asset", "component", "project", "tenant"]
|
|
},
|
|
"entity_id": {
|
|
"type": "string"
|
|
},
|
|
"profile_id": {
|
|
"type": "string",
|
|
"description": "Risk profile to use (uses default if not specified)"
|
|
},
|
|
"include_factors": {
|
|
"type": "boolean",
|
|
"default": true,
|
|
"description": "Include factor breakdown in response"
|
|
},
|
|
"include_trend": {
|
|
"type": "boolean",
|
|
"default": false,
|
|
"description": "Include trend analysis"
|
|
},
|
|
"context": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"description": "Additional context for scoring"
|
|
}
|
|
}
|
|
},
|
|
"RiskAssessmentResponse": {
|
|
"type": "object",
|
|
"description": "Risk assessment result",
|
|
"required": ["assessment_id", "entity_type", "entity_id", "score"],
|
|
"properties": {
|
|
"assessment_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"entity_type": {
|
|
"type": "string"
|
|
},
|
|
"entity_id": {
|
|
"type": "string"
|
|
},
|
|
"profile_id": {
|
|
"type": "string"
|
|
},
|
|
"score": {
|
|
"$ref": "#/definitions/RiskScore"
|
|
},
|
|
"explainability": {
|
|
"$ref": "#/definitions/RiskExplainability"
|
|
},
|
|
"recommendations": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/RiskRecommendation"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"RiskExplainability": {
|
|
"type": "object",
|
|
"description": "Human-readable explanation of risk score",
|
|
"properties": {
|
|
"summary": {
|
|
"type": "string",
|
|
"description": "One-line summary"
|
|
},
|
|
"narrative": {
|
|
"type": "string",
|
|
"description": "Detailed explanation"
|
|
},
|
|
"top_factors": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"factor": {
|
|
"type": "string"
|
|
},
|
|
"impact": {
|
|
"type": "string",
|
|
"enum": ["major", "moderate", "minor"]
|
|
},
|
|
"explanation": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"description": "Top contributing factors"
|
|
},
|
|
"comparisons": {
|
|
"type": "object",
|
|
"properties": {
|
|
"org_percentile": {
|
|
"type": "number",
|
|
"description": "Percentile within organization"
|
|
},
|
|
"industry_percentile": {
|
|
"type": "number",
|
|
"description": "Percentile within industry"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"RiskRecommendation": {
|
|
"type": "object",
|
|
"description": "Risk mitigation recommendation",
|
|
"required": ["recommendation_id", "action"],
|
|
"properties": {
|
|
"recommendation_id": {
|
|
"type": "string"
|
|
},
|
|
"action": {
|
|
"type": "string",
|
|
"description": "Recommended action"
|
|
},
|
|
"priority": {
|
|
"type": "string",
|
|
"enum": ["critical", "high", "medium", "low"]
|
|
},
|
|
"impact_estimate": {
|
|
"type": "number",
|
|
"description": "Estimated score reduction if implemented"
|
|
},
|
|
"effort": {
|
|
"type": "string",
|
|
"enum": ["minimal", "moderate", "significant"]
|
|
},
|
|
"related_factors": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"RiskAggregation": {
|
|
"type": "object",
|
|
"description": "Aggregated risk across multiple entities",
|
|
"required": ["aggregation_id", "entity_type", "count", "scores"],
|
|
"properties": {
|
|
"aggregation_id": {
|
|
"type": "string"
|
|
},
|
|
"entity_type": {
|
|
"type": "string"
|
|
},
|
|
"scope": {
|
|
"type": "string",
|
|
"description": "Aggregation scope (e.g., project, tenant)"
|
|
},
|
|
"count": {
|
|
"type": "integer",
|
|
"description": "Number of entities aggregated"
|
|
},
|
|
"scores": {
|
|
"type": "object",
|
|
"properties": {
|
|
"average": {
|
|
"type": "number"
|
|
},
|
|
"median": {
|
|
"type": "number"
|
|
},
|
|
"max": {
|
|
"type": "number"
|
|
},
|
|
"min": {
|
|
"type": "number"
|
|
},
|
|
"p95": {
|
|
"type": "number"
|
|
}
|
|
}
|
|
},
|
|
"distribution": {
|
|
"type": "object",
|
|
"properties": {
|
|
"critical": { "type": "integer" },
|
|
"high": { "type": "integer" },
|
|
"medium": { "type": "integer" },
|
|
"low": { "type": "integer" },
|
|
"info": { "type": "integer" }
|
|
}
|
|
},
|
|
"trend": {
|
|
"$ref": "#/definitions/RiskTrend"
|
|
}
|
|
}
|
|
},
|
|
"RiskApiEndpoint": {
|
|
"type": "object",
|
|
"description": "Risk API endpoint definition",
|
|
"required": ["path", "method", "operation_id"],
|
|
"properties": {
|
|
"path": {
|
|
"type": "string"
|
|
},
|
|
"method": {
|
|
"type": "string",
|
|
"enum": ["GET", "POST", "PUT", "DELETE"]
|
|
},
|
|
"operation_id": {
|
|
"type": "string"
|
|
},
|
|
"summary": {
|
|
"type": "string"
|
|
},
|
|
"request_schema": {
|
|
"type": "string",
|
|
"description": "Reference to request schema"
|
|
},
|
|
"response_schema": {
|
|
"type": "string",
|
|
"description": "Reference to response schema"
|
|
},
|
|
"scopes": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Required OAuth scopes"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"properties": {
|
|
"endpoints": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/RiskApiEndpoint"
|
|
}
|
|
},
|
|
"profiles": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/RiskProfile"
|
|
}
|
|
}
|
|
},
|
|
"examples": [
|
|
{
|
|
"endpoints": [
|
|
{
|
|
"path": "/api/v1/risk/assess",
|
|
"method": "POST",
|
|
"operation_id": "assessRisk",
|
|
"summary": "Compute risk score for an entity",
|
|
"request_schema": "RiskAssessmentRequest",
|
|
"response_schema": "RiskAssessmentResponse",
|
|
"scopes": ["risk:read"]
|
|
},
|
|
{
|
|
"path": "/api/v1/risk/profiles",
|
|
"method": "GET",
|
|
"operation_id": "listRiskProfiles",
|
|
"summary": "List available risk profiles",
|
|
"response_schema": "RiskProfile[]",
|
|
"scopes": ["risk:read"]
|
|
},
|
|
{
|
|
"path": "/api/v1/risk/aggregate",
|
|
"method": "POST",
|
|
"operation_id": "aggregateRisk",
|
|
"summary": "Compute aggregated risk across entities",
|
|
"response_schema": "RiskAggregation",
|
|
"scopes": ["risk:read"]
|
|
},
|
|
{
|
|
"path": "/api/v1/risk/profiles/{profile_id}",
|
|
"method": "PUT",
|
|
"operation_id": "updateRiskProfile",
|
|
"summary": "Update a risk profile",
|
|
"request_schema": "RiskProfile",
|
|
"scopes": ["risk:write", "admin"]
|
|
},
|
|
{
|
|
"path": "/api/v1/risk/explain/{assessment_id}",
|
|
"method": "GET",
|
|
"operation_id": "explainRisk",
|
|
"summary": "Get detailed explanation for a risk assessment",
|
|
"response_schema": "RiskExplainability",
|
|
"scopes": ["risk:read"]
|
|
}
|
|
],
|
|
"profiles": [
|
|
{
|
|
"profile_id": "default",
|
|
"name": "Default Risk Profile",
|
|
"description": "Standard risk scoring with balanced factor weights",
|
|
"scoring_model": {
|
|
"model_id": "weighted-sum-v1",
|
|
"name": "Weighted Sum Model",
|
|
"version": "1.0.0",
|
|
"type": "weighted_sum",
|
|
"base_score_source": "cvss_v3",
|
|
"modifiers": [
|
|
{
|
|
"modifier_id": "kev-boost",
|
|
"name": "KEV Exploit Known",
|
|
"condition": "kev == true",
|
|
"adjustment": 15,
|
|
"adjustment_type": "absolute",
|
|
"priority": 1
|
|
},
|
|
{
|
|
"modifier_id": "reachability-reduction",
|
|
"name": "Not Reachable",
|
|
"condition": "reachability == 'not_reachable'",
|
|
"adjustment": -30,
|
|
"adjustment_type": "absolute",
|
|
"priority": 2
|
|
},
|
|
{
|
|
"modifier_id": "vex-not-affected",
|
|
"name": "VEX Not Affected",
|
|
"condition": "vex_status == 'not_affected'",
|
|
"adjustment": -50,
|
|
"adjustment_type": "absolute",
|
|
"priority": 3
|
|
}
|
|
]
|
|
},
|
|
"thresholds": {
|
|
"critical": 90,
|
|
"high": 70,
|
|
"medium": 40,
|
|
"low": 10,
|
|
"info": 0
|
|
},
|
|
"factor_weights": {
|
|
"cvss_base": 0.35,
|
|
"exploitability": 0.25,
|
|
"reachability": 0.20,
|
|
"asset_criticality": 0.10,
|
|
"exposure": 0.10
|
|
},
|
|
"enabled_factors": [
|
|
"cvss_base",
|
|
"exploitability",
|
|
"kev",
|
|
"epss",
|
|
"reachability",
|
|
"vex_status",
|
|
"asset_criticality",
|
|
"exposure",
|
|
"age"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|