Porta i dati di compliance cybersecurity NIS2 nel contesto del Modello Organizzativo 231. Rischi cyber come presidi 231, incidenti significativi come non conformità.
NIS2 Agile espone un'API REST con API Key e un sistema di webhook outbound. 231 Agile può consumare i dati in due modalità:
231 Agile chiama periodicamente le API NIS2 per aggiornare il cruscotto 231. Indicato per dati storici e report periodici (mensile/trimestrale).
NIS2 Agile notifica 231 Agile in tempo reale su eventi critici. Indicato per incidenti significativi, rischi HIGH/CRITICAL, variazioni compliance.
org_admin in NIS2 Agile.In NIS2 Agile, vai in Settings → tab API Keys → Nuova API Key.
Per 231 Agile ti servono: read:compliance, read:risks, read:incidents. Opzionale: read:policies.
La chiave nis2_xxxxx viene mostrata una sola volta. Copiala in 231 Agile → Integrazioni → NIS2 Agile → API Key.
Aggiungi questo codice nel cron job notturno di 231 Agile per sincronizzare i dati NIS2:
// 231 Agile — CronJob: sync_nis2_compliance.php $apiKey = getenv('NIS2_API_KEY'); // nis2_abc123... $orgId = getenv('NIS2_ORG_ID'); $baseUrl = 'https://nis2.certisource.it/api'; function nis2Get(string $endpoint, array $query = []): array { global $apiKey, $orgId, $baseUrl; $url = $baseUrl . $endpoint; if (!empty($query)) $url .= '?' . http_build_query($query); $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'X-API-Key: ' . $apiKey, 'X-Organization-Id: ' . $orgId, ], ]); return json_decode(curl_exec($ch), true) ?? []; } // 1. Recupera compliance summary $compliance = nis2Get('/services/compliance-summary'); $score = $compliance['data']['overall_score'] ?? 0; // 2. Recupera rischi HIGH/CRITICAL per mappa rischi 231 $risks = nis2Get('/services/risks-feed', ['level' => 'high', 'status' => 'open']); // 3. Recupera incidenti Art.23 aperti $incidents = nis2Get('/services/incidents-feed', [ 'significant_only' => 1, 'status' => 'open' ]); // 4. Salva in DB 231 Agile — tabella nis2_integration // DB231::upsert('nis2_integration', ['org_id'=>$orgId231, 'score'=>$score, ...]);
Configura in NIS2 Agile → Settings → Webhook un endpoint del tuo server 231 Agile per ricevere eventi in tempo reale:
# Endpoint da configurare in NIS2 Agile → Settings → Webhook
URL: https://app-231.certisource.it/webhooks/nis2
Events: incident.significant, incident.deadline_warning, risk.high_created, compliance.score_changed
// 231 Agile — routes/webhook_nis2.php $secret = getenv('NIS2_WEBHOOK_SECRET'); $body = file_get_contents('php://input'); $sig = $_SERVER['HTTP_X_NIS2_SIGNATURE'] ?? ''; if (!hash_equals('sha256=' . hash_hmac('sha256', $body, $secret), $sig)) { http_response_code(401); exit; } $payload = json_decode($body, true); $event = $payload['event']; switch ($event) { case 'incident.significant': // Crea non-conformità in 231 Agile NonConformityService::createFromNis2Incident($payload['data']['incident']); break; case 'risk.high_created': // Aggiorna mappa rischi presidi 231 RiskService::importFromNis2($payload['data']['risk']); break; case 'compliance.score_changed': // Aggiorna dashboard 231 con nuovo score NIS2 DashboardService::updateNis2Score($payload['data']['new_score']); break; } http_response_code(200);
Embed HTML con chiamata API diretta. Copialo nella dashboard di 231 Agile:
<!-- Widget NIS2 per 231 Agile dashboard --> <div id="nis2-widget"></div> <script> (async () => { const r = await fetch('https://nis2.certisource.it/api/services/compliance-summary', { headers: { 'X-API-Key': 'nis2_YOUR_KEY', 'X-Organization-Id': 'YOUR_ORG_ID' } }); const { data } = await r.json(); document.getElementById('nis2-widget').innerHTML = ` <div style="padding:20px; border:1px solid #e2e8f0; border-radius:8px;"> <h4 style="font-size:.875rem; font-weight:700; margin-bottom:12px;"> 🔒 NIS2 Compliance Score </h4> <div style="font-size:2rem; font-weight:800; color:#06b6d4;"> ${data.overall_score}% </div> <div style="font-size:.75rem; color:#64748b;">${data.label}</div> <div style="margin-top:12px; display:grid; grid-template-columns:1fr 1fr 1fr; gap:8px;"> <div><strong>${data.incidents.open}</strong><br><small>Incidenti</small></div> <div><strong>${data.risks.high}</strong><br><small>Rischi HIGH</small></div> <div><strong>${data.policies.approved}</strong><br><small>Policy</small></div> </div> </div>`; })(); </script>