API, webhook e connettori per sistemi GRC di terze parti
NIS2 Agile come Provider di Compliance
NIS2 Agile espone una Services API REST che permette a sistemi esterni di leggere
score di conformità, rischi, incidenti e controlli in tempo reale. Auth via API Key dedicata,
rate limiting 100 req/ora, firma HMAC-SHA256 per webhook outbound.
Provider Disponibili
Disponibile
231 Agile (lg231)
Integrazione compliance D.Lgs. 231/2001 + NIS2. Incidenti cyber → OdV,
rischi IT → registro 231, score NIS2 nel dashboard aziendale.
Sistema Inviti / Licenze B2B: NIS2 Agile genera token di invito che abilitano
il provisioning automatico di organizzazioni e utenti. L'e-commerce o il partner riceve l'invito,
lo consegna al cliente finale (es. lg231), che lo usa per attivarsi automaticamente.
L'accesso si interrompe alla scadenza dell'invito.
Flusso completo
1. GENERAZIONE NIS2 Admin (super_admin)
POST /api/invites → { token: "inv_abc123...", expires_at, plan, max_uses }
Il token è visibile UNA SOLA VOLTA. Solo hash SHA-256 in DB.2. DISTRIBUZIONE NIS2 → E-commerce → lg231
NIS2 Admin passa inv_abc123... all'e-commerce
E-commerce lo consegna al cliente con l'ordine
lg231 lo riceve (es. in metadata ordine)
3. VALIDAZIONE lg231 prima del provisioning
GET /api/invites/validate?token=inv_abc123...
→ { valid: true, plan: "professional", expires_at, remaining_uses, plan_features }
4. PROVISIONING lg231 attiva automaticamente
POST /api/services/provision (body include "invite_token": "inv_abc123...")
→ { org_id, api_key, access_token, license_expires_at, temp_password }
NIS2 marca l'invito come usato (used_count++)
5. SCADENZA Accesso automaticamente revocato
Quando expires_at raggiunto:
- API key rimane ma licenza_expires_at è nel passato
- GET /api/invites/validate → { valid: false, code: "EXPIRED" }
- Rinnovo: nuovo invito dal NIS2 Admin → nuovo provisioning
API Inviti (solo super_admin)
Metodo
Endpoint
Auth
Descrizione
POST
/api/invites/create
JWT super_admin
Genera 1..50 inviti in batch
GET
/api/invites/list
JWT super_admin
Lista con filtri status/channel, auto-scade pending
GET
/api/invites/{id}
JWT super_admin
Dettaglio singolo + org usante
DELETE
/api/invites/{id}
JWT super_admin
Revoca (non cancella — solo status=revoked)
POST
/api/invites/{id}/regenerate
JWT super_admin
Nuovo token, stessa configurazione
GET
/api/invites/validate?token=inv_...
—
Anteprima pubblica: piano, scadenza, usi rimasti
Generare un invito (NIS2 Admin)
POST https://nis2.agile.software/api/invites/create
Authorization: Bearer {jwt_super_admin}
Content-Type: application/json
{
"plan": "professional", // essentials | professional | enterprise"duration_months": 12, // durata licenza dopo attivazione"invite_expires_days": 30, // giorni di validità dell'invito stesso"max_uses": 1, // 1=one-shot, N=batch (es: 10 per reseller)"label": "lg231 Partner Q1 2026",
"channel": "lg231", // lg231 | ecommerce | direct | manual"issued_to": "partner@lg231.it",
"notes": "Ordine OPP-2026-042"
}
// Risposta — token visibile UNA SOLA VOLTA:
{
"invites": [{
"id": 7,
"token": "inv_a1b2c3d4e5f6...", ← SALVARE SUBITO, non recuperabile"plan": "professional",
"expires_at": "2026-04-06 12:00:00",
"invite_url": "https://nis2.agile.software/onboarding.html?invite=inv_..."
}],
"warning": "Salva i token subito — non saranno più visibili in chiaro."
}
Provisioning con invito (lg231 → NIS2)
// lg231 usa l'invite_token ricevuto per attivare automaticamente il cliente:POST https://nis2.agile.software/api/services/provision
Content-Type: application/json
{
"invite_token": "inv_a1b2c3d4...", ← sostituisce X-Provision-Secret"company": {
"ragione_sociale": "Acme S.r.l.",
"partita_iva": "02345678901",
"ateco_code": "62.01.00",
"sector": "ict"
},
"admin": {
"email": "ciso@acme.it",
"first_name": "Marco",
"last_name": "Rossi"
},
"caller": {
"system": "lg231",
"company_id": 142,
"callback_url": "https://lg231.agile.software/api/integrations/nis2-callback"
}
}
// Risposta (il piano e la durata vengono dall'invito, non dal body):
{
"provisioned": true,
"org_id": 8,
"api_key": "nis2_abcdef...", ← salvare in lg231 metadata"access_token": "eyJ...", ← JWT 2h per apertura immediata"temp_password": "NIS2_xxxxxx", ← cambio obbligatorio al primo login"invite_plan": "professional",
"license_expires_at": "2027-03-07 12:00:00",
"dashboard_url": "https://nis2.agile.software/dashboard.html"
}
Validazione preventiva (opzionale)
# lg231 può validare l'invito prima del provisioning:
curl "https://nis2.agile.software/api/invites/validate?token=inv_a1b2c3..."
// Se valido:
{ "valid": true, "plan": "professional", "duration_months": 12,
"expires_at": "2026-04-06T12:00:00", "remaining_uses": 1,
"plan_features": ["Policy Management + AI", "Supply Chain Assessment", ...] }
// Se scaduto:
{ "valid": false, "error": "Invito scaduto il 2026-03-01 00:00:00", "code": "EXPIRED" }
// Se già usato:
{ "valid": false, "error": "Invito già utilizzato", "code": "ALREADY_USED" }
Gestione ciclo di vita
Stato invito
Significato
Azione
pending
Valido, non ancora usato
Usabile per provision
used
Raggiunto max_uses
Provisioning bloccato
expired
expires_at superato
Provisioning bloccato, rinnovare
revoked
Revocato da admin
Provisioning bloccato permanente
Sicurezza token: il token inv_ viene restituito in chiaro UNA SOLA VOLTA
alla creazione. Nel DB è conservato solo il hash SHA-256. Il token_prefix (es: inv_a1b2c3...)
è visibile nell'admin panel per identificazione visiva.
Per l'agente Claude di lg231: questo tab descrive esattamente cosa implementare in lg231 Agile per consumare NIS2 come provider di compliance cybersecurity.
Quando un utente lg231 clicca "Apri NIS2" dal suo dashboard, lg231 chiama
POST /api/services/sso e redirige l'utente su NIS2 già autenticato,
portando con sé ruolo e responsabilità. Ogni accesso SSO è tracciato nell'audit trail.
// In lg231, quando l'utente clicca "Apri NIS2 Agile":
$ssoResp = Nis2Client::post('/sso', $apiKey, [
'user_email' => $currentUser['email'],
'user_name' => $currentUser['first_name'] . ' ' . $currentUser['last_name'],
'user_role' => 'compliance_manager', // mappa da ruolo lg231'caller_system' => 'lg231',
'caller_user_id' => $currentUser['id'],
'responsibilities' => [
['area' => 'MOG 231', 'scope' => 'art.24-bis criminalità informatica'],
['area' => 'OdV', 'scope' => 'monitoraggio cyber risk'],
],
]);
if ($ssoResp['success']) {
$jwt = $ssoResp['data']['data']['token'];
$redirectUrl = $ssoResp['data']['data']['redirect_url'];
// Redirect con token nel fragment (sicuro, non nel server log)
header('Location: ' . $redirectUrl . '#sso_token=' . urlencode($jwt));
}
NIS2 lato frontend: in dashboard.html aggiungere: const ssoToken = location.hash.match(/#sso_token=([^&]+)/)?.[1]; if (ssoToken) { localStorage.setItem('nis2_token', ssoToken); location.hash = ''; }
5. Provisioning automatico dal portale lg231
Quando un cliente lg231 acquista una licenza NIS2 Agile, lg231 riceve un invite_token
dall'e-commerce. Con questo token lg231 chiama POST /api/services/provision passando
i dati aziendali del cliente. NIS2 crea automaticamente org, admin e API key. Il piano e la
durata sono definiti dall'invito (non modificabili dal chiamante).
// Salva in lg231 companies.metadata dopo provisioning:
$meta['nis2_api_key'] = $response['api_key'];
$meta['nis2_org_id'] = $response['org_id'];
$meta['nis2_invite_id'] = $response['invite_id'];
$meta['nis2_license_plan'] = $response['invite_plan'];
$meta['nis2_expires_at'] = $response['license_expires_at'];
$meta['nis2_enabled'] = true;
// Controlla scadenza prima di ogni chiamata:if (strtotime($meta['nis2_expires_at'] ?? '1970-01-01') < time()) {
// licenza scaduta → mostrare banner rinnovo, non chiamare NIS2return ['success' => false, 'reason' => 'license_expired'];
}
Checklist implementazione lg231
company-ms: aggiungere nis2_api_key, nis2_org_id, nis2_enabled, nis2_invite_id, nis2_license_plan, nis2_expires_at a provider-config
shared: creare Nis2Client (curl wrapper leggero) con check scadenza licenza
company-ms: endpoint provisioning — ricevi invite_token, chiama POST /api/services/provision, salva risposta in metadata
UI: widget NIS2 score nella company detail (gauge + badge + rischi high)
risk-ms: import rischi cyber durante assessment (categoria art.24-bis)