Torna al blog Data Governance

Un’app self-hosted o più app? Un quadro decisionale per separare team e clienti

Ruoli e spazi di lavoro possono controllare l’accesso quotidiano, ma non equivalgono a un deployment indipendente. Usa questo quadro per decidere quando è appropriata un’applicazione self-hosted condivisa, quando istanze separate offrono un confine di governance più chiaro e quando è più adatto un altro modello di erogazione.

Diagramma che confronta un’istanza applicativa condivisa con istanze self-hosted separate per organizzazioni diverse

Uno spazio di lavoro, un ruolo e un deployment risolvono problemi diversi

La domanda non riguarda semplicemente se le persone debbano vedere cartelle, progetti o record differenti. Riguarda quale confine debba essere imposto, chi sia autorizzato a operare su ciascun lato di quel confine e con quale grado di indipendenza ogni gruppo debba poter cambiare e ripristinare.

Un ruolo nell’applicazione stabilisce in genere ciò che un utente autenticato può fare. Uno spazio di lavoro, un’organizzazione, un progetto o un contenitore logico simile può organizzare i record e limitare quali utenti possano visualizzarli o modificarli. Questi controlli possono essere efficaci quando l’applicazione li implementa correttamente e sono configurati, revisionati e testati. Rimangono comunque controlli all’interno di un unico deployment applicativo.

Un deployment separato è un confine di infrastruttura e operatività. In una configurazione basata su container, un [progetto Docker Compose](https://docs.docker.com/compose/intro/compose-application-model/) raggruppa le risorse di un deployment e può isolarle da altre installazioni che utilizzano parametri diversi. Un progetto separato può inoltre disporre della propria rete predefinita. Questo non lo rende un host interamente indipendente né elimina l’importanza dell’amministrazione dell’host, ma è sostanzialmente diverso dal creare un altro spazio di lavoro nella stessa applicazione.

Non usare il nome di uno spazio di lavoro come abbreviazione di un’architettura di sicurezza. Stabilisci prima ciò che l’applicazione isola effettivamente; poi decidi se tale isolamento corrisponde alla promessa fatta a un team, a un cliente, a una persona giuridica o a un’autorità di regolamentazione.

  • Confine dei ruoli utente: quali azioni possono eseguire gli utenti autenticati.
  • Confine logico dei dati: a quali record, progetti o spazi di lavoro possono accedere gli utenti all’interno di un’applicazione.
  • Confine del deployment: quali servizi applicativi, configurazione, dati persistenti, credenziali, rotte e piano di rilascio appartengono insieme.
  • Confine dell’amministratore dell’host: chi può amministrare il server, il runtime dei container, lo storage e la configurazione del deployment.
  • Confine di ripristino: quali dati possono essere ripristinati in modo indipendente, da chi e con quale effetto sugli altri utenti.
Uno spazio di lavoro, un ruolo e un deployment risolvono problemi diversi

Inizia definendo il vero confine

Un team non è sempre l’unità che richiede separazione. Il confine rilevante può essere un’organizzazione cliente, una persona giuridica, un’unità aziendale con amministratori distinti, un ambiente di produzione o una categoria di dati con requisiti speciali di gestione. Una progettazione utile inizia con una dichiarazione in linguaggio semplice di ciò che non deve oltrepassare il confine.

Ad esempio: “Il personale del Cliente A non deve accedere ai record del Cliente B” è soprattutto un requisito di accesso all’applicazione. “Il Cliente A deve avere un insieme di dati ripristinabile separatamente, integrazioni possedute separatamente e nessuna dipendenza dall’approvazione dei rilasci del Cliente B” richiede un confine operativo più forte. “Un cliente esterno non deve essere costretto a fidarsi dei nostri amministratori interni per l’accesso alla configurazione del suo servizio e ai dati archiviati” solleva una questione di hosting e fiducia amministrativa, non soltanto una questione di progettazione dei ruoli.

Quando sono coinvolti dati personali, la governance dovrebbe coprire sia la prevenzione sia il ripristino. L’[articolo 5 del GDPR](https://eur-lex.europa.eu/eli/reg/2016/679/oj?locale=EN) richiede misure tecniche o organizzative adeguate che proteggano dal trattamento non autorizzato o illecito e dalla perdita, distruzione o danno accidentali. Include inoltre la limitazione della conservazione: i dati personali identificabili non dovrebbero essere conservati più a lungo del necessario per la finalità prevista, fatte salve le eccezioni indicate. Obblighi diversi di conservazione o cancellazione sono spesso un motivo pratico per evitare un unico patrimonio dati indifferenziato.

  • Identifica la popolazione protetta: personale interno, un cliente, una persona giuridica, una funzione regolamentata o un ambiente di produzione.
  • Indica la conseguenza di un errore di accesso: disagio, violazione contrattuale, esposizione di informazioni riservate o impatto normativo.
  • Elenca le persone che necessitano di accesso privilegiato: amministratori dell’applicazione, responsabili delle integrazioni, amministratori dell’infrastruttura e personale di supporto.
  • Registra se i dati debbano essere esportati, conservati, cancellati o ripristinati secondo tempistiche differenti per ciascun gruppo.
  • Annota se il confine è una preferenza organizzativa oppure un requisito contrattuale, legale o di sicurezza.
Inizia definendo il vero confine

Quando un’unica istanza condivisa è la scelta più semplice e appropriata

Un’unica istanza condivisa può essere la risposta corretta quando i gruppi operano davvero secondo lo stesso modello di governance. Centralizza aggiornamenti, monitoraggio, amministrazione dell’autenticazione, configurazione dell’applicazione, routine di backup e supporto agli utenti. Può inoltre rendere meno frammentate la collaborazione e la reportistica tra team quando la condivisione è intenzionale e il modello di accesso dell’applicazione supporta le restrizioni necessarie.

Un modello condiviso è più solido quando l’organizzazione può descrivere e gestire un unico dominio amministrativo. Gli stessi amministratori fidati possono gestire il sistema, un unico calendario di rilascio è accettabile, le integrazioni possono essere governate centralmente e un ripristino che interessi l’intera applicazione è un evento di recovery accettabile. Spesso questo è un punto di partenza sensato per reparti interni di un’unica organizzazione con esigenze comparabili in termini di sensibilità e ciclo di vita.

Il compromesso è l’accoppiamento. Una modifica della configurazione a livello dell’applicazione, un ruolo di amministratore ampio, una credenziale di integrazione condivisa o un ripristino dell’intera istanza possono avere conseguenze su tutti i gruppi. Il modello non è insicuro per definizione; richiede semplicemente una governance disciplinata e proporzionata ai dati e alle parti interessate coinvolte.

  • Scegli un’unica istanza condivisa quando la collaborazione tra gruppi è prevista e consentita.
  • Prima di includere gruppi con dati sensibili, conferma che l’applicazione disponga dei ruoli e dei controlli di isolamento logico richiesti.
  • Applica il privilegio minimo sia agli utenti ordinari sia agli amministratori; non concedere un accesso amministrativo ampio solo per comodità.
  • Mantieni un processo regolare di revisione degli accessi, soprattutto dopo cambiamenti di personale o la cessazione del rapporto con un cliente.
  • Considera aggiornamenti, modifiche di configurazione, esportazioni e ripristini a livello dell’applicazione come cambiamenti che possono interessare ogni gruppo.

Quando istanze separate sono di solito la scelta operativa più sicura

Le istanze separate sono di solito la scelta più sicura quando i gruppi hanno dati governati in modo indipendente, amministratori fidati diversi, credenziali di integrazione incompatibili oppure requisiti distinti di ciclo di vita e ripristino. Le agenzie incontrano spesso questa situazione quando ciascun cliente si aspetta utenti, dominio, servizi collegati, esportazioni dei dati, processo di offboarding e percorso di approvazione delle modifiche propri.

Le istanze separate possono ridurre il raggio d’impatto di una configurazione errata o di un ripristino, poiché ciascuna istanza può avere la propria configurazione applicativa e il proprio ambito di dati persistenti. Rendono inoltre più semplice spiegare la titolarità: questo dominio, questa rotta, questa istanza, questo insieme di credenziali, questo ambito di backup e questo runbook appartengono a questa organizzazione. Il vantaggio non consiste nel fatto che i container eliminino ogni rischio. Consiste nel fatto che i controlli operativi possono allinearsi più strettamente al vero confine organizzativo.

[Docker raccomanda](https://docs.docker.com/engine/security/) che soltanto utenti fidati controllino il daemon Docker, perché le sue capacità possono consentire di montare directory dell’host nei container senza limitare i diritti di accesso del container. Di conseguenza, applicazioni separate su un host condiviso non eliminano la necessità di governare l’accesso degli amministratori dell’infrastruttura. La [modalità Rootless di Docker](https://docs.docker.com/engine/security/rootless/) può ridurre l’esposizione eseguendo il daemon e i container come utente non root, ma è una misura di rafforzamento dell’host, non un sostituto di domini amministrativi indipendenti.

  • Separa per organizzazione quando un cliente necessita di decisioni indipendenti sulla titolarità, sull’offboarding o sul ripristino.
  • Separa quando l’amministratore di un gruppo non dovrebbe amministrare la configurazione applicativa di un altro gruppo.
  • Separa quando credenziali, webhook, chiavi API o account esterni devono essere posseduti e ruotati in modo indipendente.
  • Separa quando tempistiche di rilascio, configurazione personalizzata, conservazione o approvazione delle modifiche differiscono sostanzialmente.
  • Vai oltre le istanze separate su un unico host quando il confine richiesto include una fiducia indipendente negli amministratori dell’infrastruttura o un isolamento contrattuale più forte.

Valuta cinque fattori decisionali prima di scegliere il modello

Usa i seguenti fattori come verifica pratica. Assegna a ogni fattore una valutazione per ogni gruppo proposto: esigenza di indipendenza bassa, media o alta. Un singolo requisito ad alto rischio può prevalere su diversi vantaggi di praticità di un modello condiviso.

La chiave è valutare controlli dimostrati, non etichette. Se l’applicazione afferma di avere organizzazioni o spazi di lavoro, prova le azioni precise che contano: visualizzare record, cercare, esportare, invitare utenti, modificare autorizzazioni, amministrare integrazioni e cancellare dati. Se un requisito non può essere dimostrato in un ambiente di test o supportato dalla documentazione dell’applicazione, consideralo non soddisfatto finché non sia provato il contrario.

  • 1. Visibilità dei dati: utenti, amministratori e personale di supporto possono vedere solo i record che sono autorizzati a gestire? Prova navigazione diretta, ricerca, report, notifiche, esportazioni e azioni di massa, non soltanto la normale interfaccia utente.
  • 2. Accesso degli amministratori: chi può modificare ruoli, configurazione, storage, log e impostazioni del deployment? Separa i ruoli applicativi dall’accesso all’host Docker, al runtime e allo storage persistente. Applica, dove pratico, la separazione dei compiti e il privilegio minimo.
  • 3. Integrazioni e segreti: ogni gruppo necessita di chiavi API, account e-mail, destinazione webhook, configurazione dell’identità o connessione a dati esterni propri? [Docker Compose può concedere un segreto](https://docs.docker.com/compose/how-tos/use-secrets/) soltanto ai servizi che lo dichiarano esplicitamente e lo monta come file. Evita di trattare le variabili d’ambiente come un archivio innocuo di segreti: Docker avverte che password e chiavi API presenti in esse possono essere esposte involontariamente, anche tramite log di debug.
  • 4. Indipendenza del ciclo di vita: ogni organizzazione può accettare la stessa finestra di aggiornamento, lo stesso baseline di configurazione, lo stesso processo di supporto e lo stesso percorso di approvazione delle modifiche? In caso contrario, la multi-tenancy condivisa crea debito di coordinamento.
  • 5. Confini di backup e ripristino: un gruppo può essere ripristinato senza riportare indietro, esporre o interrompere l’attività di un altro? La domanda importante è se la procedura di ripristino pianificata dimostri il confine necessario.

Mappa il modello di isolamento dell’applicazione prima di farvi affidamento

Ogni applicazione ha il proprio modello e i termini generici non sono sufficienti. Prima di decidere che un’istanza condivisa sia adatta, crea una mappa dei suoi controlli basata su evidenze. Usa la versione e la documentazione pertinenti al deployment pianificato, poi verifica le ipotesi importanti con account di test.

Inizia dal comportamento degli utenti ordinari, quindi amplia l’analisi. Che cosa definisce l’appartenenza? Una persona può appartenere a più di uno spazio di lavoro? I ruoli sono definiti globalmente o per spazio di lavoro? Gli utenti possono scoprire record tramite ricerca, link, report, notifiche o esportazioni al di fuori del loro ambito previsto? Le schermate di audit, amministrazione e integrazione sono disponibili a una classe di utenti più ampia rispetto alle schermate operative?

Successivamente, mappa il percorso dei dati. Identifica il database o l’archivio persistente, i file caricati, i log dell’applicazione, le esportazioni, le destinazioni e-mail o webhook e i backup. Un container front-end separato non costituisce un confine di ripristino indipendente se due organizzazioni utilizzano ancora lo stesso archivio dati o lo stesso artefatto di backup. Le [indicazioni di Docker sui volumi](https://docs.docker.com/engine/storage/volumes/) includono procedure per archiviare e ripristinare volumi nominati, rafforzando una regola fondamentale di pianificazione: i dati persistenti e una procedura di ripristino testata devono far parte della progettazione del confine.

  • Documenta separatamente i ruoli globali e i ruoli con ambito delimitato.
  • Prova la rimozione dall’appartenenza, la disattivazione degli utenti, i flussi di invito e il passaggio di consegne amministrativo.
  • Prova la visibilità dei record attraverso schermate normali, ricerca, API ove applicabile, report generati, notifiche ed esportazioni.
  • Identifica dove risiedono allegati, log, esportazioni e dati persistenti.
  • Documenta chi può accedere alla configurazione dell’applicazione, ai manifesti di deployment, allo storage dell’host, ai backup e al materiale segreto.
  • Conserva le evidenze dei test insieme alla documentazione della decisione, soprattutto per impegni verso i clienti o dati sensibili.

Confronta tre modelli pratici di deployment

Il primo modello è una sola istanza applicativa condivisa. È economicamente efficiente dal punto di vista operativo e può funzionare bene per una singola organizzazione o per un insieme di team interni strettamente governato. Fa forte affidamento sul modello di autorizzazione dell’applicazione e su un’attenta gestione degli amministratori globali, della configurazione condivisa, delle integrazioni e delle procedure di ripristino.

Il secondo modello è un’istanza applicativa per organizzazione. Ogni organizzazione riceve la propria configurazione di deployment, il proprio ambito di dati persistenti, hostname o regola di routing, amministrazione dell’applicazione e documentazione operativa. Questo fornisce tipicamente una base più chiara per credenziali separate, decisioni sui rilasci, esportazioni, azioni di conservazione e ripristini. Introduce lavoro operativo ripetuto, che deve essere pianificato anziché improvvisato.

Il terzo modello consiste in servizi infrastrutturali condivisi con istanze applicative separate. Ad esempio, [progetti Compose separati possono utilizzare](https://docs.docker.com/compose/how-tos/networking/) le proprie reti specifiche di progetto per componenti interni quali applicazione e database, collegandosi deliberatamente a una rete condivisa creata esternamente quando è necessaria la comunicazione con un servizio edge o di supporto condiviso. Questo può bilanciare coerenza e connettività applicativa delimitata, ma l’appartenenza alla rete e le rotte devono essere progettate e revisionate esplicitamente.

  • Un’istanza condivisa: ideale quando governance, amministrazione, ciclo di vita e ripristino sono realmente condivisi.
  • Un’istanza per organizzazione: ideale quando titolarità e decisioni operative devono essere indipendenti.
  • Servizi condivisi con istanze applicative separate: ideale quando un’organizzazione può centralizzare in sicurezza funzioni di piattaforma selezionate mantenendo distinti i confini dell’applicazione e del livello dati.
  • Per ogni modello, decidi esplicitamente se l’amministrazione dell’host sia condivisa, limitata o richieda un modello di separazione più forte.

Pianifica il lavoro operativo che si moltiplica con ogni istanza

Le istanze separate riducono alcuni accoppiamenti di governance, ma aumentano l’inventario operativo. Ogni istanza necessita di un proprietario noto, un modello di accesso, un dominio o una regola di routing, configurazione applicativa, credenziali, ambito di backup, aspettative di monitoraggio, cronologia degli aggiornamenti e un percorso di risposta agli incidenti. Un’agenzia che crea rapidamente istanze ma non è in grado di identificarne il proprietario o la procedura di ripristino ha creato un rischio evitabile.

La gestione di domini e TLS fa parte di questo lavoro. La [configurazione dinamica di Traefik](https://doc.traefik.io/traefik/reference/routing-configuration/dynamic-configuration-methods/) determina come le richieste in arrivo vengono instradate ai servizi e tale configurazione può essere fornita tramite meccanismi che includono etichette Docker e file. Ogni istanza necessita quindi di una mappatura accurata e mantenuta dall’hostname o dalla regola al proprio servizio. Un [router Traefik configurato per TLS](https://doc.traefik.io/traefik/v3.2/routing/routers/) gestisce le richieste HTTPS e termina TLS prima di inviare il traffico decrittografato al servizio configurato.

Anche l’automazione dei certificati ha un ciclo di vita. [Let’s Encrypt applica limiti di emissione](https://letsencrypt.org/docs/rate-limits/) alle richieste tramite il proprio endpoint API new-order. Usa uno schema di denominazione controllato, verifica il DNS prima della messa in produzione, evita di richiedere ripetutamente certificati durante test improvvisati e conserva una procedura chiara per le modifiche ai domini.

Airbip esegue le istanze applicative come carichi di lavoro Docker su server cloud Airbip e automatizza il routing e i certificati TLS tramite Traefik e Let’s Encrypt. Fornisce inoltre controlli DNS, gestione del ciclo di vita dei servizi, backup giornalieri, settimanali e mensili configurabili e la scelta tra un sottodominio Airbip e un dominio personalizzato compatibile. Queste capacità della piattaforma possono ridurre il lavoro infrastrutturale ripetitivo, ma i clienti devono comunque definire titolarità, accesso, gestione dei dati, ambito di backup, procedure di ripristino e il modello di separazione appropriato.

  • Mantieni un registro delle istanze: organizzazione, proprietario, finalità, dominio, amministratori, servizi collegati, classificazione dei dati e data di offboarding, se applicabile.
  • Usa una convenzione di dominio prevedibile e verifica la titolarità del routing prima del lancio.
  • Traccia i rilasci dell’applicazione, le modifiche di configurazione e i requisiti di approvazione per ciascuna istanza.
  • Definisci contatti per monitoraggio e incidenti per ogni istanza; non dare per scontato che un team centrale conosca il contesto pertinente del cliente.
  • Pianifica backup e test di ripristino nell’ambito promesso all’organizzazione.
  • Pianifica il lavoro di migrazione prima di adottare istanze separate, incluso il modo in cui i dati vengono spostati, gli accessi vengono trasferiti e i dati originali vengono conservati o cancellati.

Domande frequenti

Gli spazi di lavoro sono sufficienti per separare i clienti in un’applicazione self-hosted?

A volte, ma solo quando il modello di autorizzazione documentato e testato dell’applicazione soddisfa il confine richiesto. Prova visibilità, ricerca, esportazioni, amministrazione, integrazioni, log e offboarding. Gli spazi di lavoro sono controlli logici all’interno di un’applicazione; non costituiscono automaticamente confini separati di deployment, amministrazione o ripristino.

Un progetto Docker Compose separato garantisce un isolamento completo?

No. Un progetto Compose raggruppa risorse di deployment e può creare una rete predefinita specifica del progetto, il che costituisce una separazione utile a livello di deployment. Non crea di per sé una fiducia indipendente negli amministratori dell’host. Docker raccomanda di limitare il controllo del daemon Docker agli utenti fidati. Progetta deliberatamente accesso all’host, storage, reti condivise, segreti e backup.

Qual è il motivo più forte per usare un’istanza per cliente?

La governance indipendente è di solito il motivo più forte: amministratori separati, credenziali di integrazione, obblighi di conservazione o offboarding, approvazioni delle modifiche e requisiti di ripristino. Le istanze separate rendono più semplice assegnare e dimostrare queste responsabilità operative, a condizione che anche archivi dati, credenziali e procedure di backup siano separati in modo appropriato.

Le istanze separate possono condividere servizi infrastrutturali?

Sì, laddove il modello di fiducia lo consenta. Docker documenta che progetti Compose separati possono comunicare tramite una rete condivisa creata esternamente, mantenendo al contempo reti specifiche del progetto per componenti interni quali i database. Tratta ogni servizio condiviso come una scelta progettuale esplicita e verifica quali istanze possano raggiungerlo e a quali dati possa accedere.

In che modo i requisiti di backup dovrebbero influenzare la decisione?

Chiediti se ogni organizzazione necessiti di un insieme di dati ripristinabile in modo indipendente, di una priorità di ripristino separata e di un diverso proprietario o obiettivo di recovery. Un backup è utile solo se può essere ripristinato con successo nello scenario richiesto; pertanto, prova la procedura di ripristino pianificata nell’ambito necessario.

Quando dovremmo scegliere invece il SaaS o una piattaforma enterprise gestita centralmente?

Valuta un altro modello quando hai bisogno di un livello di multi-tenancy, integrazione dell’identità, evidenze di conformità, copertura del supporto, responsabilità contrattuale o separazione dell’infrastruttura che il tuo team non può gestire in modo affidabile. Una terza parte può trattare dati personali per conto di un’organizzazione laddove la relazione applicabile e le garanzie siano appropriate, ma l’organizzazione deve comunque valutare il fornitore, l’accordo, le responsabilità e l’adeguatezza alla governance dei dati.

Fonti e approfondimenti

  1. Docker Engine security — Docker
  2. Docker Compose application model — Docker
  3. Docker Compose networking — Docker
  4. Docker Compose secrets — Docker
  5. Docker volumes — Docker
  6. Docker Rootless mode — Docker
  7. Traefik routing configuration — Traefik Labs
  8. Traefik routers and TLS — Traefik Labs
  9. Let’s Encrypt rate limits — Internet Security Research Group
  10. General Data Protection Regulation — EUR-Lex, European Union