Spaces:
Runtime error
Runtime error
Commit ·
1b9c1ca
1
Parent(s): 22e0141
Added Enterprise RA
Browse files- API_DOCUMENTATION.md +537 -0
- app.py +11 -1
- dashboard_analytics.py +443 -0
- enterprise_ra.py +280 -0
- threat_ra.py +337 -0
API_DOCUMENTATION.md
ADDED
|
@@ -0,0 +1,537 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# EY Catalyst Risk Analysis API Documentation
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
This document describes the AI-powered generation endpoints for the EY Catalyst Risk Analysis platform. These endpoints generate risk-related data using advanced language models and are designed to work independently of database operations.
|
| 5 |
+
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
## Enterprise Risk Assessment (RA) Endpoints
|
| 9 |
+
|
| 10 |
+
### 1. Generate Enterprise Risks
|
| 11 |
+
|
| 12 |
+
**Endpoint:** `POST /api/enterprise-ra/generate-risks`
|
| 13 |
+
|
| 14 |
+
**Purpose:** Generate comprehensive enterprise risks based on category, department, and business context.
|
| 15 |
+
|
| 16 |
+
**Request Body:**
|
| 17 |
+
```json
|
| 18 |
+
{
|
| 19 |
+
"category": "Technology",
|
| 20 |
+
"department": "IT",
|
| 21 |
+
"business_context": "Financial services organization with cloud infrastructure",
|
| 22 |
+
"specific_concerns": "Data security and regulatory compliance",
|
| 23 |
+
"number_of_risks": 5
|
| 24 |
+
}
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
**Response:**
|
| 28 |
+
```json
|
| 29 |
+
{
|
| 30 |
+
"success": true,
|
| 31 |
+
"risks": [
|
| 32 |
+
{
|
| 33 |
+
"id": "r1a2b3c4",
|
| 34 |
+
"category": "Technology",
|
| 35 |
+
"name": "Data Breach",
|
| 36 |
+
"description": "Sensitive customer data could be exposed through inadequate security measures",
|
| 37 |
+
"likelihood": 4,
|
| 38 |
+
"impact": 5,
|
| 39 |
+
"treatment": "Implement multi-factor authentication and encrypt all data at rest",
|
| 40 |
+
"department": "IT",
|
| 41 |
+
"escalated": false,
|
| 42 |
+
"threats": [
|
| 43 |
+
{
|
| 44 |
+
"name": "Phishing Attack",
|
| 45 |
+
"description": "Attackers trick employees into revealing credentials."
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"name": "Malware",
|
| 49 |
+
"description": "Malicious software used to steal or corrupt data."
|
| 50 |
+
}
|
| 51 |
+
]
|
| 52 |
+
}
|
| 53 |
+
],
|
| 54 |
+
"message": "Successfully generated 5 enterprise risks"
|
| 55 |
+
}
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
### 2. Generate Threats for Risk
|
| 59 |
+
|
| 60 |
+
**Endpoint:** `POST /api/enterprise-ra/generate-threats`
|
| 61 |
+
|
| 62 |
+
**Purpose:** Generate specific threats for a given risk scenario.
|
| 63 |
+
|
| 64 |
+
**Request Body:**
|
| 65 |
+
```json
|
| 66 |
+
{
|
| 67 |
+
"risk_name": "Data Breach",
|
| 68 |
+
"category": "Technology",
|
| 69 |
+
"department": "IT",
|
| 70 |
+
"number_of_threats": 3
|
| 71 |
+
}
|
| 72 |
+
```
|
| 73 |
+
|
| 74 |
+
**Response:**
|
| 75 |
+
```json
|
| 76 |
+
{
|
| 77 |
+
"success": true,
|
| 78 |
+
"threats": [
|
| 79 |
+
{
|
| 80 |
+
"name": "Advanced Persistent Threat",
|
| 81 |
+
"description": "Sophisticated, long-term cyber attack targeting sensitive data"
|
| 82 |
+
},
|
| 83 |
+
{
|
| 84 |
+
"name": "Insider Threat",
|
| 85 |
+
"description": "Malicious or negligent actions by employees with system access"
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"name": "Third-Party Breach",
|
| 89 |
+
"description": "Security compromise through vendor or partner systems"
|
| 90 |
+
}
|
| 91 |
+
],
|
| 92 |
+
"message": "Successfully generated 3 threats for risk: Data Breach"
|
| 93 |
+
}
|
| 94 |
+
```
|
| 95 |
+
|
| 96 |
+
---
|
| 97 |
+
|
| 98 |
+
## Threat Risk Assessment Endpoints
|
| 99 |
+
|
| 100 |
+
### 3. Generate Threat Risk Records
|
| 101 |
+
|
| 102 |
+
**Endpoint:** `POST /api/threat-ra/generate-threat-risks`
|
| 103 |
+
|
| 104 |
+
**Purpose:** Generate comprehensive threat risk records for threat risk assessment tables.
|
| 105 |
+
|
| 106 |
+
**Request Body:**
|
| 107 |
+
```json
|
| 108 |
+
{
|
| 109 |
+
"domain": "IT",
|
| 110 |
+
"category": "Technology",
|
| 111 |
+
"business_context": "Cloud-based infrastructure with remote workforce",
|
| 112 |
+
"specific_focus": "Network security and endpoint protection",
|
| 113 |
+
"number_of_records": 10
|
| 114 |
+
}
|
| 115 |
+
```
|
| 116 |
+
|
| 117 |
+
**Response:**
|
| 118 |
+
```json
|
| 119 |
+
{
|
| 120 |
+
"success": true,
|
| 121 |
+
"threatRisks": [
|
| 122 |
+
{
|
| 123 |
+
"id": "tr1a2b3c",
|
| 124 |
+
"domain": "IT",
|
| 125 |
+
"riskName": "Network Intrusion",
|
| 126 |
+
"threat": "External Hacker",
|
| 127 |
+
"vulnerability": "Unpatched Network Equipment",
|
| 128 |
+
"category": "Technology",
|
| 129 |
+
"likelihood": 4,
|
| 130 |
+
"impact": 5,
|
| 131 |
+
"rating": 20
|
| 132 |
+
},
|
| 133 |
+
{
|
| 134 |
+
"id": "tr4d5e6f",
|
| 135 |
+
"domain": "IT",
|
| 136 |
+
"riskName": "Data Exfiltration",
|
| 137 |
+
"threat": "Malicious Insider",
|
| 138 |
+
"vulnerability": "Excessive User Privileges",
|
| 139 |
+
"category": "Technology",
|
| 140 |
+
"likelihood": 3,
|
| 141 |
+
"impact": 4,
|
| 142 |
+
"rating": 12
|
| 143 |
+
}
|
| 144 |
+
],
|
| 145 |
+
"message": "Successfully generated 10 threat risk records"
|
| 146 |
+
}
|
| 147 |
+
```
|
| 148 |
+
|
| 149 |
+
### 4. Analyze Threat Risk Scenario
|
| 150 |
+
|
| 151 |
+
**Endpoint:** `POST /api/threat-ra/analyze-threat-risk`
|
| 152 |
+
|
| 153 |
+
**Purpose:** Provide detailed analysis and recommendations for a specific threat risk scenario.
|
| 154 |
+
|
| 155 |
+
**Request Body:**
|
| 156 |
+
```json
|
| 157 |
+
{
|
| 158 |
+
"domain": "HR",
|
| 159 |
+
"risk_name": "Key Personnel Loss",
|
| 160 |
+
"threat": "Employee Resignation",
|
| 161 |
+
"vulnerability": "No Succession Planning",
|
| 162 |
+
"category": "People"
|
| 163 |
+
}
|
| 164 |
+
```
|
| 165 |
+
|
| 166 |
+
**Response:**
|
| 167 |
+
```json
|
| 168 |
+
{
|
| 169 |
+
"success": true,
|
| 170 |
+
"analysis": {
|
| 171 |
+
"id": "ana1b2c3",
|
| 172 |
+
"domain": "HR",
|
| 173 |
+
"riskName": "Key Personnel Loss",
|
| 174 |
+
"threat": "Employee Resignation",
|
| 175 |
+
"vulnerability": "No Succession Planning",
|
| 176 |
+
"category": "People",
|
| 177 |
+
"likelihood": 3,
|
| 178 |
+
"impact": 4,
|
| 179 |
+
"rating": 12
|
| 180 |
+
},
|
| 181 |
+
"recommendations": [
|
| 182 |
+
"Develop comprehensive succession plans for key roles",
|
| 183 |
+
"Implement knowledge transfer and documentation processes",
|
| 184 |
+
"Create retention strategies for critical personnel",
|
| 185 |
+
"Establish cross-training programs to reduce single points of failure"
|
| 186 |
+
],
|
| 187 |
+
"message": "Successfully analyzed threat risk scenario"
|
| 188 |
+
}
|
| 189 |
+
```
|
| 190 |
+
|
| 191 |
+
### 5. Generate Bulk Threat Analysis
|
| 192 |
+
|
| 193 |
+
**Endpoint:** `POST /api/threat-ra/generate-bulk-analysis`
|
| 194 |
+
|
| 195 |
+
**Purpose:** Generate comprehensive threat risk analysis across multiple domains and categories.
|
| 196 |
+
|
| 197 |
+
**Request Body:**
|
| 198 |
+
```json
|
| 199 |
+
{
|
| 200 |
+
"domains": ["IT", "HR", "Finance", "Operations"],
|
| 201 |
+
"categories": ["Technology", "People", "Process", "External"]
|
| 202 |
+
}
|
| 203 |
+
```
|
| 204 |
+
|
| 205 |
+
**Response:**
|
| 206 |
+
```json
|
| 207 |
+
{
|
| 208 |
+
"success": true,
|
| 209 |
+
"total_records": 80,
|
| 210 |
+
"threat_risks": [
|
| 211 |
+
{
|
| 212 |
+
"id": "bulk1a2b",
|
| 213 |
+
"domain": "IT",
|
| 214 |
+
"riskName": "System Downtime",
|
| 215 |
+
"threat": "Hardware Failure",
|
| 216 |
+
"vulnerability": "Aging Infrastructure",
|
| 217 |
+
"category": "Technology",
|
| 218 |
+
"likelihood": 3,
|
| 219 |
+
"impact": 4,
|
| 220 |
+
"rating": 12
|
| 221 |
+
}
|
| 222 |
+
],
|
| 223 |
+
"message": "Successfully generated 80 threat risk records across 4 domains and 4 categories"
|
| 224 |
+
}
|
| 225 |
+
```
|
| 226 |
+
|
| 227 |
+
---
|
| 228 |
+
|
| 229 |
+
## Dashboard Analytics Endpoints
|
| 230 |
+
|
| 231 |
+
### 6. Generate Dashboard KPIs
|
| 232 |
+
|
| 233 |
+
**Endpoint:** `POST /api/dashboard/generate-kpis`
|
| 234 |
+
|
| 235 |
+
**Purpose:** Generate realistic KPI metrics for the main dashboard based on organization context.
|
| 236 |
+
|
| 237 |
+
**Request Body:**
|
| 238 |
+
```json
|
| 239 |
+
{
|
| 240 |
+
"organization_name": "TechCorp Inc",
|
| 241 |
+
"industry": "Technology",
|
| 242 |
+
"departments": ["IT", "HR", "Finance", "Operations", "Legal", "Marketing"],
|
| 243 |
+
"time_period": "last_30_days"
|
| 244 |
+
}
|
| 245 |
+
```
|
| 246 |
+
|
| 247 |
+
**Response:**
|
| 248 |
+
```json
|
| 249 |
+
{
|
| 250 |
+
"success": true,
|
| 251 |
+
"kpis": {
|
| 252 |
+
"totalRisks": 124,
|
| 253 |
+
"totalThreats": 37,
|
| 254 |
+
"criticalRisks": 8,
|
| 255 |
+
"departments": 6
|
| 256 |
+
},
|
| 257 |
+
"message": "Successfully generated dashboard KPI metrics"
|
| 258 |
+
}
|
| 259 |
+
```
|
| 260 |
+
|
| 261 |
+
### 7. Generate Assessment Summaries
|
| 262 |
+
|
| 263 |
+
**Endpoint:** `POST /api/dashboard/generate-assessment-summaries`
|
| 264 |
+
|
| 265 |
+
**Purpose:** Generate assessment summaries with realistic progress and key findings.
|
| 266 |
+
|
| 267 |
+
**Request Body:**
|
| 268 |
+
```json
|
| 269 |
+
{
|
| 270 |
+
"assessment_types": [
|
| 271 |
+
"Critical Process RA",
|
| 272 |
+
"Threat Risk Assessment",
|
| 273 |
+
"Site Assessment",
|
| 274 |
+
"Vendor Risk Assessment"
|
| 275 |
+
],
|
| 276 |
+
"organization_context": "Mid-size financial services firm with 500+ employees"
|
| 277 |
+
}
|
| 278 |
+
```
|
| 279 |
+
|
| 280 |
+
**Response:**
|
| 281 |
+
```json
|
| 282 |
+
{
|
| 283 |
+
"success": true,
|
| 284 |
+
"summaries": [
|
| 285 |
+
{
|
| 286 |
+
"assessmentType": "Critical Process RA",
|
| 287 |
+
"completed": 12,
|
| 288 |
+
"inProgress": 3,
|
| 289 |
+
"pending": 2,
|
| 290 |
+
"keyFindings": [
|
| 291 |
+
"Most processes are up to date.",
|
| 292 |
+
"2 processes need urgent review."
|
| 293 |
+
]
|
| 294 |
+
},
|
| 295 |
+
{
|
| 296 |
+
"assessmentType": "Threat Risk Assessment",
|
| 297 |
+
"completed": 8,
|
| 298 |
+
"inProgress": 4,
|
| 299 |
+
"pending": 1,
|
| 300 |
+
"keyFindings": [
|
| 301 |
+
"Phishing is the top threat.",
|
| 302 |
+
"Training is needed for IT staff."
|
| 303 |
+
]
|
| 304 |
+
}
|
| 305 |
+
],
|
| 306 |
+
"message": "Successfully generated assessment summaries"
|
| 307 |
+
}
|
| 308 |
+
```
|
| 309 |
+
|
| 310 |
+
### 8. Generate Recent Activities
|
| 311 |
+
|
| 312 |
+
**Endpoint:** `GET /api/dashboard/generate-recent-activities?days=7&limit=10`
|
| 313 |
+
|
| 314 |
+
**Purpose:** Generate realistic recent activities for the dashboard activity feed.
|
| 315 |
+
|
| 316 |
+
**Query Parameters:**
|
| 317 |
+
- `days` (optional): Number of days to look back (default: 7)
|
| 318 |
+
- `limit` (optional): Maximum number of activities to return (default: 10)
|
| 319 |
+
|
| 320 |
+
**Response:**
|
| 321 |
+
```json
|
| 322 |
+
{
|
| 323 |
+
"success": true,
|
| 324 |
+
"activities": [
|
| 325 |
+
{
|
| 326 |
+
"action": "Risk escalated",
|
| 327 |
+
"user": "Jane Doe",
|
| 328 |
+
"timestamp": "2024-06-01T10:15:00Z",
|
| 329 |
+
"meta": "Risk: Data Breach"
|
| 330 |
+
},
|
| 331 |
+
{
|
| 332 |
+
"action": "Threat added",
|
| 333 |
+
"user": "John Smith",
|
| 334 |
+
"timestamp": "2024-05-31T16:42:00Z",
|
| 335 |
+
"meta": "Threat: Ransomware"
|
| 336 |
+
}
|
| 337 |
+
],
|
| 338 |
+
"message": "Successfully generated 10 recent activities"
|
| 339 |
+
}
|
| 340 |
+
```
|
| 341 |
+
|
| 342 |
+
### 9. Generate Risk Insights
|
| 343 |
+
|
| 344 |
+
**Endpoint:** `POST /api/dashboard/generate-risk-insights`
|
| 345 |
+
|
| 346 |
+
**Purpose:** Generate strategic risk insights and recommendations for executive dashboard.
|
| 347 |
+
|
| 348 |
+
**Request Body:**
|
| 349 |
+
```json
|
| 350 |
+
{
|
| 351 |
+
"organization_context": "Global technology company with remote workforce",
|
| 352 |
+
"focus_areas": ["Cybersecurity", "Supply Chain", "Regulatory Compliance"]
|
| 353 |
+
}
|
| 354 |
+
```
|
| 355 |
+
|
| 356 |
+
**Response:**
|
| 357 |
+
```json
|
| 358 |
+
{
|
| 359 |
+
"success": true,
|
| 360 |
+
"insights": [
|
| 361 |
+
{
|
| 362 |
+
"title": "Cybersecurity Threat Evolution",
|
| 363 |
+
"description": "Increasing sophistication of cyber attacks requires enhanced security measures",
|
| 364 |
+
"priority": "High",
|
| 365 |
+
"recommendation": "Implement zero-trust architecture and advanced threat detection"
|
| 366 |
+
}
|
| 367 |
+
],
|
| 368 |
+
"trends": [
|
| 369 |
+
"Increased remote work security challenges",
|
| 370 |
+
"Regulatory compliance complexity"
|
| 371 |
+
],
|
| 372 |
+
"kpis_to_monitor": [
|
| 373 |
+
"Mean time to detect threats",
|
| 374 |
+
"Risk mitigation completion rate"
|
| 375 |
+
],
|
| 376 |
+
"message": "Successfully generated risk insights"
|
| 377 |
+
}
|
| 378 |
+
```
|
| 379 |
+
|
| 380 |
+
---
|
| 381 |
+
|
| 382 |
+
## Risk Mitigation Endpoint (Updated)
|
| 383 |
+
|
| 384 |
+
### 10. Generate Risk Mitigation Analysis
|
| 385 |
+
|
| 386 |
+
**Endpoint:** `POST /api/risk-mitigation`
|
| 387 |
+
|
| 388 |
+
**Purpose:** Generate comprehensive risk analysis and mitigation plan based on user responses to risk assessment questions.
|
| 389 |
+
|
| 390 |
+
**Request Body:**
|
| 391 |
+
```json
|
| 392 |
+
{
|
| 393 |
+
"responses": [
|
| 394 |
+
{
|
| 395 |
+
"category": "Fire",
|
| 396 |
+
"question": "Is the data centre equipped with an appropriate fire suppression system?",
|
| 397 |
+
"user_answer": "We only have a few handheld fire extinguishers, and there's no automated system."
|
| 398 |
+
}
|
| 399 |
+
]
|
| 400 |
+
}
|
| 401 |
+
```
|
| 402 |
+
|
| 403 |
+
**Response:**
|
| 404 |
+
```json
|
| 405 |
+
{
|
| 406 |
+
"risk_analysis": {
|
| 407 |
+
"risk_id": "RISK-001",
|
| 408 |
+
"category": "Fire",
|
| 409 |
+
"question": "Is the data centre equipped with an appropriate fire suppression system?",
|
| 410 |
+
"user_answer": "We only have a few handheld fire extinguishers, and there's no automated system.",
|
| 411 |
+
"risk_name": "Absence of automated fire suppression system",
|
| 412 |
+
"identified_threat": "Increased risk of fire damage and personnel danger due to lack of automatic suppression systems.",
|
| 413 |
+
"likelihood": "High",
|
| 414 |
+
"impact": "Severe",
|
| 415 |
+
"risk_value": 9,
|
| 416 |
+
"residual_risk": "Critical",
|
| 417 |
+
"current_control_description": "Only basic handheld extinguishers are available; no active fire suppression in place.",
|
| 418 |
+
"current_control_rating": "Poor",
|
| 419 |
+
"business_unit": "Facilities",
|
| 420 |
+
"risk_owner": "Fire Safety Officer",
|
| 421 |
+
"timeline": "Immediate",
|
| 422 |
+
"mitigation_plan": "Install automated suppression systems like FM200 or Inergen and integrate with fire alarms.",
|
| 423 |
+
"summary": {
|
| 424 |
+
"risk_classification_summary": "This is a critical fire safety risk with a high likelihood and severe impact. It requires immediate action.",
|
| 425 |
+
"mitigation_suggestions": [
|
| 426 |
+
"Deploy automated gas-based fire suppression systems.",
|
| 427 |
+
"Conduct fire safety training and drills.",
|
| 428 |
+
"Regularly inspect and maintain suppression systems."
|
| 429 |
+
],
|
| 430 |
+
"risk_trends": {
|
| 431 |
+
"top_category": "Fire",
|
| 432 |
+
"risk_severity": "Critical",
|
| 433 |
+
"observations": [
|
| 434 |
+
"Many facilities lack automated fire suppression.",
|
| 435 |
+
"High fire risks stem from outdated or manual systems.",
|
| 436 |
+
"Immediate remediation is crucial to prevent major incidents."
|
| 437 |
+
]
|
| 438 |
+
}
|
| 439 |
+
}
|
| 440 |
+
}
|
| 441 |
+
}
|
| 442 |
+
```
|
| 443 |
+
|
| 444 |
+
---
|
| 445 |
+
|
| 446 |
+
## Error Handling
|
| 447 |
+
|
| 448 |
+
All endpoints follow consistent error handling patterns:
|
| 449 |
+
|
| 450 |
+
**Success Response Structure:**
|
| 451 |
+
```json
|
| 452 |
+
{
|
| 453 |
+
"success": true,
|
| 454 |
+
"data": { ... },
|
| 455 |
+
"message": "Success message"
|
| 456 |
+
}
|
| 457 |
+
```
|
| 458 |
+
|
| 459 |
+
**Error Response Structure:**
|
| 460 |
+
```json
|
| 461 |
+
{
|
| 462 |
+
"success": false,
|
| 463 |
+
"error": "Error description",
|
| 464 |
+
"status_code": 500,
|
| 465 |
+
"details": "Detailed error information"
|
| 466 |
+
}
|
| 467 |
+
```
|
| 468 |
+
|
| 469 |
+
**Common HTTP Status Codes:**
|
| 470 |
+
- `200`: Success
|
| 471 |
+
- `400`: Bad Request (invalid input)
|
| 472 |
+
- `422`: Validation Error
|
| 473 |
+
- `500`: Internal Server Error
|
| 474 |
+
|
| 475 |
+
---
|
| 476 |
+
|
| 477 |
+
## Usage Notes
|
| 478 |
+
|
| 479 |
+
1. **AI-Generated Content**: All endpoints use advanced language models to generate realistic, contextually appropriate risk data.
|
| 480 |
+
|
| 481 |
+
2. **Fallback Mechanisms**: Each endpoint includes intelligent fallback responses in case of AI processing issues.
|
| 482 |
+
|
| 483 |
+
3. **Unique Identifiers**: Generated records include unique IDs for tracking and reference.
|
| 484 |
+
|
| 485 |
+
4. **Customizable Parameters**: Most endpoints accept optional parameters to customize the generated content.
|
| 486 |
+
|
| 487 |
+
5. **Industry-Specific Logic**: Responses are tailored based on industry, department, and organizational context.
|
| 488 |
+
|
| 489 |
+
6. **Rate Limiting**: Consider implementing rate limiting for production use to manage AI API costs.
|
| 490 |
+
|
| 491 |
+
7. **Validation**: All request models include validation to ensure data quality and consistency.
|
| 492 |
+
|
| 493 |
+
---
|
| 494 |
+
|
| 495 |
+
## Integration Examples
|
| 496 |
+
|
| 497 |
+
### PowerShell Example:
|
| 498 |
+
```powershell
|
| 499 |
+
$body = @{
|
| 500 |
+
category = "Technology"
|
| 501 |
+
department = "IT"
|
| 502 |
+
business_context = "Cloud infrastructure with remote workforce"
|
| 503 |
+
number_of_risks = 5
|
| 504 |
+
} | ConvertTo-Json
|
| 505 |
+
|
| 506 |
+
$response = Invoke-RestMethod -Uri "http://localhost:8000/api/enterprise-ra/generate-risks" -Method Post -Body $body -ContentType "application/json"
|
| 507 |
+
```
|
| 508 |
+
|
| 509 |
+
### Python Example:
|
| 510 |
+
```python
|
| 511 |
+
import requests
|
| 512 |
+
|
| 513 |
+
data = {
|
| 514 |
+
"category": "Technology",
|
| 515 |
+
"department": "IT",
|
| 516 |
+
"business_context": "Cloud infrastructure with remote workforce",
|
| 517 |
+
"number_of_risks": 5
|
| 518 |
+
}
|
| 519 |
+
|
| 520 |
+
response = requests.post(
|
| 521 |
+
"http://localhost:8000/api/enterprise-ra/generate-risks",
|
| 522 |
+
json=data
|
| 523 |
+
)
|
| 524 |
+
result = response.json()
|
| 525 |
+
```
|
| 526 |
+
|
| 527 |
+
### cURL Example:
|
| 528 |
+
```bash
|
| 529 |
+
curl -X POST "http://localhost:8000/api/enterprise-ra/generate-risks" \
|
| 530 |
+
-H "Content-Type: application/json" \
|
| 531 |
+
-d '{
|
| 532 |
+
"category": "Technology",
|
| 533 |
+
"department": "IT",
|
| 534 |
+
"business_context": "Cloud infrastructure with remote workforce",
|
| 535 |
+
"number_of_risks": 5
|
| 536 |
+
}'
|
| 537 |
+
```
|
app.py
CHANGED
|
@@ -6,7 +6,17 @@ import os
|
|
| 6 |
import openai
|
| 7 |
import json
|
| 8 |
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
# Environment Variables
|
| 12 |
GROQ_API_KEY = os.environ.get("GROQ_API_KEY").strip()
|
|
|
|
| 6 |
import openai
|
| 7 |
import json
|
| 8 |
|
| 9 |
+
# Import the new routers
|
| 10 |
+
from enterprise_ra import enterprise_ra_router
|
| 11 |
+
from threat_ra import threat_ra_router
|
| 12 |
+
from dashboard_analytics import dashboard_router
|
| 13 |
+
|
| 14 |
+
app = FastAPI(title="EY Catalyst Risk Analysis API", version="1.0.0")
|
| 15 |
+
|
| 16 |
+
# Include the routers
|
| 17 |
+
app.mount("/enterprise", enterprise_ra_router)
|
| 18 |
+
app.mount("/threat", threat_ra_router)
|
| 19 |
+
app.mount("/dashboard", dashboard_router)
|
| 20 |
|
| 21 |
# Environment Variables
|
| 22 |
GROQ_API_KEY = os.environ.get("GROQ_API_KEY").strip()
|
dashboard_analytics.py
ADDED
|
@@ -0,0 +1,443 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# dashboard_analytics.py
|
| 2 |
+
from fastapi import FastAPI, HTTPException
|
| 3 |
+
from pydantic import BaseModel
|
| 4 |
+
from typing import List, Optional, Dict, Any
|
| 5 |
+
import os
|
| 6 |
+
import openai
|
| 7 |
+
import json
|
| 8 |
+
from datetime import datetime, timedelta
|
| 9 |
+
import random
|
| 10 |
+
|
| 11 |
+
# Environment Variables
|
| 12 |
+
GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
|
| 13 |
+
|
| 14 |
+
# Model Setup
|
| 15 |
+
def generate_response(system_prompt: str, user_message: str):
|
| 16 |
+
client = openai.OpenAI(api_key=GROQ_API_KEY, base_url="https://api.groq.com/openai/v1")
|
| 17 |
+
response = client.chat.completions.create(
|
| 18 |
+
model="llama3-8b-8192",
|
| 19 |
+
messages=[
|
| 20 |
+
{"role": "system", "content": system_prompt},
|
| 21 |
+
{"role": "user", "content": user_message}
|
| 22 |
+
],
|
| 23 |
+
temperature=0.4
|
| 24 |
+
)
|
| 25 |
+
return response.choices[0].message.content
|
| 26 |
+
|
| 27 |
+
# Request Models
|
| 28 |
+
class DashboardAnalyticsRequest(BaseModel):
|
| 29 |
+
organization_name: Optional[str] = "Organization"
|
| 30 |
+
industry: Optional[str] = "Technology"
|
| 31 |
+
departments: Optional[List[str]] = ["IT", "HR", "Finance", "Operations"]
|
| 32 |
+
time_period: Optional[str] = "last_30_days"
|
| 33 |
+
|
| 34 |
+
class AssessmentSummaryRequest(BaseModel):
|
| 35 |
+
assessment_types: List[str]
|
| 36 |
+
organization_context: Optional[str] = ""
|
| 37 |
+
|
| 38 |
+
# Response Models
|
| 39 |
+
class KPIMetrics(BaseModel):
|
| 40 |
+
totalRisks: int
|
| 41 |
+
totalThreats: int
|
| 42 |
+
criticalRisks: int
|
| 43 |
+
departments: int
|
| 44 |
+
|
| 45 |
+
class AssessmentSummary(BaseModel):
|
| 46 |
+
assessmentType: str
|
| 47 |
+
completed: int
|
| 48 |
+
inProgress: int
|
| 49 |
+
pending: int
|
| 50 |
+
keyFindings: List[str]
|
| 51 |
+
|
| 52 |
+
class RecentActivity(BaseModel):
|
| 53 |
+
action: str
|
| 54 |
+
user: str
|
| 55 |
+
timestamp: str
|
| 56 |
+
meta: str
|
| 57 |
+
|
| 58 |
+
class DashboardKPIResponse(BaseModel):
|
| 59 |
+
success: bool
|
| 60 |
+
kpis: KPIMetrics
|
| 61 |
+
message: str
|
| 62 |
+
|
| 63 |
+
class AssessmentSummariesResponse(BaseModel):
|
| 64 |
+
success: bool
|
| 65 |
+
summaries: List[AssessmentSummary]
|
| 66 |
+
message: str
|
| 67 |
+
|
| 68 |
+
class RecentActivitiesResponse(BaseModel):
|
| 69 |
+
success: bool
|
| 70 |
+
activities: List[RecentActivity]
|
| 71 |
+
message: str
|
| 72 |
+
|
| 73 |
+
# Dashboard Analytics Router
|
| 74 |
+
dashboard_router = FastAPI()
|
| 75 |
+
|
| 76 |
+
@dashboard_router.post("/api/dashboard/generate-kpis", response_model=DashboardKPIResponse)
|
| 77 |
+
def generate_dashboard_kpis(request: DashboardAnalyticsRequest):
|
| 78 |
+
"""
|
| 79 |
+
Generate realistic KPI metrics for the main dashboard based on organization context
|
| 80 |
+
"""
|
| 81 |
+
system_prompt = """
|
| 82 |
+
You are an expert risk analytics specialist. Your task is to generate realistic KPI metrics for an organization's risk management dashboard.
|
| 83 |
+
|
| 84 |
+
Based on the organization context, generate appropriate metrics that reflect:
|
| 85 |
+
1. Total number of identified risks
|
| 86 |
+
2. Total number of distinct threats
|
| 87 |
+
3. Number of critical risks (high likelihood and high impact)
|
| 88 |
+
4. Number of departments involved in risk management
|
| 89 |
+
|
| 90 |
+
Consider:
|
| 91 |
+
- Organization size and industry standards
|
| 92 |
+
- Typical risk profiles for different industries
|
| 93 |
+
- Realistic proportions between total risks and critical risks
|
| 94 |
+
- Department involvement based on organization structure
|
| 95 |
+
|
| 96 |
+
Respond strictly in this JSON format:
|
| 97 |
+
{
|
| 98 |
+
"kpis": {
|
| 99 |
+
"totalRisks": 125,
|
| 100 |
+
"totalThreats": 45,
|
| 101 |
+
"criticalRisks": 12,
|
| 102 |
+
"departments": 6
|
| 103 |
+
},
|
| 104 |
+
"rationale": "Brief explanation of the metrics provided"
|
| 105 |
+
}
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
+
user_message = f"""
|
| 109 |
+
Generate KPI metrics for the following organization:
|
| 110 |
+
|
| 111 |
+
Organization: {request.organization_name}
|
| 112 |
+
Industry: {request.industry}
|
| 113 |
+
Departments: {', '.join(request.departments)}
|
| 114 |
+
Time Period: {request.time_period}
|
| 115 |
+
|
| 116 |
+
Please provide realistic metrics that align with this organization's profile and industry standards.
|
| 117 |
+
"""
|
| 118 |
+
|
| 119 |
+
try:
|
| 120 |
+
result = generate_response(system_prompt, user_message)
|
| 121 |
+
|
| 122 |
+
# Extract JSON from the response
|
| 123 |
+
json_start = result.find('{')
|
| 124 |
+
json_end = result.rfind('}') + 1
|
| 125 |
+
|
| 126 |
+
if json_start != -1 and json_end > json_start:
|
| 127 |
+
json_str = result[json_start:json_end]
|
| 128 |
+
kpi_data = json.loads(json_str)
|
| 129 |
+
|
| 130 |
+
kpis = KPIMetrics(**kpi_data.get("kpis", {}))
|
| 131 |
+
|
| 132 |
+
return DashboardKPIResponse(
|
| 133 |
+
success=True,
|
| 134 |
+
kpis=kpis,
|
| 135 |
+
message="Successfully generated dashboard KPI metrics"
|
| 136 |
+
)
|
| 137 |
+
else:
|
| 138 |
+
raise ValueError("No valid JSON found in response")
|
| 139 |
+
|
| 140 |
+
except (json.JSONDecodeError, ValueError) as e:
|
| 141 |
+
# Fallback response with industry-appropriate metrics
|
| 142 |
+
base_multiplier = len(request.departments) * 10
|
| 143 |
+
|
| 144 |
+
if request.industry.lower() in ["technology", "financial services", "healthcare"]:
|
| 145 |
+
risk_multiplier = 1.5
|
| 146 |
+
elif request.industry.lower() in ["manufacturing", "retail"]:
|
| 147 |
+
risk_multiplier = 1.2
|
| 148 |
+
else:
|
| 149 |
+
risk_multiplier = 1.0
|
| 150 |
+
|
| 151 |
+
total_risks = int(base_multiplier * risk_multiplier)
|
| 152 |
+
total_threats = int(total_risks * 0.3)
|
| 153 |
+
critical_risks = int(total_risks * 0.08)
|
| 154 |
+
departments = len(request.departments)
|
| 155 |
+
|
| 156 |
+
fallback_kpis = KPIMetrics(
|
| 157 |
+
totalRisks=total_risks,
|
| 158 |
+
totalThreats=total_threats,
|
| 159 |
+
criticalRisks=critical_risks,
|
| 160 |
+
departments=departments
|
| 161 |
+
)
|
| 162 |
+
|
| 163 |
+
return DashboardKPIResponse(
|
| 164 |
+
success=True,
|
| 165 |
+
kpis=fallback_kpis,
|
| 166 |
+
message="Generated fallback KPI metrics"
|
| 167 |
+
)
|
| 168 |
+
|
| 169 |
+
except Exception as e:
|
| 170 |
+
raise HTTPException(status_code=500, detail=f"Error generating KPIs: {str(e)}")
|
| 171 |
+
|
| 172 |
+
@dashboard_router.post("/api/dashboard/generate-assessment-summaries", response_model=AssessmentSummariesResponse)
|
| 173 |
+
def generate_assessment_summaries(request: AssessmentSummaryRequest):
|
| 174 |
+
"""
|
| 175 |
+
Generate assessment summaries with realistic progress and key findings
|
| 176 |
+
"""
|
| 177 |
+
system_prompt = """
|
| 178 |
+
You are an expert risk assessment analyst. Your task is to generate realistic assessment summaries for different types of risk assessments.
|
| 179 |
+
|
| 180 |
+
For each assessment type, provide:
|
| 181 |
+
1. Number of completed assessments
|
| 182 |
+
2. Number of assessments in progress
|
| 183 |
+
3. Number of pending assessments
|
| 184 |
+
4. Key findings relevant to that assessment type
|
| 185 |
+
|
| 186 |
+
Consider:
|
| 187 |
+
- Realistic distribution of assessment states
|
| 188 |
+
- Assessment-specific findings and insights
|
| 189 |
+
- Current risk landscape and common issues
|
| 190 |
+
- Actionable and meaningful key findings
|
| 191 |
+
|
| 192 |
+
Respond strictly in this JSON format:
|
| 193 |
+
{
|
| 194 |
+
"summaries": [
|
| 195 |
+
{
|
| 196 |
+
"assessmentType": "Assessment Type Name",
|
| 197 |
+
"completed": 12,
|
| 198 |
+
"inProgress": 3,
|
| 199 |
+
"pending": 2,
|
| 200 |
+
"keyFindings": [
|
| 201 |
+
"Finding 1",
|
| 202 |
+
"Finding 2"
|
| 203 |
+
]
|
| 204 |
+
}
|
| 205 |
+
]
|
| 206 |
+
}
|
| 207 |
+
"""
|
| 208 |
+
|
| 209 |
+
user_message = f"""
|
| 210 |
+
Generate assessment summaries for the following assessment types:
|
| 211 |
+
|
| 212 |
+
Assessment Types: {', '.join(request.assessment_types)}
|
| 213 |
+
Organization Context: {request.organization_context}
|
| 214 |
+
|
| 215 |
+
Please provide realistic progress numbers and meaningful key findings for each assessment type.
|
| 216 |
+
"""
|
| 217 |
+
|
| 218 |
+
try:
|
| 219 |
+
result = generate_response(system_prompt, user_message)
|
| 220 |
+
|
| 221 |
+
# Extract JSON from the response
|
| 222 |
+
json_start = result.find('{')
|
| 223 |
+
json_end = result.rfind('}') + 1
|
| 224 |
+
|
| 225 |
+
if json_start != -1 and json_end > json_start:
|
| 226 |
+
json_str = result[json_start:json_end]
|
| 227 |
+
summary_data = json.loads(json_str)
|
| 228 |
+
|
| 229 |
+
summaries = [AssessmentSummary(**summary) for summary in summary_data.get("summaries", [])]
|
| 230 |
+
|
| 231 |
+
return AssessmentSummariesResponse(
|
| 232 |
+
success=True,
|
| 233 |
+
summaries=summaries,
|
| 234 |
+
message="Successfully generated assessment summaries"
|
| 235 |
+
)
|
| 236 |
+
else:
|
| 237 |
+
raise ValueError("No valid JSON found in response")
|
| 238 |
+
|
| 239 |
+
except (json.JSONDecodeError, ValueError) as e:
|
| 240 |
+
# Fallback response with default summaries
|
| 241 |
+
fallback_summaries = []
|
| 242 |
+
|
| 243 |
+
for assessment_type in request.assessment_types:
|
| 244 |
+
# Generate realistic numbers
|
| 245 |
+
total_assessments = random.randint(15, 25)
|
| 246 |
+
completed = random.randint(int(total_assessments * 0.6), int(total_assessments * 0.8))
|
| 247 |
+
in_progress = random.randint(2, 5)
|
| 248 |
+
pending = total_assessments - completed - in_progress
|
| 249 |
+
|
| 250 |
+
# Generate assessment-specific findings
|
| 251 |
+
if "critical process" in assessment_type.lower():
|
| 252 |
+
key_findings = [
|
| 253 |
+
"Most critical processes are properly documented",
|
| 254 |
+
"2-3 processes require immediate review",
|
| 255 |
+
"Backup procedures need enhancement"
|
| 256 |
+
]
|
| 257 |
+
elif "threat" in assessment_type.lower():
|
| 258 |
+
key_findings = [
|
| 259 |
+
"Phishing remains the top threat vector",
|
| 260 |
+
"Insider threat controls need strengthening",
|
| 261 |
+
"Third-party risks require attention"
|
| 262 |
+
]
|
| 263 |
+
elif "site" in assessment_type.lower():
|
| 264 |
+
key_findings = [
|
| 265 |
+
"Physical security controls are adequate",
|
| 266 |
+
"Some locations need access control upgrades",
|
| 267 |
+
"Emergency procedures are well-established"
|
| 268 |
+
]
|
| 269 |
+
else:
|
| 270 |
+
key_findings = [
|
| 271 |
+
f"{assessment_type} controls are generally effective",
|
| 272 |
+
"Some areas need improvement",
|
| 273 |
+
"Regular monitoring is recommended"
|
| 274 |
+
]
|
| 275 |
+
|
| 276 |
+
summary = AssessmentSummary(
|
| 277 |
+
assessmentType=assessment_type,
|
| 278 |
+
completed=completed,
|
| 279 |
+
inProgress=in_progress,
|
| 280 |
+
pending=pending,
|
| 281 |
+
keyFindings=key_findings[:2] # Limit to 2 findings
|
| 282 |
+
)
|
| 283 |
+
fallback_summaries.append(summary)
|
| 284 |
+
|
| 285 |
+
return AssessmentSummariesResponse(
|
| 286 |
+
success=True,
|
| 287 |
+
summaries=fallback_summaries,
|
| 288 |
+
message="Generated fallback assessment summaries"
|
| 289 |
+
)
|
| 290 |
+
|
| 291 |
+
except Exception as e:
|
| 292 |
+
raise HTTPException(status_code=500, detail=f"Error generating assessment summaries: {str(e)}")
|
| 293 |
+
|
| 294 |
+
@dashboard_router.get("/api/dashboard/generate-recent-activities", response_model=RecentActivitiesResponse)
|
| 295 |
+
def generate_recent_activities(days: int = 7, limit: int = 10):
|
| 296 |
+
"""
|
| 297 |
+
Generate realistic recent activities for the dashboard activity feed
|
| 298 |
+
"""
|
| 299 |
+
try:
|
| 300 |
+
# Generate sample activities with realistic timestamps
|
| 301 |
+
activity_types = [
|
| 302 |
+
("Risk escalated", "Risk: Data Breach"),
|
| 303 |
+
("Threat added", "Threat: Ransomware"),
|
| 304 |
+
("Assessment completed", "Critical Process RA"),
|
| 305 |
+
("Risk mitigated", "Risk: System Failure"),
|
| 306 |
+
("Threat updated", "Threat: Phishing Attack"),
|
| 307 |
+
("Assessment started", "Site Assessment"),
|
| 308 |
+
("Risk reviewed", "Risk: Supply Chain"),
|
| 309 |
+
("Control implemented", "Multi-factor Authentication"),
|
| 310 |
+
("Vulnerability identified", "Network Security Gap"),
|
| 311 |
+
("Training completed", "Security Awareness")
|
| 312 |
+
]
|
| 313 |
+
|
| 314 |
+
users = ["Jane Doe", "John Smith", "Alice Johnson", "Bob Wilson", "Carol Brown", "David Lee"]
|
| 315 |
+
|
| 316 |
+
activities = []
|
| 317 |
+
|
| 318 |
+
for i in range(min(limit, len(activity_types))):
|
| 319 |
+
# Generate timestamp within the last 'days' days
|
| 320 |
+
days_ago = random.randint(0, days)
|
| 321 |
+
hours_ago = random.randint(0, 23)
|
| 322 |
+
minutes_ago = random.randint(0, 59)
|
| 323 |
+
|
| 324 |
+
timestamp = datetime.now() - timedelta(days=days_ago, hours=hours_ago, minutes=minutes_ago)
|
| 325 |
+
|
| 326 |
+
action, meta = activity_types[i]
|
| 327 |
+
user = random.choice(users)
|
| 328 |
+
|
| 329 |
+
activity = RecentActivity(
|
| 330 |
+
action=action,
|
| 331 |
+
user=user,
|
| 332 |
+
timestamp=timestamp.isoformat() + "Z",
|
| 333 |
+
meta=meta
|
| 334 |
+
)
|
| 335 |
+
activities.append(activity)
|
| 336 |
+
|
| 337 |
+
# Sort by timestamp (most recent first)
|
| 338 |
+
activities.sort(key=lambda x: x.timestamp, reverse=True)
|
| 339 |
+
|
| 340 |
+
return RecentActivitiesResponse(
|
| 341 |
+
success=True,
|
| 342 |
+
activities=activities,
|
| 343 |
+
message=f"Successfully generated {len(activities)} recent activities"
|
| 344 |
+
)
|
| 345 |
+
|
| 346 |
+
except Exception as e:
|
| 347 |
+
raise HTTPException(status_code=500, detail=f"Error generating recent activities: {str(e)}")
|
| 348 |
+
|
| 349 |
+
@dashboard_router.post("/api/dashboard/generate-risk-insights")
|
| 350 |
+
def generate_risk_insights(organization_context: str = "", focus_areas: List[str] = []):
|
| 351 |
+
"""
|
| 352 |
+
Generate strategic risk insights and recommendations for executive dashboard
|
| 353 |
+
"""
|
| 354 |
+
system_prompt = """
|
| 355 |
+
You are a senior risk management consultant. Your task is to generate strategic risk insights and recommendations for executive leadership.
|
| 356 |
+
|
| 357 |
+
Provide:
|
| 358 |
+
1. Top 3-5 strategic risk insights
|
| 359 |
+
2. Trend analysis and predictions
|
| 360 |
+
3. Actionable recommendations for senior management
|
| 361 |
+
4. Key performance indicators to monitor
|
| 362 |
+
|
| 363 |
+
Consider:
|
| 364 |
+
- Current business environment and market conditions
|
| 365 |
+
- Emerging risks and threat landscapes
|
| 366 |
+
- Regulatory and compliance considerations
|
| 367 |
+
- Business continuity and operational resilience
|
| 368 |
+
|
| 369 |
+
Respond strictly in this JSON format:
|
| 370 |
+
{
|
| 371 |
+
"insights": [
|
| 372 |
+
{
|
| 373 |
+
"title": "Insight Title",
|
| 374 |
+
"description": "Detailed insight description",
|
| 375 |
+
"priority": "High/Medium/Low",
|
| 376 |
+
"recommendation": "Specific recommendation"
|
| 377 |
+
}
|
| 378 |
+
],
|
| 379 |
+
"trends": [
|
| 380 |
+
"Trend observation 1",
|
| 381 |
+
"Trend observation 2"
|
| 382 |
+
],
|
| 383 |
+
"kpis_to_monitor": [
|
| 384 |
+
"KPI 1",
|
| 385 |
+
"KPI 2"
|
| 386 |
+
]
|
| 387 |
+
}
|
| 388 |
+
"""
|
| 389 |
+
|
| 390 |
+
user_message = f"""
|
| 391 |
+
Generate strategic risk insights for the following context:
|
| 392 |
+
|
| 393 |
+
Organization Context: {organization_context}
|
| 394 |
+
Focus Areas: {', '.join(focus_areas) if focus_areas else 'General risk management'}
|
| 395 |
+
|
| 396 |
+
Please provide executive-level insights and recommendations.
|
| 397 |
+
"""
|
| 398 |
+
|
| 399 |
+
try:
|
| 400 |
+
result = generate_response(system_prompt, user_message)
|
| 401 |
+
|
| 402 |
+
# Extract JSON from the response
|
| 403 |
+
json_start = result.find('{')
|
| 404 |
+
json_end = result.rfind('}') + 1
|
| 405 |
+
|
| 406 |
+
if json_start != -1 and json_end > json_start:
|
| 407 |
+
json_str = result[json_start:json_end]
|
| 408 |
+
insights_data = json.loads(json_str)
|
| 409 |
+
|
| 410 |
+
return {
|
| 411 |
+
"success": True,
|
| 412 |
+
"insights": insights_data.get("insights", []),
|
| 413 |
+
"trends": insights_data.get("trends", []),
|
| 414 |
+
"kpis_to_monitor": insights_data.get("kpis_to_monitor", []),
|
| 415 |
+
"message": "Successfully generated risk insights"
|
| 416 |
+
}
|
| 417 |
+
else:
|
| 418 |
+
raise ValueError("No valid JSON found in response")
|
| 419 |
+
|
| 420 |
+
except Exception as e:
|
| 421 |
+
# Fallback response
|
| 422 |
+
fallback_insights = [
|
| 423 |
+
{
|
| 424 |
+
"title": "Cybersecurity Threat Evolution",
|
| 425 |
+
"description": "Increasing sophistication of cyber attacks requires enhanced security measures",
|
| 426 |
+
"priority": "High",
|
| 427 |
+
"recommendation": "Implement zero-trust architecture and advanced threat detection"
|
| 428 |
+
},
|
| 429 |
+
{
|
| 430 |
+
"title": "Supply Chain Resilience",
|
| 431 |
+
"description": "Global supply chain disruptions pose ongoing operational risks",
|
| 432 |
+
"priority": "Medium",
|
| 433 |
+
"recommendation": "Diversify supplier base and establish contingency plans"
|
| 434 |
+
}
|
| 435 |
+
]
|
| 436 |
+
|
| 437 |
+
return {
|
| 438 |
+
"success": True,
|
| 439 |
+
"insights": fallback_insights,
|
| 440 |
+
"trends": ["Increased remote work security challenges", "Regulatory compliance complexity"],
|
| 441 |
+
"kpis_to_monitor": ["Mean time to detect threats", "Risk mitigation completion rate"],
|
| 442 |
+
"message": "Generated fallback risk insights"
|
| 443 |
+
}
|
enterprise_ra.py
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# enterprise_ra.py
|
| 2 |
+
from fastapi import FastAPI, HTTPException
|
| 3 |
+
from pydantic import BaseModel
|
| 4 |
+
from typing import List, Optional
|
| 5 |
+
import os
|
| 6 |
+
import openai
|
| 7 |
+
import json
|
| 8 |
+
import uuid
|
| 9 |
+
|
| 10 |
+
# Environment Variables
|
| 11 |
+
GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
|
| 12 |
+
|
| 13 |
+
# Model Setup
|
| 14 |
+
def generate_response(system_prompt: str, user_message: str):
|
| 15 |
+
client = openai.OpenAI(api_key=GROQ_API_KEY, base_url="https://api.groq.com/openai/v1")
|
| 16 |
+
response = client.chat.completions.create(
|
| 17 |
+
model="llama3-8b-8192",
|
| 18 |
+
messages=[
|
| 19 |
+
{"role": "system", "content": system_prompt},
|
| 20 |
+
{"role": "user", "content": user_message}
|
| 21 |
+
],
|
| 22 |
+
temperature=0.4
|
| 23 |
+
)
|
| 24 |
+
return response.choices[0].message.content
|
| 25 |
+
|
| 26 |
+
# Request Models
|
| 27 |
+
class RiskGenerationRequest(BaseModel):
|
| 28 |
+
category: str
|
| 29 |
+
department: str
|
| 30 |
+
business_context: Optional[str] = ""
|
| 31 |
+
specific_concerns: Optional[str] = ""
|
| 32 |
+
number_of_risks: Optional[int] = 5
|
| 33 |
+
|
| 34 |
+
class ThreatGenerationRequest(BaseModel):
|
| 35 |
+
risk_name: str
|
| 36 |
+
category: str
|
| 37 |
+
department: str
|
| 38 |
+
number_of_threats: Optional[int] = 3
|
| 39 |
+
|
| 40 |
+
# Response Models
|
| 41 |
+
class Threat(BaseModel):
|
| 42 |
+
name: str
|
| 43 |
+
description: str
|
| 44 |
+
|
| 45 |
+
class Risk(BaseModel):
|
| 46 |
+
id: str
|
| 47 |
+
category: str
|
| 48 |
+
name: str
|
| 49 |
+
description: str
|
| 50 |
+
likelihood: int
|
| 51 |
+
impact: int
|
| 52 |
+
treatment: str
|
| 53 |
+
department: str
|
| 54 |
+
escalated: bool
|
| 55 |
+
threats: List[Threat]
|
| 56 |
+
|
| 57 |
+
class RiskGenerationResponse(BaseModel):
|
| 58 |
+
success: bool
|
| 59 |
+
risks: List[Risk]
|
| 60 |
+
message: str
|
| 61 |
+
|
| 62 |
+
class ThreatGenerationResponse(BaseModel):
|
| 63 |
+
success: bool
|
| 64 |
+
threats: List[Threat]
|
| 65 |
+
message: str
|
| 66 |
+
|
| 67 |
+
# Enterprise RA Router
|
| 68 |
+
enterprise_ra_router = FastAPI()
|
| 69 |
+
|
| 70 |
+
@enterprise_ra_router.post("/api/enterprise-ra/generate-risks", response_model=RiskGenerationResponse)
|
| 71 |
+
def generate_enterprise_risks(request: RiskGenerationRequest):
|
| 72 |
+
"""
|
| 73 |
+
Generate comprehensive enterprise risks based on category and department
|
| 74 |
+
"""
|
| 75 |
+
system_prompt = """
|
| 76 |
+
You are an expert enterprise risk analyst. Your task is to generate comprehensive risks for organizations based on the provided category, department, and business context.
|
| 77 |
+
|
| 78 |
+
For each risk, you need to:
|
| 79 |
+
1. Create a clear, specific risk name
|
| 80 |
+
2. Provide a detailed description of the risk
|
| 81 |
+
3. Assess likelihood (1-5 scale, where 1=very unlikely, 5=very likely)
|
| 82 |
+
4. Assess impact (1-5 scale, where 1=minimal impact, 5=catastrophic impact)
|
| 83 |
+
5. Provide appropriate treatment strategies
|
| 84 |
+
6. Generate relevant threats associated with each risk
|
| 85 |
+
|
| 86 |
+
Consider:
|
| 87 |
+
- Industry best practices for risk identification
|
| 88 |
+
- Department-specific risks and challenges
|
| 89 |
+
- Current business environment factors
|
| 90 |
+
- Regulatory and compliance considerations
|
| 91 |
+
- Technological and operational dependencies
|
| 92 |
+
|
| 93 |
+
Respond strictly in this JSON format:
|
| 94 |
+
{
|
| 95 |
+
"risks": [
|
| 96 |
+
{
|
| 97 |
+
"name": "Clear, specific risk name",
|
| 98 |
+
"description": "Detailed description of the risk and its potential impact on the organization",
|
| 99 |
+
"likelihood": 3,
|
| 100 |
+
"impact": 4,
|
| 101 |
+
"treatment": "Specific treatment strategies to mitigate the risk",
|
| 102 |
+
"threats": [
|
| 103 |
+
{
|
| 104 |
+
"name": "Threat name",
|
| 105 |
+
"description": "Detailed description of the threat"
|
| 106 |
+
}
|
| 107 |
+
]
|
| 108 |
+
}
|
| 109 |
+
]
|
| 110 |
+
}
|
| 111 |
+
"""
|
| 112 |
+
|
| 113 |
+
user_message = f"""
|
| 114 |
+
Generate {request.number_of_risks} enterprise risks for the following context:
|
| 115 |
+
|
| 116 |
+
Category: {request.category}
|
| 117 |
+
Department: {request.department}
|
| 118 |
+
Business Context: {request.business_context}
|
| 119 |
+
Specific Concerns: {request.specific_concerns}
|
| 120 |
+
|
| 121 |
+
Please provide comprehensive risks that are relevant to this department and category, including appropriate likelihood and impact assessments, treatment strategies, and associated threats.
|
| 122 |
+
"""
|
| 123 |
+
|
| 124 |
+
try:
|
| 125 |
+
result = generate_response(system_prompt, user_message)
|
| 126 |
+
|
| 127 |
+
# Extract JSON from the response
|
| 128 |
+
json_start = result.find('{')
|
| 129 |
+
json_end = result.rfind('}') + 1
|
| 130 |
+
|
| 131 |
+
if json_start != -1 and json_end > json_start:
|
| 132 |
+
json_str = result[json_start:json_end]
|
| 133 |
+
risks_data = json.loads(json_str)
|
| 134 |
+
|
| 135 |
+
# Convert to our response format
|
| 136 |
+
risks = []
|
| 137 |
+
for risk_data in risks_data.get("risks", []):
|
| 138 |
+
risk = Risk(
|
| 139 |
+
id=str(uuid.uuid4())[:8], # Generate unique ID
|
| 140 |
+
category=request.category,
|
| 141 |
+
name=risk_data.get("name", ""),
|
| 142 |
+
description=risk_data.get("description", ""),
|
| 143 |
+
likelihood=risk_data.get("likelihood", 3),
|
| 144 |
+
impact=risk_data.get("impact", 3),
|
| 145 |
+
treatment=risk_data.get("treatment", ""),
|
| 146 |
+
department=request.department,
|
| 147 |
+
escalated=False,
|
| 148 |
+
threats=[Threat(**threat) for threat in risk_data.get("threats", [])]
|
| 149 |
+
)
|
| 150 |
+
risks.append(risk)
|
| 151 |
+
|
| 152 |
+
return RiskGenerationResponse(
|
| 153 |
+
success=True,
|
| 154 |
+
risks=risks,
|
| 155 |
+
message=f"Successfully generated {len(risks)} enterprise risks"
|
| 156 |
+
)
|
| 157 |
+
else:
|
| 158 |
+
raise ValueError("No valid JSON found in response")
|
| 159 |
+
|
| 160 |
+
except (json.JSONDecodeError, ValueError) as e:
|
| 161 |
+
# Fallback response with sample risks
|
| 162 |
+
fallback_risks = [
|
| 163 |
+
Risk(
|
| 164 |
+
id=str(uuid.uuid4())[:8],
|
| 165 |
+
category=request.category,
|
| 166 |
+
name=f"{request.category} Risk Assessment",
|
| 167 |
+
description=f"Potential risks related to {request.category} operations in {request.department} department",
|
| 168 |
+
likelihood=3,
|
| 169 |
+
impact=3,
|
| 170 |
+
treatment=f"Implement comprehensive {request.category} risk management framework",
|
| 171 |
+
department=request.department,
|
| 172 |
+
escalated=False,
|
| 173 |
+
threats=[
|
| 174 |
+
Threat(
|
| 175 |
+
name="Operational Disruption",
|
| 176 |
+
description="Potential for operational processes to be disrupted"
|
| 177 |
+
),
|
| 178 |
+
Threat(
|
| 179 |
+
name="Compliance Violation",
|
| 180 |
+
description="Risk of non-compliance with regulatory requirements"
|
| 181 |
+
)
|
| 182 |
+
]
|
| 183 |
+
)
|
| 184 |
+
]
|
| 185 |
+
|
| 186 |
+
return RiskGenerationResponse(
|
| 187 |
+
success=True,
|
| 188 |
+
risks=fallback_risks,
|
| 189 |
+
message="Generated fallback risks due to processing error"
|
| 190 |
+
)
|
| 191 |
+
|
| 192 |
+
except Exception as e:
|
| 193 |
+
raise HTTPException(status_code=500, detail=f"Error generating risks: {str(e)}")
|
| 194 |
+
|
| 195 |
+
@enterprise_ra_router.post("/api/enterprise-ra/generate-threats", response_model=ThreatGenerationResponse)
|
| 196 |
+
def generate_threats_for_risk(request: ThreatGenerationRequest):
|
| 197 |
+
"""
|
| 198 |
+
Generate specific threats for a given risk
|
| 199 |
+
"""
|
| 200 |
+
system_prompt = """
|
| 201 |
+
You are an expert threat analyst. Your task is to generate specific threats that could lead to or contribute to a given risk.
|
| 202 |
+
|
| 203 |
+
For each threat, provide:
|
| 204 |
+
1. A clear, specific threat name
|
| 205 |
+
2. A detailed description of how this threat could manifest and impact the organization
|
| 206 |
+
|
| 207 |
+
Consider:
|
| 208 |
+
- Direct and indirect threat vectors
|
| 209 |
+
- Internal and external threat sources
|
| 210 |
+
- Current threat landscape and emerging risks
|
| 211 |
+
- Department-specific threat considerations
|
| 212 |
+
- Industry-relevant threat patterns
|
| 213 |
+
|
| 214 |
+
Respond strictly in this JSON format:
|
| 215 |
+
{
|
| 216 |
+
"threats": [
|
| 217 |
+
{
|
| 218 |
+
"name": "Specific threat name",
|
| 219 |
+
"description": "Detailed description of the threat and how it could impact the organization"
|
| 220 |
+
}
|
| 221 |
+
]
|
| 222 |
+
}
|
| 223 |
+
"""
|
| 224 |
+
|
| 225 |
+
user_message = f"""
|
| 226 |
+
Generate {request.number_of_threats} specific threats for the following risk:
|
| 227 |
+
|
| 228 |
+
Risk Name: {request.risk_name}
|
| 229 |
+
Category: {request.category}
|
| 230 |
+
Department: {request.department}
|
| 231 |
+
|
| 232 |
+
Please provide threats that are directly relevant to this risk and could realistically occur in this department context.
|
| 233 |
+
"""
|
| 234 |
+
|
| 235 |
+
try:
|
| 236 |
+
result = generate_response(system_prompt, user_message)
|
| 237 |
+
|
| 238 |
+
# Extract JSON from the response
|
| 239 |
+
json_start = result.find('{')
|
| 240 |
+
json_end = result.rfind('}') + 1
|
| 241 |
+
|
| 242 |
+
if json_start != -1 and json_end > json_start:
|
| 243 |
+
json_str = result[json_start:json_end]
|
| 244 |
+
threats_data = json.loads(json_str)
|
| 245 |
+
|
| 246 |
+
threats = [Threat(**threat) for threat in threats_data.get("threats", [])]
|
| 247 |
+
|
| 248 |
+
return ThreatGenerationResponse(
|
| 249 |
+
success=True,
|
| 250 |
+
threats=threats,
|
| 251 |
+
message=f"Successfully generated {len(threats)} threats for risk: {request.risk_name}"
|
| 252 |
+
)
|
| 253 |
+
else:
|
| 254 |
+
raise ValueError("No valid JSON found in response")
|
| 255 |
+
|
| 256 |
+
except (json.JSONDecodeError, ValueError) as e:
|
| 257 |
+
# Fallback response
|
| 258 |
+
fallback_threats = [
|
| 259 |
+
Threat(
|
| 260 |
+
name="System Failure",
|
| 261 |
+
description="Critical system components may fail leading to operational disruption"
|
| 262 |
+
),
|
| 263 |
+
Threat(
|
| 264 |
+
name="Human Error",
|
| 265 |
+
description="Mistakes by personnel could trigger or worsen the risk scenario"
|
| 266 |
+
),
|
| 267 |
+
Threat(
|
| 268 |
+
name="External Dependencies",
|
| 269 |
+
description="Failure of external services or suppliers could contribute to the risk"
|
| 270 |
+
)
|
| 271 |
+
]
|
| 272 |
+
|
| 273 |
+
return ThreatGenerationResponse(
|
| 274 |
+
success=True,
|
| 275 |
+
threats=fallback_threats[:request.number_of_threats],
|
| 276 |
+
message="Generated fallback threats due to processing error"
|
| 277 |
+
)
|
| 278 |
+
|
| 279 |
+
except Exception as e:
|
| 280 |
+
raise HTTPException(status_code=500, detail=f"Error generating threats: {str(e)}")
|
threat_ra.py
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# threat_ra.py
|
| 2 |
+
from fastapi import FastAPI, HTTPException
|
| 3 |
+
from pydantic import BaseModel
|
| 4 |
+
from typing import List, Optional
|
| 5 |
+
import os
|
| 6 |
+
import openai
|
| 7 |
+
import json
|
| 8 |
+
import uuid
|
| 9 |
+
|
| 10 |
+
# Environment Variables
|
| 11 |
+
GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
|
| 12 |
+
|
| 13 |
+
# Model Setup
|
| 14 |
+
def generate_response(system_prompt: str, user_message: str):
|
| 15 |
+
client = openai.OpenAI(api_key=GROQ_API_KEY, base_url="https://api.groq.com/openai/v1")
|
| 16 |
+
response = client.chat.completions.create(
|
| 17 |
+
model="llama3-8b-8192",
|
| 18 |
+
messages=[
|
| 19 |
+
{"role": "system", "content": system_prompt},
|
| 20 |
+
{"role": "user", "content": user_message}
|
| 21 |
+
],
|
| 22 |
+
temperature=0.4
|
| 23 |
+
)
|
| 24 |
+
return response.choices[0].message.content
|
| 25 |
+
|
| 26 |
+
# Request Models
|
| 27 |
+
class ThreatRiskGenerationRequest(BaseModel):
|
| 28 |
+
domain: str
|
| 29 |
+
category: str
|
| 30 |
+
business_context: Optional[str] = ""
|
| 31 |
+
specific_focus: Optional[str] = ""
|
| 32 |
+
number_of_records: Optional[int] = 10
|
| 33 |
+
|
| 34 |
+
class ThreatRiskAnalysisRequest(BaseModel):
|
| 35 |
+
domain: str
|
| 36 |
+
risk_name: str
|
| 37 |
+
threat: str
|
| 38 |
+
vulnerability: str
|
| 39 |
+
category: str
|
| 40 |
+
|
| 41 |
+
# Response Models
|
| 42 |
+
class ThreatRisk(BaseModel):
|
| 43 |
+
id: str
|
| 44 |
+
domain: str
|
| 45 |
+
riskName: str
|
| 46 |
+
threat: str
|
| 47 |
+
vulnerability: str
|
| 48 |
+
category: str
|
| 49 |
+
likelihood: int
|
| 50 |
+
impact: int
|
| 51 |
+
rating: int
|
| 52 |
+
|
| 53 |
+
class ThreatRiskGenerationResponse(BaseModel):
|
| 54 |
+
success: bool
|
| 55 |
+
threatRisks: List[ThreatRisk]
|
| 56 |
+
message: str
|
| 57 |
+
|
| 58 |
+
class ThreatRiskAnalysisResponse(BaseModel):
|
| 59 |
+
success: bool
|
| 60 |
+
analysis: ThreatRisk
|
| 61 |
+
recommendations: List[str]
|
| 62 |
+
message: str
|
| 63 |
+
|
| 64 |
+
# Threat RA Router
|
| 65 |
+
threat_ra_router = FastAPI()
|
| 66 |
+
|
| 67 |
+
@threat_ra_router.post("/api/threat-ra/generate-threat-risks", response_model=ThreatRiskGenerationResponse)
|
| 68 |
+
def generate_threat_risks(request: ThreatRiskGenerationRequest):
|
| 69 |
+
"""
|
| 70 |
+
Generate comprehensive threat risk records for threat risk assessment
|
| 71 |
+
"""
|
| 72 |
+
system_prompt = """
|
| 73 |
+
You are an expert threat risk analyst. Your task is to generate comprehensive threat risk records that include domain-specific risks, threats, vulnerabilities, and their assessments.
|
| 74 |
+
|
| 75 |
+
For each threat risk record, you need to:
|
| 76 |
+
1. Create a specific risk name relevant to the domain
|
| 77 |
+
2. Identify a credible threat that could exploit vulnerabilities
|
| 78 |
+
3. Identify specific vulnerabilities that could be exploited
|
| 79 |
+
4. Assess likelihood (1-5 scale, where 1=very unlikely, 5=very likely)
|
| 80 |
+
5. Assess impact (1-5 scale, where 1=minimal impact, 5=catastrophic impact)
|
| 81 |
+
6. Calculate rating (likelihood × impact)
|
| 82 |
+
|
| 83 |
+
Consider:
|
| 84 |
+
- Domain-specific threats and vulnerabilities
|
| 85 |
+
- Current threat landscape and attack vectors
|
| 86 |
+
- Industry-specific risk factors
|
| 87 |
+
- Realistic likelihood and impact assessments
|
| 88 |
+
- Emerging threats and evolving attack methods
|
| 89 |
+
|
| 90 |
+
Respond strictly in this JSON format:
|
| 91 |
+
{
|
| 92 |
+
"threatRisks": [
|
| 93 |
+
{
|
| 94 |
+
"riskName": "Specific risk name",
|
| 95 |
+
"threat": "Specific threat vector",
|
| 96 |
+
"vulnerability": "Specific vulnerability that could be exploited",
|
| 97 |
+
"likelihood": 3,
|
| 98 |
+
"impact": 4
|
| 99 |
+
}
|
| 100 |
+
]
|
| 101 |
+
}
|
| 102 |
+
"""
|
| 103 |
+
|
| 104 |
+
user_message = f"""
|
| 105 |
+
Generate {request.number_of_records} threat risk records for the following context:
|
| 106 |
+
|
| 107 |
+
Domain: {request.domain}
|
| 108 |
+
Category: {request.category}
|
| 109 |
+
Business Context: {request.business_context}
|
| 110 |
+
Specific Focus: {request.specific_focus}
|
| 111 |
+
|
| 112 |
+
Please provide comprehensive threat risk records that include specific risks, threats, and vulnerabilities relevant to this domain and category.
|
| 113 |
+
"""
|
| 114 |
+
|
| 115 |
+
try:
|
| 116 |
+
result = generate_response(system_prompt, user_message)
|
| 117 |
+
|
| 118 |
+
# Extract JSON from the response
|
| 119 |
+
json_start = result.find('{')
|
| 120 |
+
json_end = result.rfind('}') + 1
|
| 121 |
+
|
| 122 |
+
if json_start != -1 and json_end > json_start:
|
| 123 |
+
json_str = result[json_start:json_end]
|
| 124 |
+
risks_data = json.loads(json_str)
|
| 125 |
+
|
| 126 |
+
# Convert to our response format
|
| 127 |
+
threat_risks = []
|
| 128 |
+
for risk_data in risks_data.get("threatRisks", []):
|
| 129 |
+
likelihood = risk_data.get("likelihood", 3)
|
| 130 |
+
impact = risk_data.get("impact", 3)
|
| 131 |
+
rating = likelihood * impact
|
| 132 |
+
|
| 133 |
+
threat_risk = ThreatRisk(
|
| 134 |
+
id=str(uuid.uuid4())[:8], # Generate unique ID
|
| 135 |
+
domain=request.domain,
|
| 136 |
+
riskName=risk_data.get("riskName", ""),
|
| 137 |
+
threat=risk_data.get("threat", ""),
|
| 138 |
+
vulnerability=risk_data.get("vulnerability", ""),
|
| 139 |
+
category=request.category,
|
| 140 |
+
likelihood=likelihood,
|
| 141 |
+
impact=impact,
|
| 142 |
+
rating=rating
|
| 143 |
+
)
|
| 144 |
+
threat_risks.append(threat_risk)
|
| 145 |
+
|
| 146 |
+
return ThreatRiskGenerationResponse(
|
| 147 |
+
success=True,
|
| 148 |
+
threatRisks=threat_risks,
|
| 149 |
+
message=f"Successfully generated {len(threat_risks)} threat risk records"
|
| 150 |
+
)
|
| 151 |
+
else:
|
| 152 |
+
raise ValueError("No valid JSON found in response")
|
| 153 |
+
|
| 154 |
+
except (json.JSONDecodeError, ValueError) as e:
|
| 155 |
+
# Fallback response with sample threat risks
|
| 156 |
+
fallback_risks = []
|
| 157 |
+
for i in range(min(request.number_of_records, 3)):
|
| 158 |
+
likelihood = 3
|
| 159 |
+
impact = 3
|
| 160 |
+
rating = likelihood * impact
|
| 161 |
+
|
| 162 |
+
fallback_risk = ThreatRisk(
|
| 163 |
+
id=str(uuid.uuid4())[:8],
|
| 164 |
+
domain=request.domain,
|
| 165 |
+
riskName=f"{request.category} Risk {i+1}",
|
| 166 |
+
threat=f"Generic {request.category} Threat",
|
| 167 |
+
vulnerability=f"System vulnerability in {request.domain}",
|
| 168 |
+
category=request.category,
|
| 169 |
+
likelihood=likelihood,
|
| 170 |
+
impact=impact,
|
| 171 |
+
rating=rating
|
| 172 |
+
)
|
| 173 |
+
fallback_risks.append(fallback_risk)
|
| 174 |
+
|
| 175 |
+
return ThreatRiskGenerationResponse(
|
| 176 |
+
success=True,
|
| 177 |
+
threatRisks=fallback_risks,
|
| 178 |
+
message="Generated fallback threat risks due to processing error"
|
| 179 |
+
)
|
| 180 |
+
|
| 181 |
+
except Exception as e:
|
| 182 |
+
raise HTTPException(status_code=500, detail=f"Error generating threat risks: {str(e)}")
|
| 183 |
+
|
| 184 |
+
@threat_ra_router.post("/api/threat-ra/analyze-threat-risk", response_model=ThreatRiskAnalysisResponse)
|
| 185 |
+
def analyze_threat_risk(request: ThreatRiskAnalysisRequest):
|
| 186 |
+
"""
|
| 187 |
+
Provide detailed analysis and recommendations for a specific threat risk scenario
|
| 188 |
+
"""
|
| 189 |
+
system_prompt = """
|
| 190 |
+
You are an expert threat risk analyst. Your task is to provide detailed analysis and recommendations for a specific threat risk scenario.
|
| 191 |
+
|
| 192 |
+
Analyze the provided threat risk scenario and provide:
|
| 193 |
+
1. Likelihood assessment (1-5 scale) with justification
|
| 194 |
+
2. Impact assessment (1-5 scale) with justification
|
| 195 |
+
3. Overall risk rating (likelihood × impact)
|
| 196 |
+
4. Specific recommendations for risk mitigation
|
| 197 |
+
5. Detection and prevention strategies
|
| 198 |
+
|
| 199 |
+
Consider:
|
| 200 |
+
- Current threat landscape and attack trends
|
| 201 |
+
- Domain-specific vulnerabilities and exposures
|
| 202 |
+
- Industry best practices for risk mitigation
|
| 203 |
+
- Cost-effective security controls
|
| 204 |
+
- Realistic implementation timelines
|
| 205 |
+
|
| 206 |
+
Respond strictly in this JSON format:
|
| 207 |
+
{
|
| 208 |
+
"analysis": {
|
| 209 |
+
"likelihood": 3,
|
| 210 |
+
"impact": 4,
|
| 211 |
+
"justification": "Detailed justification for the likelihood and impact assessments"
|
| 212 |
+
},
|
| 213 |
+
"recommendations": [
|
| 214 |
+
"Specific recommendation 1",
|
| 215 |
+
"Specific recommendation 2",
|
| 216 |
+
"Specific recommendation 3"
|
| 217 |
+
]
|
| 218 |
+
}
|
| 219 |
+
"""
|
| 220 |
+
|
| 221 |
+
user_message = f"""
|
| 222 |
+
Analyze the following threat risk scenario:
|
| 223 |
+
|
| 224 |
+
Domain: {request.domain}
|
| 225 |
+
Risk Name: {request.risk_name}
|
| 226 |
+
Threat: {request.threat}
|
| 227 |
+
Vulnerability: {request.vulnerability}
|
| 228 |
+
Category: {request.category}
|
| 229 |
+
|
| 230 |
+
Please provide a comprehensive analysis including likelihood and impact assessments, and specific recommendations for mitigating this threat risk.
|
| 231 |
+
"""
|
| 232 |
+
|
| 233 |
+
try:
|
| 234 |
+
result = generate_response(system_prompt, user_message)
|
| 235 |
+
|
| 236 |
+
# Extract JSON from the response
|
| 237 |
+
json_start = result.find('{')
|
| 238 |
+
json_end = result.rfind('}') + 1
|
| 239 |
+
|
| 240 |
+
if json_start != -1 and json_end > json_start:
|
| 241 |
+
json_str = result[json_start:json_end]
|
| 242 |
+
analysis_data = json.loads(json_str)
|
| 243 |
+
|
| 244 |
+
# Extract analysis data
|
| 245 |
+
analysis_info = analysis_data.get("analysis", {})
|
| 246 |
+
likelihood = analysis_info.get("likelihood", 3)
|
| 247 |
+
impact = analysis_info.get("impact", 3)
|
| 248 |
+
rating = likelihood * impact
|
| 249 |
+
|
| 250 |
+
# Create analysis response
|
| 251 |
+
analysis = ThreatRisk(
|
| 252 |
+
id=str(uuid.uuid4())[:8],
|
| 253 |
+
domain=request.domain,
|
| 254 |
+
riskName=request.risk_name,
|
| 255 |
+
threat=request.threat,
|
| 256 |
+
vulnerability=request.vulnerability,
|
| 257 |
+
category=request.category,
|
| 258 |
+
likelihood=likelihood,
|
| 259 |
+
impact=impact,
|
| 260 |
+
rating=rating
|
| 261 |
+
)
|
| 262 |
+
|
| 263 |
+
recommendations = analysis_data.get("recommendations", [])
|
| 264 |
+
|
| 265 |
+
return ThreatRiskAnalysisResponse(
|
| 266 |
+
success=True,
|
| 267 |
+
analysis=analysis,
|
| 268 |
+
recommendations=recommendations,
|
| 269 |
+
message="Successfully analyzed threat risk scenario"
|
| 270 |
+
)
|
| 271 |
+
else:
|
| 272 |
+
raise ValueError("No valid JSON found in response")
|
| 273 |
+
|
| 274 |
+
except (json.JSONDecodeError, ValueError) as e:
|
| 275 |
+
# Fallback response
|
| 276 |
+
likelihood = 3
|
| 277 |
+
impact = 3
|
| 278 |
+
rating = likelihood * impact
|
| 279 |
+
|
| 280 |
+
fallback_analysis = ThreatRisk(
|
| 281 |
+
id=str(uuid.uuid4())[:8],
|
| 282 |
+
domain=request.domain,
|
| 283 |
+
riskName=request.risk_name,
|
| 284 |
+
threat=request.threat,
|
| 285 |
+
vulnerability=request.vulnerability,
|
| 286 |
+
category=request.category,
|
| 287 |
+
likelihood=likelihood,
|
| 288 |
+
impact=impact,
|
| 289 |
+
rating=rating
|
| 290 |
+
)
|
| 291 |
+
|
| 292 |
+
fallback_recommendations = [
|
| 293 |
+
f"Implement security controls specific to {request.category}",
|
| 294 |
+
f"Regular assessment and monitoring of {request.domain} systems",
|
| 295 |
+
f"Employee training on {request.threat} prevention",
|
| 296 |
+
f"Establish incident response procedures for {request.risk_name}"
|
| 297 |
+
]
|
| 298 |
+
|
| 299 |
+
return ThreatRiskAnalysisResponse(
|
| 300 |
+
success=True,
|
| 301 |
+
analysis=fallback_analysis,
|
| 302 |
+
recommendations=fallback_recommendations,
|
| 303 |
+
message="Generated fallback analysis due to processing error"
|
| 304 |
+
)
|
| 305 |
+
|
| 306 |
+
except Exception as e:
|
| 307 |
+
raise HTTPException(status_code=500, detail=f"Error analyzing threat risk: {str(e)}")
|
| 308 |
+
|
| 309 |
+
@threat_ra_router.post("/api/threat-ra/generate-bulk-analysis")
|
| 310 |
+
def generate_bulk_threat_analysis(domains: List[str], categories: List[str]):
|
| 311 |
+
"""
|
| 312 |
+
Generate bulk threat risk analysis for multiple domains and categories
|
| 313 |
+
"""
|
| 314 |
+
try:
|
| 315 |
+
results = []
|
| 316 |
+
|
| 317 |
+
for domain in domains:
|
| 318 |
+
for category in categories:
|
| 319 |
+
request = ThreatRiskGenerationRequest(
|
| 320 |
+
domain=domain,
|
| 321 |
+
category=category,
|
| 322 |
+
number_of_records=5
|
| 323 |
+
)
|
| 324 |
+
|
| 325 |
+
response = generate_threat_risks(request)
|
| 326 |
+
if response.success:
|
| 327 |
+
results.extend(response.threatRisks)
|
| 328 |
+
|
| 329 |
+
return {
|
| 330 |
+
"success": True,
|
| 331 |
+
"total_records": len(results),
|
| 332 |
+
"threat_risks": results,
|
| 333 |
+
"message": f"Successfully generated {len(results)} threat risk records across {len(domains)} domains and {len(categories)} categories"
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
except Exception as e:
|
| 337 |
+
raise HTTPException(status_code=500, detail=f"Error in bulk analysis: {str(e)}")
|