Files
nis2-agile/docs/STARGATEWB_ANONYMITY_PLACEMENT.md
T
DevEnv nis2-agileandClaude Opus 4.8 1fe5b7ae61 [DOCS] StarGateWB/Vocea: direttive anonimato segnalante per embed widget + gap NIS2
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>
2026-06-27 08:22:23 +02:00

40 lines
4.0 KiB
Markdown
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.
# 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`) — vedi `OUTGOING_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)
1. Nuova pagina **pubblica** `public/segnala-anonimo.html` (o simile): no `checkAuth`, no sidebar, no analytics, `<meta name="referrer" content="no-referrer">` + header CSP `frame-src https://app.vocea.cloud`.
2. Iframe `https://app.vocea.cloud/it/segnala/<slug>?embed=1` (slug del canale dell'org) **oppure** widget `wb-link.js`.
3. Embed JS: check `event.origin` + envelope, nessuna persistenza del recovery code.
4. Coordinare la CSP a doppio lato (frame-src ↔ frame-ancestors) con l'origin sopra.
5. 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.origin` verificato; recovery code non salvato/inoltrato
- [ ] `Referrer-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).