Fase 1 - Asset Relevance Scoring NIS2 (GV.OC-04): metodologia 0-100 a 6 criteri, AssetScoringService + endpoint scoringGrid/score/relevantSystems + UI assets.html + registro stampabile. Fase 2 - Tassonomia incidenti Determina ACN 164179/2025: IS-1..4 + regime essenziale/importante (Allegati 3/4). Fase 3 - Post-Incident Review (5-Whys) + metriche TTD/TTC/TTR + timestamp di fase. Fase 4 - Mapping NIST CSF 2.0 (43 controlli) reference-only. Fonti certe: registry config/nis2_sources.php + grounding AI (vieta riferimenti inventati) + citazioni help.js + ingest PDF normativi nella KB RAG (scripts/ingest-nis2-sources.php). Migrazioni 020/021/022 (additive idempotenti). Fix VectorService IP Qdrant (drift .5->.3). Analisi concorrenza Evix (docs/EVIX_ANALISI_CONCORRENZA.html, gap-driven). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
89 lines
6.4 KiB
Markdown
89 lines
6.4 KiB
Markdown
# Integrazione analisi `docs/nis2/` → NIS2 Agile
|
|
|
|
> Data: 2026-05-29 (CEST) · Versione: v1.7.0 · Stato: **✅ DEPLOYATO ED ESEGUITO IN PRODUZIONE (Hetzner)**
|
|
|
|
## ✅ Eseguito in produzione (2026-05-29 ~17:06 CEST)
|
|
- **Codice**: live su `/var/www/nis2-agile` (stesso filesystem del container dev via bind mount → nessuno scp necessario). 5 nuovi endpoint verificati live (HTTP 401 auth, routing OK).
|
|
- **Migrazioni DB 020/021/022**: applicate e verificate (colonne assets/incidents + tabella `incident_pir` create).
|
|
- **Ingest KB**: **287 chunk** normativi indicizzati in Qdrant `nis2_kb` scope SYSTEM (171 NIS2 + 77 CER + 25 Det.333017 + 9 Det.164179 + 5 Ambiti). Retrieval verificato (query "preallarme CSIRT" → Direttiva NIS2; "settori alta criticità" → Ambiti Allegati I/II).
|
|
- **Backup**: `/root/backup_pre_v170_20260529_165447.sql`.
|
|
|
|
### ⚠️ Azione consigliata residua (richiede conferma — recreate container)
|
|
**Qdrant IP drift**: il container `nis2-qdrant` non ha IP statico in `docker-compose.yml` ed è driftato da `172.21.0.5` → `172.21.0.3`. Fallback in `VectorService.php` aggiornato a `.3` (live). Per evitare ricorrenze: in `docker/docker-compose.yml` assegnare `ipv4_address` statico al servizio `qdrant` e allineare `QDRANT_URL`, poi `docker compose up -d --force-recreate qdrant app`. NB: nota anche che `kb_uploaded_documents` non esiste su questo DB (migrazioni KB 012-014 non applicate qui) → il tracking MySQL dei doc KB è saltato (best-effort), ma la ricerca RAG legge da Qdrant e funziona.
|
|
|
|
---
|
|
|
|
Integrazione del materiale di analisi (mockup HTML + testi normativi PDF) nel prodotto NIS2 Agile.
|
|
Tutto il codice è scritto e lint-clean (`php -l` / `node --check`). **Le migrazioni DB e l'ingest KB
|
|
NON sono ancora stati eseguiti** (questo container dev non raggiunge il DB/Qdrant di produzione).
|
|
|
|
---
|
|
|
|
## Cosa è stato implementato
|
|
|
|
### Fase 1 — Asset Relevance Scoring NIS2 (GV.OC-04)
|
|
Metodologia di scoring 0-100 su 6 criteri pesati, soglia rilevanza ≥40, classi critico/alto/medio/basso/trascurabile.
|
|
- `docs/sql/020_asset_relevance.sql` — colonne `relevance_score`, `relevance_criteria` (JSON), `relevance_class`, `is_nis2_relevant`, `relevance_assessed_at/by` + indice
|
|
- `application/services/AssetScoringService.php` — logica pura + griglia ufficiale in costante
|
|
- `application/controllers/AssetController.php` — `GET scoringGrid`, `POST {id}/score`, `GET relevantSystems`, filtro `nis2_relevant`
|
|
- `public/assets.html` — colonna "Rilevanza NIS2" + modale di valutazione a 6 criteri con anteprima punteggio
|
|
- `public/js/api.js` — `getScoringGrid`, `scoreAsset`, `listRelevantSystems`, `deleteAsset`
|
|
- Verifica: esempio ERP del mockup = **91/100 → critico** ✓
|
|
|
|
### Fase 2 — Tassonomia incidenti (Determina ACN 164179/2025)
|
|
- `docs/sql/021_incident_nis2_taxonomy.sql` — colonne `nis2_incident_type` ENUM(IS-1..IS-4), `entity_obligation` ENUM(essential/important)
|
|
- `application/controllers/IncidentController.php` — `create()` deriva il regime (Allegato 3 essenziali / Allegato 4 importanti) e blocca IS-4 per gli importanti
|
|
- `application/services/AIService.php` — `classifyIncident()` cita le fonti e restituisce `nis2_incident_type` + `notification_basis`
|
|
|
|
### Fase 3 — Post-Incident Review + metriche TTD/TTC/TTR
|
|
- `docs/sql/022_incident_metrics_pir.sql` — timestamp di fase (`triaged_at`, `contained_at`, `eradicated_at`, `recovered_at`) + tabella `incident_pir` (5-Whys, metriche, costo, lesson learned)
|
|
- `IncidentController.php` — `GET {id}/metrics`, `GET {id}/pir`, `POST {id}/pir`; `update()` timbra i timestamp di fase al cambio stato
|
|
- `public/js/api.js` — `getIncidentMetrics`, `getIncidentPir`, `saveIncidentPir`, `aiClassifyIncident`
|
|
|
|
### Fase 4 — Layer mapping NIST CSF 2.0 (reference, non invasivo)
|
|
- `application/controllers/AuditController.php` — `GET nistCsfMapping`: 43 controlli NIST CSF 2.0 → NIS2 Art.21/23 → modulo. **Nessuna migrazione**, nessuna modifica all'assessment esistente.
|
|
|
|
### Fonti normative certe (richiesta esplicita: AI + help citano fonti certe)
|
|
- `application/config/nis2_sources.php` — **registry canonico citabile** (Dir. 2022/2555, Dir. 2022/2557, D.Lgs. 138/2024, Determina ACN 164179/2025, Determina ACN 333017/2025, Ambiti NIS2)
|
|
- `application/services/AIService.php` — `authoritativeSourcesBlock()` iniettato nei system prompt (default, RAG, classifyIncident): impone di citare le fonti e vieta riferimenti inventati
|
|
- `public/js/help.js` — riferimenti normativi italiani aggiunti a incidenti e asset
|
|
- `scripts/ingest-nis2-sources.php` — indicizza i 5 PDF normativi nella KB (Qdrant `nis2_kb`, scope SYSTEM) per il grounding RAG
|
|
|
|
### Report
|
|
- `ReportService::generateRelevantSystemsRegister()` + `GET /api/audit/relevantSystemsRegister` — registro formale "Sistemi Rilevanti NIS2" (GV.OC-04) HTML stampabile con citazioni.
|
|
|
|
---
|
|
|
|
## Deploy su Hetzner (da eseguire, in ordine — CHIEDERE CONFERMA UTENTE)
|
|
|
|
```bash
|
|
# 0) Backup pre-migrazione
|
|
ssh -i docs/credentials/hetzner_key root@135.181.149.254
|
|
mysqldump nis2_agile_db assets incidents > /root/backup_pre_v170_$(date +%F).sql
|
|
|
|
# 1) Deploy codice (bind mount: PHP live; verificare path reale di produzione)
|
|
cd /var/www/nis2-agile && git pull origin main # dopo push su Gitea
|
|
|
|
# 2) Migrazioni DB (additive, idempotenti). NB: usare host MySQL, non docker exec nis2-db
|
|
mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/020_asset_relevance.sql"
|
|
mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/021_incident_nis2_taxonomy.sql"
|
|
mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/022_incident_metrics_pir.sql"
|
|
|
|
# 3) Ingest fonti normative nella KB (richiede Qdrant + Voyage attivi)
|
|
docker exec -i nis2-app php /var/www/nis2-agile/scripts/ingest-nis2-sources.php --dry-run # verifica
|
|
docker exec -i nis2-app php /var/www/nis2-agile/scripts/ingest-nis2-sources.php # esegui
|
|
|
|
# 4) Smoke test
|
|
curl -s https://nis2.agile.software/api/assets/scoringGrid -H "Authorization: Bearer <jwt>" | head
|
|
```
|
|
|
|
### Rollback
|
|
Ogni `.sql` contiene la sezione ROLLBACK in coda. Per la KB: cancellare i chunk scope=SYSTEM/source=normativa o ripristinare la collection.
|
|
|
|
---
|
|
|
|
## Note
|
|
- **Phase 4** è volutamente reference-only (nessuna tabella/migrazione) per non toccare l'assessment Art.21 consolidato.
|
|
- I PDF normativi restano in `docs/nis2/*.pdf` come libreria sorgente referenziata da `nis2_sources.php`.
|
|
- I file `*copy.html` e `incidente_r00/` dei mockup non sono stati usati (duplicati/superati).
|