Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
- TechniqueRiskProfile model: per-technique risk scoring (0-100) - 4-factor weighted scoring: detection_gap(35%) + threat_actors(30%) + osint(20%) + test_failures(15%) - Risk levels: critical(≥75) / high(≥50) / medium(≥25) / low(≥10) / info - Detailed scoring_breakdown (JSONB) + actionable recommendations per technique - Router /api/v1/risk: compute-all, compute-one, list, matrix, summary, recommendations, top - Alembic migration b038risk (raw SQL, idempotent) - QA script: 60+ tests across all endpoints Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
1.9 KiB
Python
72 lines
1.9 KiB
Python
"""Phase 12: Risk Intelligence schemas."""
|
|
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Optional
|
|
from uuid import UUID
|
|
|
|
from pydantic import BaseModel, ConfigDict
|
|
|
|
VALID_RISK_LEVELS = ["critical", "high", "medium", "low", "info"]
|
|
|
|
|
|
class TechniqueRiskProfileOut(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: UUID
|
|
technique_id: UUID
|
|
risk_score: float
|
|
likelihood: float
|
|
impact: float
|
|
risk_level: str
|
|
detection_gap: float
|
|
threat_actor_count: int
|
|
osint_signal_count: int
|
|
test_fail_count: int
|
|
test_total_count: int
|
|
test_failure_rate: float
|
|
confidence_level: float
|
|
scoring_breakdown: Optional[Dict[str, Any]]
|
|
recommendations: Optional[List[str]]
|
|
computed_at: datetime
|
|
is_stale: bool
|
|
|
|
|
|
class RiskMatrixEntry(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
technique_id: UUID
|
|
technique_name: Optional[str] = None
|
|
technique_tid: Optional[str] = None # e.g. "T1059"
|
|
risk_score: float
|
|
likelihood: float
|
|
impact: float
|
|
risk_level: str
|
|
detection_gap: float
|
|
computed_at: datetime
|
|
|
|
|
|
class RiskSummary(BaseModel):
|
|
total_techniques: int
|
|
scored_techniques: int
|
|
stale_count: int
|
|
by_level: Dict[str, int] # {"critical": 3, "high": 12, ...}
|
|
avg_risk_score: float
|
|
top_risks: List[RiskMatrixEntry]
|
|
|
|
|
|
class RecommendationItem(BaseModel):
|
|
technique_id: UUID
|
|
technique_name: Optional[str] = None
|
|
technique_tid: Optional[str] = None
|
|
risk_level: str
|
|
risk_score: float
|
|
recommendations: List[str]
|
|
priority: int # 1 = highest
|
|
|
|
|
|
class ComputeResult(BaseModel):
|
|
computed: int
|
|
skipped: int
|
|
errors: int
|
|
duration_seconds: float
|