nis2-agile/public/integrations/allrisk.html
DevEnv nis2-agile 07c1a71685 [MIGRATE] Migrazione a nis2.agile.software
- Tutti i riferimenti nis2.certisource.it → nis2.agile.software
- Apache vhost HTTP nis2.agile.software attivo su Hetzner
- Script setup-nis2-agile-software.sh: certbot SSL + redirect da vecchio dominio
- .env server: APP_URL aggiornato a https://nis2.agile.software
- CLAUDE.md, docs commerciali, integrazioni, API docs aggiornati

DNS da aggiungere in Cloudflare: nis2.agile.software A 135.181.149.254 (proxy OFF)
Poi eseguire: bash /opt/devenv/scripts/setup-nis2-agile-software.sh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 14:07:10 +01:00

157 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AllRisk × NIS2 Agile — Integrazione</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--primary: #06b6d4; --amber: #f59e0b;
--gray-200: #e2e8f0; --gray-500: #64748b; --gray-700: #334155; --gray-900: #0f172a;
--radius: 8px; --font: -apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
--mono: 'Cascadia Code','Consolas',monospace;
}
body { background: #f8fafc; font-family: var(--font); color: var(--gray-900); }
.header { background: linear-gradient(135deg, #78350f, #92400e); padding: 40px 48px; color: #fff; }
.header-badges { display: flex; gap: 10px; margin-bottom: 16px; }
.badge { padding: 4px 12px; border-radius: 20px; font-size: 0.75rem; font-weight: 700; }
.badge-nis2 { background: rgba(6,182,212,0.2); color: #67e8f9; border: 1px solid rgba(6,182,212,0.3); }
.badge-ar { background: rgba(245,158,11,0.2); color: #fde68a; border: 1px solid rgba(245,158,11,0.3); }
h1 { font-size: 1.875rem; font-weight: 800; margin-bottom: 8px; }
.header p { color: #fde68a; font-size: 1rem; }
.container { max-width: 960px; margin: 0 auto; padding: 40px 24px; }
h2 { font-size: 1.25rem; font-weight: 700; margin-bottom: 12px; padding-bottom: 10px; border-bottom: 2px solid var(--gray-200); }
.section { margin-bottom: 48px; }
p { color: var(--gray-500); font-size: 0.9rem; line-height: 1.7; margin-bottom: 12px; }
pre { background: #1e293b; color: #e2e8f0; padding: 20px; border-radius: var(--radius); font-family: var(--mono); font-size: 0.8125rem; overflow-x: auto; line-height: 1.7; margin: 12px 0; }
code { background: #f1f5f9; padding: 2px 6px; border-radius: 4px; font-family: var(--mono); font-size: 0.85em; color: var(--gray-700); }
.step { display: flex; gap: 16px; margin-bottom: 20px; padding: 18px; background: #fff; border: 1px solid var(--gray-200); border-radius: var(--radius); }
.step-num { width: 30px; height: 30px; border-radius: 50%; background: var(--amber); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.875rem; flex-shrink: 0; }
.step-content h3 { font-size: 0.9375rem; font-weight: 700; margin-bottom: 6px; }
.info-box { padding: 14px 16px; border-radius: var(--radius); margin: 16px 0; font-size: 0.875rem; }
.info-amber { background: #fffbeb; border-left: 3px solid var(--amber); color: #92400e; }
.field-map { width: 100%; border-collapse: collapse; }
.field-map th { padding: 9px 12px; background: #f1f5f9; font-size: 0.8rem; font-weight: 700; text-align: left; }
.field-map td { padding: 9px 12px; border-bottom: 1px solid var(--gray-200); font-size: 0.8rem; }
</style>
</head>
<body>
<div class="header">
<div class="header-badges">
<span class="badge badge-ar">AllRisk</span>
<span>×</span>
<span class="badge badge-nis2">NIS2 Agile</span>
</div>
<h1>Integrazione AllRisk ← NIS2 Agile</h1>
<p>Esporta il risk register cyber NIS2 verso AllRisk per consolidamento nel registro rischi enterprise. Importazione automatica dei rischi HIGH/CRITICAL tramite API Key.</p>
</div>
<div class="container">
<div class="section">
<h2>Scenario di integrazione</h2>
<p>AllRisk è il registro rischi enterprise centralizzato. NIS2 Agile gestisce i rischi cyber in ottica normativa (ISO 27005 / NIS2). L'integrazione permette di:</p>
<div class="step"><div class="step-num">1</div><div class="step-content"><h3>Consolidamento automatico</h3><p>I rischi HIGH/CRITICAL di NIS2 vengono automaticamente importati in AllRisk come rischi di categoria "Cyber/IT" con score e deadline normalizzati.</p></div></div>
<div class="step"><div class="step-num">2</div><div class="step-content"><h3>Aggiornamento bidirezionale</h3><p>AllRisk notifica NIS2 tramite webhook se un rischio enterprise si trasforma in minaccia cyber (es. incidente supply chain → rischio NIS2).</p></div></div>
<div class="step"><div class="step-num">3</div><div class="step-content"><h3>Reporting unificato</h3><p>Report rischi enterprise unico che include dimensione NIS2 con compliance score per ogni categoria di rischio cyber (Art.21 domains).</p></div></div>
</div>
<div class="section">
<h2>Mappatura campi NIS2 → AllRisk</h2>
<table class="field-map">
<thead><tr><th>Campo NIS2 Agile</th><th>Campo AllRisk</th><th>Trasformazione</th></tr></thead>
<tbody>
<tr><td><code>risk_code</code></td><td><code>external_ref</code></td><td>Prefisso <code>NIS2-</code> + codice</td></tr>
<tr><td><code>title</code></td><td><code>risk_name</code></td><td>Diretta</td></tr>
<tr><td><code>risk_level</code></td><td><code>severity</code></td><td>critical→5, high→4, medium→3, low→2</td></tr>
<tr><td><code>likelihood</code> × <code>impact</code></td><td><code>risk_score</code></td><td>Scala 025 → 0100</td></tr>
<tr><td><code>category</code></td><td><code>risk_category</code></td><td>Mappato su tassonomia AllRisk "Cyber"</td></tr>
<tr><td><code>nis2_article</code></td><td><code>regulatory_ref</code></td><td>Prefisso "NIS2 Art."</td></tr>
<tr><td><code>treatment</code></td><td><code>response_strategy</code></td><td>mitigate→Reduce, accept→Accept, ecc.</td></tr>
<tr><td><code>review_date</code></td><td><code>next_review</code></td><td>Diretta (ISO 8601)</td></tr>
</tbody>
</table>
</div>
<div class="section">
<h2>Import automatico — Script PHP</h2>
<pre><span style="color:#7dd3fc;">// AllRisk — import_nis2_risks.php (cron settimanale)</span>
<span style="color:#f1fa8c;">$apiKey</span> = getenv(<span style="color:#86efac;">'NIS2_API_KEY'</span>);
<span style="color:#f1fa8c;">$orgId</span> = getenv(<span style="color:#86efac;">'NIS2_ORG_ID'</span>);
<span style="color:#f1fa8c;">$baseUrl</span> = <span style="color:#86efac;">'https://nis2.agile.software/api'</span>;
<span style="color:#f1fa8c;">$allriskOrgId</span> = getenv(<span style="color:#86efac;">'ALLRISK_ORG_ID'</span>);
<span style="color:#7dd3fc;">// Fetch rischi HIGH/CRITICAL aperti da NIS2</span>
<span style="color:#f1fa8c;">$response</span> = nis2Get(<span style="color:#f1fa8c;">$baseUrl</span> . <span style="color:#86efac;">'/services/risks-feed'</span>, [
<span style="color:#86efac;">'level'</span> => <span style="color:#86efac;">'high'</span>,
<span style="color:#86efac;">'status'</span> => <span style="color:#86efac;">'open'</span>,
<span style="color:#86efac;">'limit'</span> => 200,
], <span style="color:#f1fa8c;">$apiKey</span>, <span style="color:#f1fa8c;">$orgId</span>);
<span style="color:#f1fa8c;">$risks</span> = <span style="color:#f1fa8c;">$response</span>[<span style="color:#86efac;">'data'</span>][<span style="color:#86efac;">'risks'</span>] ?? [];
<span style="color:#f1fa8c;">$imported</span> = 0;
foreach (<span style="color:#f1fa8c;">$risks</span> as <span style="color:#f1fa8c;">$risk</span>) {
<span style="color:#f1fa8c;">$allriskPayload</span> = [
<span style="color:#86efac;">'external_ref'</span> => <span style="color:#86efac;">'NIS2-'</span> . <span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'risk_code'</span>],
<span style="color:#86efac;">'risk_name'</span> => <span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'title'</span>],
<span style="color:#86efac;">'risk_category'</span> => <span style="color:#86efac;">'Cyber/IT'</span>,
<span style="color:#86efac;">'severity'</span> => mapSeverity(<span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'risk_level'</span>]),
<span style="color:#86efac;">'risk_score'</span> => round(<span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'risk_score'</span>] / 25 * 100),
<span style="color:#86efac;">'regulatory_ref'</span> => <span style="color:#86efac;">'NIS2 '</span> . (<span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'nis2_article'</span>] ?? <span style="color:#86efac;">'Art.21'</span>),
<span style="color:#86efac;">'response_strategy'</span> => mapTreatment(<span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'treatment'</span>]),
<span style="color:#86efac;">'source_system'</span> => <span style="color:#86efac;">'NIS2 Agile'</span>,
<span style="color:#86efac;">'organization_id'</span> => <span style="color:#f1fa8c;">$allriskOrgId</span>,
];
<span style="color:#7dd3fc;">// Upsert: aggiorna se external_ref esiste, crea altrimenti</span>
AllRiskApiClient::upsertRisk(<span style="color:#f1fa8c;">$allriskPayload</span>);
<span style="color:#f1fa8c;">$imported</span>++;
}
error_log("[NIS2→AllRisk] Importati {<span style="color:#f1fa8c;">$imported</span>} rischi");
<span style="color:#f1fa8c;">function</span> mapSeverity(<span style="color:#f1fa8c;">string $level</span>): int {
return match(<span style="color:#f1fa8c;">$level</span>) { <span style="color:#86efac;">'critical'</span> => 5, <span style="color:#86efac;">'high'</span> => 4, <span style="color:#86efac;">'medium'</span> => 3, default => 2 };
}
<span style="color:#f1fa8c;">function</span> mapTreatment(<span style="color:#f1fa8c;">string $t</span>): string {
return match(<span style="color:#f1fa8c;">$t</span>) {
<span style="color:#86efac;">'mitigate'</span> => <span style="color:#86efac;">'Reduce'</span>, <span style="color:#86efac;">'accept'</span> => <span style="color:#86efac;">'Accept'</span>,
<span style="color:#86efac;">'transfer'</span> => <span style="color:#86efac;">'Transfer'</span>, default => <span style="color:#86efac;">'Avoid'</span>
};
}</pre>
</div>
<div class="section">
<h2>Webhook NIS2 → AllRisk (real-time)</h2>
<p>Configura webhook per importazione immediata dei nuovi rischi HIGH/CRITICAL:</p>
<pre><span style="color:#7dd3fc;"># Settings → Webhook in NIS2 Agile</span>
URL: https://allrisk.certisource.it/api/v1/webhooks/nis2
Events: risk.high_created, compliance.score_changed, incident.significant</pre>
<pre><span style="color:#7dd3fc;">// AllRisk — webhook receiver per NIS2</span>
<span style="color:#f1fa8c;">$payload</span> = verifyAndDecode($_SERVER[<span style="color:#86efac;">'HTTP_X_NIS2_SIGNATURE'</span>], file_get_contents(<span style="color:#86efac;">'php://input'</span>));
if (<span style="color:#f1fa8c;">$payload</span>[<span style="color:#86efac;">'event'</span>] === <span style="color:#86efac;">'risk.high_created'</span>) {
<span style="color:#f1fa8c;">$risk</span> = <span style="color:#f1fa8c;">$payload</span>[<span style="color:#86efac;">'data'</span>][<span style="color:#86efac;">'risk'</span>];
AllRiskApiClient::upsertRisk([
<span style="color:#86efac;">'external_ref'</span> => <span style="color:#86efac;">'NIS2-'</span> . <span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'id'</span>],
<span style="color:#86efac;">'risk_name'</span> => <span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'title'</span>],
<span style="color:#86efac;">'severity'</span> => <span style="color:#f1fa8c;">$risk</span>[<span style="color:#86efac;">'risk_level'</span>] === <span style="color:#86efac;">'critical'</span> ? 5 : 4,
<span style="color:#86efac;">'source_system'</span>=> <span style="color:#86efac;">'NIS2 Agile'</span>,
<span style="color:#86efac;">'alert'</span> => true, <span style="color:#7dd3fc;">// Notifica CRO AllRisk</span>
]);
}
http_response_code(200);</pre>
</div>
<div class="info-box info-amber">
<strong>Nota architetturale:</strong> Il flusso è unidirezionale NIS2 → AllRisk. Per il flusso inverso (AllRisk → NIS2), AllRisk chiama l'API NIS2 per creare rischi cyber direttamente tramite le API JWT (POST /api/risks/create) usando le credenziali dell'utente integration.
</div>
</div>
</body>
</html>