NIS2 Agile API
API REST per integrare NIS2 Agile con SIEM, GRC, piattaforme ESG e strumenti di compliance.
Panoramica
NIS2 Agile espone due famiglie di API: Services API per lettura dati di compliance in tempo reale, e Webhook API per notifiche push su eventi NIS2.
{ "success": bool, "data": {}, "message": "..." }
Autenticazione
Le Services API usano API Keys con scope granulari. Le API di gestione (webhook, key management) usano JWT Bearer token della sessione utente.
API Key — 3 modalità
# Header (raccomandato)
X-API-Key: nis2_abc123def456...
# Authorization Bearer
Authorization: Bearer nis2_abc123def456...
# Query string (sconsigliato in prod)
GET /api/services/risks-feed?api_key=nis2_abc123def456...
JWT Bearer — Per gestione API
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Scope disponibili
Header obbligatorio
X-Organization-Id: 42 # ID organizzazione target
Gestione Errori
| HTTP | error_code | Descrizione |
|---|---|---|
| 400 | VALIDATION_ERROR | Parametri obbligatori mancanti o non validi |
| 401 | UNAUTHORIZED | API Key assente, scaduta o non valida |
| 403 | INSUFFICIENT_SCOPE | Scope insufficiente per questa risorsa |
| 404 | NOT_FOUND | Risorsa non trovata |
| 429 | RATE_LIMITED | Limite richieste superato |
| 500 | INTERNAL_ERROR | Errore interno del server |
{ "success": false, "message": "Scope insufficiente: richiesto read:risks", "error_code": "INSUFFICIENT_SCOPE" }
Services API
Endpoint GET per leggere dati di compliance da sistemi esterni. Autenticazione tramite API Key con scope granulari.
Stato della piattaforma, versione API e timestamp. Non richiede autenticazione.
Risposta 200
{ "status": "ok", "version": "1.0.0", "timestamp": 1709900400, "platform": "NIS2 Agile" }
Score di conformità NIS2 aggregato per dominio Art.21, con statistiche rischi, incidenti aperti e policy approvate.
Risposta 200
{ "overall_score": 73, "label": "substantially_compliant", "domain_scores": [ { "category": "governance", "score": 80, "answered": 8, "total": 10 } ], "risks": { "total": 24, "critical": 2, "high": 5 }, "incidents": { "open": 3, "significant": 1 }, "policies": { "approved": 12, "draft": 4 } }
Feed rischi con filtri su livello, area NIS2, stato e data. Include deadline di trattamento.
Query Parameters
| Parametro | Tipo | Descrizione |
|---|---|---|
level | string | Filtro livello: critical, high, medium, low |
area | string | Categoria rischio (es. network_security) |
status | string | Stato: open, in_treatment, closed |
from | datetime | Filtra da data ISO (es. 2026-01-01T00:00:00) |
limit | integer | Max risultati (default 50, max 200) |
Risposta 200
{ "risks": [ { "id": 15, "risk_code": "RSK-2026-015", "title": "Vulnerabilità VPN senza MFA", "category": "network_security", "risk_level": "high", "risk_score": 15, "treatment": "mitigate", "nis2_article": "21.2.i", "created_at": "2026-01-15T10:30:00+01:00" } ], "total": 24, "filters": { "level": "high" } }
Feed incidenti con status Art.23 (deadlines 24h/72h/30d) e flag di scadenza. Utile per integrare in SIEM e SOC dashboard.
Query Parameters
| Parametro | Tipo | Descrizione |
|---|---|---|
status | string | open, investigating, resolved, closed |
severity | string | critical, high, medium, low |
significant_only | boolean | Solo incidenti Art.23 significativi |
from | datetime | Filtra da data ISO |
Risposta 200 — Elemento
{ "id": 7, "incident_code": "INC-2026-007", "title": "Accesso non autorizzato sistema ERP", "severity": "high", "is_significant": true, "art23_status": { "early_warning": { "due": "2026-02-21T14:00:00+01:00", "sent": true, "overdue": false }, "notification": { "due": "2026-02-23T14:00:00+01:00", "sent": false, "overdue": false }, "final_report": { "due": "2026-03-22T14:00:00+01:00", "sent": false, "overdue": false } } }
Stato dei controlli di sicurezza Art.21 raggruppati per categoria (governance, network_security, access_control, ecc.).
Risposta 200 — Elemento categoria
{ "category": "network_security", "total": 8, "implemented": 5, "partial": 2, "not_implemented": 1, "score": 75 }
Inventario asset critici con tipo, livello di criticità e dipendenze. Filtrabili per tipo e livello.
Query Parameters
| Parametro | Tipo | Descrizione |
|---|---|---|
type | string | server, network, software, data, service |
criticality | string | critical, high, medium, low |
Panoramica rischio fornitori con risk_score, data ultima valutazione e flag critici. Include stats aggregate.
Risposta 200 — Stats
{ "suppliers": [...], "stats": { "total": 18, "critical": 2, "high": 4, "avg_risk_score": 42 } }
Policy approvate con categoria, articolo NIS2 di riferimento e versione. Opzionalmente include il testo completo.
Query Parameters
| Parametro | Tipo | Descrizione |
|---|---|---|
category | string | Filtra per categoria (es. incident_response) |
include_content | boolean | Include testo policy (default: false) |
Gestione API Keys
CRUD API Keys. Richiede autenticazione JWT con ruolo org_admin.
Restituisce tutte le API Keys (attive e revocate) dell'organizzazione corrente. Non espone mai il testo completo della chiave.
Body (JSON)
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
name | string | * | Nome descrittivo (es. "SIEM Integration") |
scopes | array | * | Array di scope (es. ["read:risks","read:incidents"]) |
expires_at | datetime | Scadenza opzionale (ISO 8601) |
Risposta 201
{ "id": 5, "name": "SIEM Integration", "key": "nis2_a3f8c2d1e4b7...", "key_prefix": "nis2_a3f8c2", "scopes": ["read:risks", "read:incidents"], "warning": "Salva questa chiave in modo sicuro. Non sara' piu' visibile." }
Revoca una API Key impostando is_active = 0. La chiave non viene eliminata dal DB per mantenere l'audit trail.
Webhook Subscriptions
Gestione sottoscrizioni webhook outbound. NIS2 Agile invierà POST HTTP all'URL configurato al verificarsi degli eventi sottoscritti.
Include statistiche di delivery (total, success, failed) per ogni subscription. Non espone il secret HMAC.
X-NIS2-Signature.Body (JSON)
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
name | string | * | Nome descrittivo |
url | string | * | URL https:// destinazione POST |
events | array | * | Array eventi (o ["*"] per wildcard) |
Risposta 201
{ "id": 3, "secret": "a3f8c2d1e4b7f9a2c8d3e1f4...", "warning": "Salva il secret. Sara' usato per verificare la firma X-NIS2-Signature." }
Aggiornamento parziale (PATCH semantics). Solo i campi inviati vengono aggiornati: name, events, is_active.
Invia un ping di test per verificare che l'endpoint remoto sia raggiungibile e risponda correttamente. Controlla il delivery log per il risultato.
Query Parameters
| Parametro | Tipo | Descrizione |
|---|---|---|
subscription_id | integer | Filtra per subscription specifica |
Catalogo Eventi Webhook
NIS2 Agile emette eventi su tutte le operazioni rilevanti per la compliance. Ogni evento ha un payload tipizzato.
| Evento | Trigger | Payload |
|---|---|---|
incident.created | Nuovo incidente registrato | incidentPayload(incident, 'created') |
incident.updated | Incidente modificato | incidentPayload(incident, 'updated') |
incident.significant | Incidente flaggato Art.23 | incidentPayload con deadlines |
incident.deadline_warning | Scadenza 24h/72h imminente | deadline + ore rimanenti |
risk.high_created | Rischio HIGH o CRITICAL creato | riskPayload(risk, 'created') |
risk.updated | Rischio aggiornato | riskPayload(risk, 'updated') |
compliance.score_changed | Variazione score >5% | previous_score, new_score, delta, label |
policy.approved | Policy approvata | policyPayload(policy) |
policy.created | Nuova policy creata | id, title, category, nis2_article |
supplier.risk_flagged | Fornitore con rischio HIGH/CRITICAL | supplier + risk_level |
assessment.completed | Gap assessment completato | score, gap_count, top_gaps[] |
whistleblowing.received | Nuova segnalazione anonima | id, category, priority (no PII) |
normative.update | Aggiornamento normativo NIS2/ACN | title, source, effective_date |
webhook.test | Ping manuale di test | message, timestamp |
* | Wildcard — tutti gli eventi | — |
Struttura envelope payload
{ "id": "550e8400-e29b-41d4-a716-446655440000", "event": "incident.created", "api_version": "1.0.0", "created": 1709900400, "created_at": "2026-03-07T10:00:00+01:00", "source": "nis2-agile", "org_id": 42, "data": { "action": "created", "incident": { ... } } }
Verifica Firma Webhook
Ogni delivery include l'header X-NIS2-Signature con firma HMAC-SHA256 del body. Verifica sempre la firma prima di processare il payload.
sha256=HMAC_SHA256(body, secret)
Headers inviati
X-NIS2-Signature: sha256=a3f8c2d1e4b7...
X-NIS2-Event: incident.created
X-NIS2-Delivery-Id: 147
X-NIS2-Attempt: 1
Content-Type: application/json
Verifica in PHP
$body = file_get_contents('php://input'); $secret = 'il-tuo-secret'; $signature = $_SERVER['HTTP_X_NIS2_SIGNATURE']; $expected = 'sha256=' . hash_hmac('sha256', $body, $secret); if (!hash_equals($expected, $signature)) { http_response_code(401); exit('Invalid signature'); }
Verifica in Python
import hmac, hashlib
secret = b'il-tuo-secret'
body = request.data # bytes
expected = 'sha256=' + hmac.new(secret, body, hashlib.sha256).hexdigest()
received = request.headers.get('X-NIS2-Signature', '')
if not hmac.compare_digest(expected, received):
abort(401)
Retry Policy
| Tentativo | Ritardo | Note |
|---|---|---|
| 1° | Immediato | Fire-and-forget sincrono |
| 2° | +5 minuti | Processato da cron |
| 3° | +30 minuti | Ultimo tentativo |
Dopo 10 fallimenti consecutivi la subscription viene messa in pausa automatica (failure_count >= 10).