Ricevute da Vocea (27/6) le 6 regole per preservare l'anonimato del segnalante nell'embed del widget. Gap analysis NIS2: la pagina app «Segnalazioni» (whistleblowing.html) è dietro login → NON usabile come canale anonimo; serve una pagina PUBBLICA pre-login. Più: no-log apertura, no id nell'URL iframe, check event.origin, Referrer-Policy no-referrer, CSP frame-src app.vocea.cloud. Origin da dare a Vocea per frame-ancestors: https://nis2.agile.software. Da applicare all'attivazione Vocea (oggi scaffold dormiente). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.0 KiB
4.0 KiB
StarGateWB / Vocea — Anonimato del segnalante nell'embed del Widget (direttive + gap NIS2)
Da: Vocea/StarGateWB · A: NIS2 · Ricevuto: 2026-06-27 · Riferito all'integrazione Vocea (Modalità C). Stato integrazione Vocea: scaffold dormiente (
VoceaService, mig 063,VOCEA_ENABLED=off) — vediOUTGOING_TO_AGILEHUB_2026_06_23_vocea_whistleblowing_integration.md. Queste regole diventano vincolanti quando costruiamo la pagina di embed (all'attivazione).
Responsabilità condivisa
- Vocea garantisce (non ci pensiamo noi): zero-knowledge (mai testo/identità/allegati/chiavi in chiaro); IP del segnalante mai memorizzato; codice di recupero mai fuori dall'iframe.
- NIS2 garantisce: che la superficie d'accesso non sia tracciabile.
Le 6 regole + GAP NIS2 (stato → azione)
| # | Regola Vocea | Stato NIS2 oggi | Azione |
|---|---|---|---|
| 1 | Accesso pubblico, senza login (pagina pre-login "Segnala in anonimato") | ❌ whistleblowing.html è dietro login (checkAuth(), sidebar, app-layout) → tracciabile |
Creare una pagina pubblica NUOVA (pre-login, no sidebar, no checkAuth) che ospita l'iframe Vocea. NON riusare la pagina app «Segnalazioni». |
| 2 | Non registrare il "passaggio" (apertura non in audit/web-log/analytics) | ⚠️ la pagina pubblica non deve loggare; il web-log Apache/nginx logga gli accessi | La pagina pubblica = statica, niente audit applicativo; valutare esclusione dal web-log / niente identificatori. Nessun evento "ha aperto il canale". |
| 3 | Nessun identificativo nell'URL dell'iframe (…/segnala/{slug}?embed=1[&theme=dark]) |
✅ facile (controllato in fase di build) | Iframe src SOLO slug+embed; mai employee_id/email/token. |
| 4 | Verifica origin, non toccare il codice (event.origin==='https://app.vocea.cloud', envelope {source:'vocea'}; non salvare/inoltrare il codice di recupero) |
➖ da implementare nell'embed JS | Listener postMessage con check origin + envelope; mai persistere il recovery code. |
| 5 | Niente fughe via referrer/analytics (Referrer-Policy: no-referrer, no analytics terze) |
⚠️ globale = strict-origin-when-cross-origin (nginx.conf); nessuna analytics terza nota |
Sulla pagina pubblica forzare Referrer-Policy: no-referrer; zero tag analytics/telemetria. |
| 6 | CSP allineata (noi: frame-src https://app.vocea.cloud; loro: il nostro origin in frame-ancestors) |
⚠️ oggi solo X-Frame-Options: SAMEORIGIN, nessuna CSP frame-src |
Aggiungere CSP frame-src https://app.vocea.cloud sulla pagina pubblica; comunicare a Vocea il nostro origin (sotto). |
Origin esatto da autorizzare in frame-ancestors (lato Vocea)
https://nis2.agile.software(produzione, canale pubblico).- Eventuale wrapper demo:
https://dimostrazione.agile.software(se si dimostra il canale in demo — da confermare).
Piano (all'attivazione Vocea, non ora)
- Nuova pagina pubblica
public/segnala-anonimo.html(o simile): nocheckAuth, no sidebar, no analytics,<meta name="referrer" content="no-referrer">+ header CSPframe-src https://app.vocea.cloud. - Iframe
https://app.vocea.cloud/it/segnala/<slug>?embed=1(slug del canale dell'org) oppure widgetwb-link.js. - Embed JS: check
event.origin+ envelope, nessuna persistenza del recovery code. - Coordinare la CSP a doppio lato (frame-src ↔ frame-ancestors) con l'origin sopra.
- La pagina app «Segnalazioni» (post-login) resta per la gestione interna (Art.32 NIS2) o viene dismessa, ma NON è il canale anonimo Vocea.
Checklist go-live (canale reale)
- Superficie pubblica, senza login
- "Passaggio" non in audit/web-log/analytics
- Nessun identificativo nell'URL dell'iframe
event.originverificato; recovery code non salvato/inoltratoReferrer-Policy: no-referrer, niente analytics terze sulla pagina- CSP allineata (
frame-ancestors↔frame-src)
Riferimenti Vocea: app.vocea.cloud/integrazioni.html · app.vocea.cloud/it/canale-dedicato · esempio docs/api/examples/embed-test.html (lato Vocea).