Documento 5 di 13
Sicurezza e privacy
Misure tecniche, backup, dati trattati, ruoli GDPR, sub-responsabili.
Per chi: Privacy, DPO, IT
Questo documento descrive le misure di sicurezza di Orafila e come si inserisce negli obblighi del GDPR. Può essere usato come base per l'allegato sulle misure tecniche e organizzative (art. 32 GDPR) dell'accordo sul trattamento dei dati.
Le indicazioni sul GDPR sono pratiche e non sono consulenza legale: i contratti vanno verificati con un consulente privacy o con il DPO.
In sintesi
| Area | Misura |
|---|---|
| Separazione tra aziende | Row-Level Security di PostgreSQL forzata su ogni tabella, chiavi esterne che includono l'azienda, ruolo del database senza privilegi; l'app si ferma all'avvio se il ruolo può aggirare l'isolamento |
| Accesso | Password di almeno 12 caratteri (hash scrypt), verifica in due passaggi obbligatoria per tutti, blocco dopo 5 tentativi per 15 minuti, sessioni lato server di 12 ore |
| Autorizzazioni | Ruoli e 23 permessi; ogni pagina e ogni azione ricontrollano il permesso sul server |
| Cifratura in transito | HTTPS con certificati Let's Encrypt rinnovati in automatico, HSTS; con un database esterno, TLS con verifica del certificato obbligatoria |
| Cifratura dei segreti | Segreti della verifica in due passaggi, password delle caselle di posta e token di Fatture in Cloud cifrati con AES-256-GCM; dei token di sessione e di invito si conserva solo l'impronta (hash) |
| Tracciabilità | Registro attività non modificabile né cancellabile dall'applicazione, senza segreti |
| Backup | Ogni notte, cifrati, verificati e copiati su un archivio separato; la chiave privata va custodita anche fuori dal server |
| Infrastruttura | Database non raggiungibile da internet, contenitori dell'applicazione con file system in sola lettura e senza privilegi, aggiornamenti di sicurezza del sistema operativo automatici |
| AI | Facoltativa, disattivabile per azienda, sola lettura, dati limitati a quelli necessari, mai segreti |
1. Separazione dei dati tra aziende
Orafila è multi-azienda: più aziende possono usare la stessa installazione, ognuna con il proprio codice azienda.
- Ogni tabella con dati di un'azienda ha la colonna dell'azienda e una regola di Row-Level Security di PostgreSQL forzata (vale anche per il proprietario delle tabelle). Ogni operazione dell'applicazione imposta l'azienda della persona collegata; senza azienda impostata il database restituisce zero righe: in caso di errore il sistema resta chiuso.
- Le chiavi esterne includono l'azienda: un record non può puntare a un record di un'altra azienda nemmeno se il codice sbagliasse.
- L'applicazione si collega con un ruolo senza privilegi (non superuser, senza
BYPASSRLS, non proprietario delle tabelle). All'avvio l'app e il processo della posta controllano il proprio ruolo e si fermano se potrebbe aggirare l'isolamento. - L'isolamento è verificato da test automatici che falliscono se una tabella resta scoperta o se un'azienda riesce a vedere i dati di un'altra.
- Le query usano sempre valori come parametri: l'SQL injection è esclusa per costruzione.
2. Accesso e sessioni
- Password: almeno 12 caratteri; conservate solo come hash scrypt con sale; mai scritte nei log o nel registro attività.
- Verifica in due passaggi (TOTP) obbligatoria per tutti, attivata al primo accesso; codice QR generato dall'applicazione, senza servizi esterni; segreto cifrato; ogni codice vale una sola volta. L'indirizzo IP non decide mai l'autenticazione.
- Blocco dopo 5 tentativi sbagliati (password o codice) per 15 minuti, anche nel cambio password; il messaggio di errore non dice quale tra codice azienda, email e password è sbagliato, e la verifica della password richiede lo stesso tempo anche per un utente inesistente.
- Sessioni lato server di 12 ore, in cookie
HttpOnly,Secure,SameSite=Lax; del token si conserva solo l'impronta. Ognuno vede le proprie sessioni (dispositivo, IP, scadenza) e può chiudere le altre; il cambio di password le chiude. - Dopo l'accesso si va sempre al cruscotto o all'attivazione della verifica: nessun reindirizzamento verso indirizzi esterni.
- Inviti monouso validi 7 giorni; nessun recupero password automatico via email (lo fa un amministratore, che azzera l'accesso).
- Sospensione di un utente: le sue sessioni si chiudono subito.
3. Autorizzazioni
- 23 permessi raggruppati in ruoli (vedi Ruoli e permessi). Le regole di visibilità sono dichiarative, mai codice salvato nel database.
- Doppio controllo: la pagina verifica il permesso e mostra un avviso; l'azione sul server lo verifica di nuovo; anche i download (PDF, CSV) lo verificano.
- L'azienda ha sempre almeno un amministratore attivo.
4. Cifratura
- In transito: HTTPS obbligatorio con certificato Let's Encrypt ottenuto e rinnovato automaticamente; HTTP reindirizzato a HTTPS; intestazione HSTS (2 anni). Le connessioni alle caselle di posta sono sempre cifrate (TLS o STARTTLS). Con un database esterno la connessione è sempre TLS con verifica del certificato (
verify-fulloverify-ca): una configurazione senza verifica viene rifiutata. - Segreti applicativi: cifrati con AES-256-GCM con una chiave (
APP_ENCRYPTION_KEY) che sta solo nella configurazione del server e va conservata anche fuori dal server, in un gestore di password. - Backup: cifrati con age con una chiave pubblica. La chiave privata viene creata sul server (serve a verificare ogni backup) e va copiata in un gestore di password: senza, i backup non si aprono. Chi ha solo i file dei backup, compreso il fornitore dello spazio di archiviazione, non può leggerli.
- Dischi: la cifratura dei dischi del server dipende dal fornitore di hosting scelto.
5. Registro attività
- Registra chi ha fatto cosa e quando: accessi riusciti e falliti con l'indirizzo IP, cambi di password, uscite dagli altri dispositivi, utenti e ruoli, clienti e contratti, ticket, prodotti e magazzino, documenti, impostazioni.
- Il ruolo dell'applicazione non può modificare né cancellare il registro.
- Non contiene mai password, codici, token, segreti o dati personali superflui; salva codici e dettagli, letti nella lingua di chi lo consulta.
- Consultabile dagli amministratori con filtri per area, persona, periodo e testo.
6. Protezione dell'applicazione e dell'infrastruttura
- Intestazioni di sicurezza su ogni pagina:
X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: same-origin,Permissions-Policy(niente fotocamera, microfono, posizione),Strict-Transport-Security; il server non dichiara il software usato. - Limiti alle richieste: 8 MB per richiesta al server web, 4 MB per i form (import CSV), 2 MB per le email ricevute dal gateway.
- Posta: nessuna connessione a indirizzi di rete interni o privati (contro gli attacchi SSRF), nessun ciclo di risposte automatiche, intestazioni che scoraggiano le risposte automatiche, email dei clienti mai cancellate dalla casella.
- Contenitori: app, processo della posta, migrazioni e strumenti con file system in sola lettura, nessuna capability di Linux, nessuna escalation di privilegi e un utente non amministratore; Caddy in sola lettura con la sola capability per aprire le porte 80 e 443; il database nell'immagine ufficiale di PostgreSQL; limiti di memoria per tutti.
- Rete: il database sta su una rete interna senza accesso a internet e senza porte pubbliche; sono esposte solo le porte 80 e 443 del proxy HTTPS.
- Server: aggiornamenti di sicurezza di Ubuntu e Docker installati automaticamente ogni giorno; accesso SSH solo con chiavi (raccomandato nelle guide di installazione).
- Aggiornamenti di Orafila: arrivano come pacchetto con la firma digitale del fornitore; installatore e
deploy/nova.sh updatecontrollano la firma e l'impronta di ogni file prima di cambiare qualcosa, fanno un backup e non tornano da soli a una versione precedente. Il fornitore può dare a ogni server credenziali di accesso proprie e revocarle. - Controllo di salute (
/api/health): risponde solo "ok" o "non disponibile", senza dati. - Log: i messaggi del processo della posta e della ricezione delle email non riportano indirizzi, testi né segreti; i log dei contenitori ruotano automaticamente (5 file da 10 MB per servizio).
7. Backup e continuità
- Backup completo del database ogni notte alle 02:30 (ora italiana), cifrato e verificato prima di essere conservato; un backup saltato a server spento viene fatto al riavvio.
- Copie: le ultime 7 sul server e una copia su un archivio esterno compatibile S3 (per esempio Oracle Object Storage o DigitalOcean Spaces) per 30 giorni. Su Oracle Object Storage, se si crea la regola di conservazione indicata nella guida, i backup non si possono cancellare per 29 giorni, nemmeno con le chiavi del server.
- Avviso via email se il backup di una notte non riesce, configurando un servizio esterno di controllo (per esempio Healthchecks.io).
- Ripristino in un comando, preceduto da un backup di sicurezza: il backup viene caricato in un database temporaneo che sostituisce quello attuale solo se il caricamento riesce (con un database esterno, in una sola transazione).
- Perdita massima di dati con il solo backup notturno: le modifiche successive all'ultimo backup (al massimo circa 24 ore). Con un database gestito dal fornitore cloud si aggiungono i suoi backup e, se previsto, il ripristino a un momento preciso.
- Le procedure di ripristino e di ricostruzione su un server nuovo sono descritte e vanno provate all'avvio del servizio (vedi Gestione e manutenzione).
8. Dati personali trattati
| Categoria di interessati | Dati | Note |
|---|---|---|
| Utenti dell'azienda | Nome, email, lingua, ruoli, costo orario, ultimo accesso, hash della password, segreto TOTP cifrato, sessioni (dispositivo, IP), accessi nel registro attività | |
| Contatti dei clienti | Nome, email, telefono, ruolo in azienda, referente per, consenso alle comunicazioni commerciali | Le email da un contatto aprono ticket a nome del cliente |
| Mittenti delle email | Indirizzo, oggetto e testo delle email ricevute dalle code | Le email sconosciute restano in Posta in arrivo; gli allegati non vengono importati |
| Clienti e fornitori (persone giuridiche e ditte individuali) | Dati fiscali, indirizzi, PEC, IBAN dei fornitori, documenti commerciali | |
| Dipendenti | Nome, email, telefono, dati di lavoro (mansione, reparto, contratto, ore, date di assunzione e fine), costo orario, note, assenze con eventuale nota | Per la malattia si registrano solo le date: il modulo chiede di non scrivere diagnosi né certificati nella nota (è un'indicazione, non un blocco). Il tipo di assenza lo vede chi ha «vede i dipendenti e le assenze» (di base Amministratore, Amministrazione e Risorse umane); gli altri vedono «Assente» |
9. Ruoli nel trattamento (GDPR)
- Titolare del trattamento è l'azienda che usa Orafila per i propri clienti, contatti e dipendenti.
- Responsabile del trattamento (art. 28) è chi eroga il servizio, se Orafila è fornito come servizio gestito: serve un accordo sul trattamento dei dati (DPA).
- Sub-responsabili possibili, da elencare nel DPA in base all'installazione:
| Servizio | Quando | Cosa riceve |
|---|---|---|
| Fornitore di hosting (per esempio Oracle Cloud, DigitalOcean o altro fornitore UE) | Sempre | Il server, il database e i backup cifrati |
| Archivio dei backup (dello stesso fornitore o di un altro) | Se configurato | Solo backup cifrati, illeggibili senza la chiave |
| Fornitore AI (Anthropic, OpenAI, Google) | Solo se l'AI è attiva | I dati elencati in Intelligenza artificiale |
| Fatture in Cloud | Solo se collegato | Le fatture emesse con i dati del cliente; di solito è un contratto diretto dell'azienda con il servizio |
| Fornitori delle caselle di posta e servizi di invio | Sempre, se si collegano caselle | Le email in uscita e in arrivo; di solito sono servizi dell'azienda stessa |
| Gateway di inoltro delle email | Solo se usato | Le email inoltrate |
- Dove stanno i dati: nella regione del server scelta all'installazione. Le guide di installazione usano regioni dell'Unione Europea (Milano, Francoforte, Amsterdam). Per i fornitori AI verificare dove trattano i dati e le loro condizioni.
10. Diritti degli interessati e conservazione
- Accesso e rettifica: i dati si consultano e si correggono dalle pagine dei moduli.
- Cancellazione: contatti, sedi, prodotti installati, prodotti, fornitori, dipendenti e altri record si eliminano dall'interfaccia quando non sono usati altrove; quelli collegati a documenti o storico (per esempio un contatto citato in un ticket, una fattura emessa) si modificano invece di essere cancellati, per non falsare lo storico e i documenti fiscali. Clienti, utenti, ticket ed email ricevute non si eliminano dall'interfaccia (gli utenti si sospendono): una richiesta di cancellazione di questi dati la gestisce l'operatore della piattaforma.
- Portabilità: esportazioni CSV di entrate e uscite e dei report; un'esportazione completa dei dati di un'azienda non è ancora disponibile dall'interfaccia ed è un'attività dell'operatore della piattaforma, su richiesta.
- Conservazione: oggi non ci sono cancellazioni automatiche per scadenza (per esempio dei ticket chiusi da anni); i tempi di conservazione vanno decisi dal titolare e applicati su richiesta.
11. Sviluppo sicuro
- Ogni modifica al codice passa da controlli automatici: controllo rigoroso dei tipi, centinaia di test unitari e di integrazione su database reali, test SQL di isolamento tra aziende, costruzione dell'immagine.
- Scansione dei segreti nel codice e verifica delle vulnerabilità note nelle dipendenze a ogni modifica.
- Nessun segreto nel codice: chiavi e password stanno solo nella configurazione del server.
- PDF generati in JavaScript puro, senza browser né servizi esterni sul server.
12. Cosa resta all'azienda cliente
- Assegnare ruoli con il minimo dei permessi necessari e sospendere subito chi lascia l'azienda.
- Controllare periodicamente il registro attività (per esempio gli accessi non riusciti).
- Usare caselle di posta dedicate alle code, con password per le app dove il fornitore lo richiede.
- Valutare quali funzioni AI attivare e informare, se necessario, i propri clienti e dipendenti.
- Con un'installazione sul proprio server: custodire
deploy/.env, la chiave dei backup eAPP_ENCRYPTION_KEYin un gestore di password, provare il ripristino, tenere attivo un controllo esterno del sito e dei backup.