A dockerized framework that dynamically prioritizes vulnerabilities by combining LLM reasoning, asset context, and business impact analysis — moving beyond static CVSS scores to actionable, business-aware risk assessments.
- Docker and Docker Compose (v2+)
- An OpenAI-compatible LLM endpoint (Ollama, vLLM, LiteLLM, OpenAI, or any custom proxy)
- No NVD API key required (public API, rate-limited)
git clone https://github.com/luigiMiranda/PrioritAIze.git && cd PrioritAIzecp .env.example .envEdit .env with your actual values:
LLM_BASE_URL=http://localhost:11434/v1 # your endpoint
LLM_MODEL=llama3.2 # model name
LLM_API_KEY=ollama # your API key
SCORING_FORMULA=phase2 # phase1 or phase2 (with financial impact)
APP_API_KEY= # optional: set for API key authOllama example: Install Ollama, run
ollama pull llama3.2, and useLLM_BASE_URL=http://host.docker.internal:11434/v1(on Windows/macOS) orhttp://172.17.0.1:11434/v1(on Linux).
OpenAI example: Set
LLM_BASE_URL=https://api.openai.com/v1,LLM_MODEL=gpt-4o, and your API key.
docker compose up -d --buildThe app starts at http://localhost:8000.
Standard evaluation (seed assets from data/assets.yaml):
- Open http://localhost:8000/evaluate
- Enter a CVE ID (e.g.,
CVE-2021-44228for Log4Shell) - Select a target asset from the dropdown
- Click Evaluate Risk
Custom evaluation (define your own asset with financial parameters on the fly):
- Open http://localhost:8000/evaluate/custom
- Enter a CVE ID
- Fill in asset metadata: name, type, exposure, criticality, compliance tags
- Enter financial parameters: hourly revenue, annual turnover, customer count, customer lifetime value (CLV)
- Click Evaluate Risk
Penalties, churn percentages, and downtime-hour brackets are always sourced from
data/cost_model.yaml— only business-specific financial figures (revenue, turnover, customers, CLV) are user-configurable.
The system will:
- Fetch the CVE description & CVSS score from the NVD (with exponential backoff retry)
- Send it to your LLM for contextual risk reasoning + remediation recommendation
- Compute business impact (downtime costs, regulatory fines, reputational damage)
- Calculate a dynamic risk score using the enhanced formula
- Persist the result in PostgreSQL
- Show the detailed breakdown with financial analysis and per-value calculation trace
├── app/
│ ├── main.py # FastAPI app factory (v0.2.0 with auth middleware)
│ ├── config.py # Env-based configuration (Phase 2: scoring formula, API key)
│ ├── db.py # PostgreSQL access (psycopg2, raw SQL, aggregation helpers)
│ ├── templating.py # Jinja2Templates singleton
│ ├── middleware.py # API-key / bearer-token auth middleware (Phase 2)
│ ├── routes/
│ │ ├── views.py # Web page routes (dashboard, evaluate, custom, batch, metrics, login)
│ │ └── api.py # JSON API routes (evaluate, batch, stats, delete)
│ ├── services/
│ │ ├── nvd.py # NVD API v2: CVE description + CVSS (with retry + backoff)
│ │ ├── llm.py # OpenAI-compatible LLM risk analysis + structured justification
│ │ ├── scorer.py # Weighted risk score formula (Phase 1 & 2 toggle)
│ │ ├── impact.py # Business Impact Modeler: downtime, fines, reputation (Phase 2)
│ │ ├── pipeline.py # Full evaluation pipeline (standard + custom evaluation)
│ │ ├── batch.py # Batch evaluation with concurrent semaphore + stagger (Phase 2)
│ │ └── assets/
│ │ ├── cmdb.py # Mock CMDB connector (Phase 2)
│ │ └── cloud.py # Mock cloud inventory (Phase 2)
│ ├── templates/ # Jinja2 HTML (Bootstrap 5 + Chart.js + dark mode)
│ │ ├── custom_evaluate.html # Custom evaluation form (user-defined asset + finances)
│ │ └── ...
│ └── static/ # CSS, JS (dashboard.js for Chart.js rendering)
├── data/
│ ├── assets.yaml # 8 seed assets (types, exposures, criticalities, compliance)
│ └── cost_model.yaml # Financial cost parameters per asset type (Phase 2)
├── postgres/
│ └── init.sql # Database schema + Phase 2 financial columns + audit_log
├── docker-compose.yaml # App + PostgreSQL 16
├── Dockerfile # Python 3.12-slim + uv
├── .env.example # Configuration template
├── spiegazione.md # Comprehensive project guide (Italian)
└── docs/
├── phase2-plan.md # Phase 2 implementation plan
└── scoring_formulas.md # Full mathematical derivation of all scores & costs
Score = (LLM Threat Level × 0.5) + (Asset Criticality × 0.3) + (Asset Exposure × 0.2)
Score = (LLM Threat × 0.35) + (Criticality × 0.20) + (Exposure × 0.15) + (Financial Impact × 0.30)
Financial impact is the total estimated cost (downtime + regulatory fines + reputational damage), normalized via log₁₀(total + 1) × 1.5 — logarithmic scaling with no upper cap, so a €100M breach (score ~12.0) is clearly differentiated from a €10M breach (score ~10.5).
Toggle between formulas with SCORING_FORMULA=phase1 or SCORING_FORMULA=phase2 in .env.
See docs/scoring_formulas.md for the complete mathematical derivation of every parameter, including downtime brackets, regulatory penalty regimes per compliance tag, churn-tier thresholds, and worked examples.
| Weight (P2) | Component | Source |
|---|---|---|
| 35% | LLM Threat Level | AI analysis of vulnerability + asset context |
| 20% | Asset Criticality | Seed data: high (10), medium (6), low (3) |
| 15% | Asset Exposure | Seed data: public (10), internal (5), isolated (2) |
| 30% | Financial Impact | Downtime cost + regulatory fines + reputational damage |
The modeler quantifies three cost dimensions:
- Downtime cost =
hourly_revenue × estimated_downtime_hours(downtime hours bracketed by threat level) - Regulatory fines — per-compliance-tag penalties (GDPR:
max(€20M, 4% × turnover); HIPAA, PCI-DSS, SOX, NIS2) - Reputational damage =
customer_churn_pct × customer_count × customer_lifetime_value(churn % tiered by severity)
Parameters are configurable in data/cost_model.yaml. Each evaluation result page shows the full derivation of every monetary value in a collapsible "Per-value calculation details" table.
Every evaluation includes a structured 6-factor justification from the LLM explaining why the threat level was chosen:
- CVE characteristics (attack vector, complexity, privileges, CIA impact)
- Asset type implications
- Exposure impact on attack surface
- Criticality impact on business damage
- Compliance tags with specific regulatory consequences
- Final verdict comparing assigned threat to raw CVSS (raised/lowered rationale)
The justification is displayed prominently on the result page under "Why the LLM chose threat level = N/10".
curl -X POST http://localhost:8000/api/evaluate \
-H "Content-Type: application/json" \
-d '{"cve_id": "CVE-2021-44228", "asset_id": "web-payment-prod"}'curl -X POST http://localhost:8000/api/evaluate/batch \
-H "Content-Type: application/json" \
-d '{"items": [
{"cve_id": "CVE-2021-44228", "asset_id": "web-payment-prod"},
{"cve_id": "CVE-2021-45046", "asset_id": "db-customer-prod"}
]}'curl http://localhost:8000/api/statsResponse:
{
"total_evaluations": 42,
"score_distribution": [
{"range": "0–2", "count": 2},
{"range": "2–4", "count": 5},
{"range": "4–6", "count": 8},
{"range": "6–8", "count": 15},
{"range": "8–10", "count": 12}
],
"by_asset_type": [{"asset_type": "web_server", "count": 20}, ...],
"by_exposure": [{"asset_exposure": "public", "count": 25}, ...]
}| ID | Name | Type | Exposure | Criticality | Compliance |
|---|---|---|---|---|---|
web-payment-prod |
Payment Gateway (Prod) | web_server | public | high | PCI-DSS, GDPR |
db-customer-prod |
Customer Database (Prod) | database | internal | high | GDPR, HIPAA |
web-corp-portal |
Corporate Portal | web_server | public | medium | GDPR |
db-internal-dev |
Dev Database Server | database | internal | low | — |
iot-building-mgmt |
Building Management | iot_device | isolated | medium | — |
ws-finance-prod |
Finance Workstation | workstation | internal | high | SOX |
api-third-party |
Third-Party API | api_endpoint | public | medium | GDPR |
scada-plant-floor |
SCADA Plant Controller | control_system | isolated | high | NIS2 |
Edit data/assets.yaml to customize. Edit data/cost_model.yaml to adjust financial parameters per asset type.
Visit /batch or use the API to evaluate multiple CVEs against a single asset concurrently. Up to 5 CVEs are processed in parallel to respect LLM and NVD rate limits.
- Score distribution histogram (Chart.js bar chart)
- Asset type breakdown (doughnut chart)
- Exposure distribution (pie chart)
- Sortable evaluation table with financial impact column
- Delete records (trash button per row with confirmation)
- CSV export of visible evaluations
- Dark/light theme toggle (persisted across page navigations via localStorage)
- Batch reasoning expand — click 💬 on any batch row to see the full LLM justification, narrative, and remediation
- Per-value financial trace — every evaluation result shows exactly how each monetary figure was computed (downtime formula, regulatory fine breakdown, reputation calculation, total, and log₁₀ normalization)
- Metrics page (
/metrics): aggregate stats, score distribution, average score by exposure - Custom evaluation (
/evaluate/custom): define your own asset with financial parameters on the fly — no YAML editing needed
Set APP_API_KEY in .env to restrict access:
- Web routes require
Authorization: Bearer <key>header orcvrs_authcookie - API routes require
X-API-Keyheader - Leave empty for local development (no auth)
Need to assess a vulnerability against an asset not in the seed data? Use /evaluate/custom to define everything inline:
- Asset metadata: name, type (web_server, database, api_endpoint, iot_device, workstation, control_system), exposure (public/internal/isolated), criticality (high/medium/low), compliance tags (GDPR, HIPAA, PCI-DSS, SOX, NIS2)
- Financial parameters: hourly revenue (€/h), annual turnover (€), customer count, customer lifetime value (€)
Penalties, churn percentages, and downtime-hour brackets always come from data/cost_model.yaml — only your business-specific numbers are exposed. The pipeline reuses the same NVD → LLM → impact → scoring → persistence codepath, so results appear on the dashboard with the same detailed breakdown.
report.typ— final Typst report (8 chapters, compilable withtypst compile report.typ)
| Command | Purpose |
|---|---|
docker compose up -d --build |
Build and start both services |
docker compose down |
Stop and remove containers |
docker compose down -v |
Stop, remove, and delete database volume |
docker compose logs app |
View app logs |
docker compose logs db |
View database logs |
docker compose ps |
Check service status |
- Python 3.12 — application runtime
- FastAPI — web framework with middleware support
- Jinja2 + Bootstrap 5 + Chart.js — server-rendered UI with interactive charts
- PostgreSQL 16 — persistence (raw SQL via psycopg2)
- OpenAI SDK — LLM integration (any compatible endpoint)
- uv — dependency management
- Docker Compose — orchestration