La sicurezza è la parte dell’architettura che la maggior parte dei team tratta come lavoro di qualcun altro fino al giorno in cui non lo è. Il cloud security team scrive le policy, il platform team fa girare l’IAM, i data engineer cablano insieme le pipeline e assumono che qualunque permesso serva loro verrà concesso su richiesta. Il risultato è un sistema in cui nessuna singola persona ha un modello mentale end-to-end di chi può leggere cosa, e una piccola misconfiguration da qualche parte produce una storia sui giornali.
L’inquadramento che prende questa lezione è che la sicurezza è architettura portante, allo stesso modo in cui consistenza, partitioning e replicazione sono portanti. Non è uno strato che si imbullona alla fine; è un insieme di vincoli che modella ogni componente. Una piattaforma dati costruita sulle assunzioni sbagliate riguardo a identità e permessi passerà anni a retrofittare controlli che dovevano esserci dall’inizio.
La buona notizia è che i principi sono pochi e i pattern sono ben compresi. Il lavoro sta nell’applicarli con consistenza, non nell’inventarli.
Tre principi
Tre principi coprono la maggior parte di ciò che un architetto operativo deve interiorizzare. Si rinforzano a vicenda, e un sistema a cui ne manca anche solo uno ha una postura fragile.
Least privilege. Ogni attore nel sistema, sia un utente umano, un service account, o un ruolo assunto da un workload, ottiene esattamente i permessi di cui ha bisogno per fare il suo lavoro, e niente di più. Il default è nulla; i permessi sono concessi esplicitamente. La frase che conta è “default deny”: se un permesso non è stato esplicitamente concesso, l’azione è proibita. Questo suona burocratico finché non arriva il giorno in cui un service account viene compromesso e il blast radius è esattamente il piccolo set di azioni che era autorizzato a fare, invece dell’intero account AWS.
La versione pratica è che ogni ruolo IAM parte vuoto e cresce per accrescimento mano a mano che il team identifica cosa fa effettivamente il workload. I permessi wildcard come Action: * sono allettanti perché rimuovono una classe di piccole frizioni, ma rimpiazzano quelle frizioni con un singolo rischio enorme. Un ruolo che può fare qualunque cosa è un ruolo che, una volta rubato, può fare qualunque cosa.
Defense in depth. Assumi che qualunque singolo strato dell’architettura di sicurezza possa essere violato. Il sistema rimane sicuro perché ci sono più strati tra l’attaccante e i gioielli della corona. Un firewall perimetrale, più l’autenticazione su ogni richiesta interna, più l’autorizzazione su ogni operazione, più la cifratura dei dati at rest, più l’audit logging che registra chi ha fatto cosa. Un attaccante che supera il firewall deve comunque autenticarsi; un attaccante che ruba una credenziale deve comunque trovare un modo di usarla che l’audit log non segnali; un attaccante che esfiltra dati li trova comunque cifrati con chiavi che non può raggiungere.
Il principio è onesto sui limiti umani. Ogni strato avrà bug. Ogni strato sarà occasionalmente misconfigurato. La domanda è se un singolo bug o misconfiguration sia sufficiente a compromettere il sistema, o se diversi dovrebbero allinearsi. La defense in depth rende il secondo caso più probabile del primo.
Zero trust. Il modello classico di sicurezza assumeva che le richieste originate dentro la rete aziendale fossero affidabili e quelle dall’esterno no, e il firewall era la linea che le separava. Lo zero trust rifiuta questo. La posizione di rete non è una credenziale. Ogni richiesta, sia che venga da un laptop sul Wi-Fi dell’ufficio o da un cellulare sulla rete di un bar, deve essere autenticata e autorizzata sui propri meriti. Questo diventa specialmente importante una volta che i workload sono distribuiti su region cloud, data centre on-prem, SaaS di vendor, e laptop di contractor, ognuno dei quali ha posture di rete diverse.
La conseguenza architetturale è mTLS tra servizi, identity-aware proxy davanti alle applicazioni interne, e policy di accesso condizionale che considerano la postura del dispositivo, la posizione, e il comportamento invece della sola appartenenza alla rete.
Le pezze architetturali
I principi hanno bisogno di implementazioni. I componenti qui sotto sono i pezzi che ogni piattaforma dati seria ha, in qualche forma, e una piattaforma a cui ne manca uno qualunque è esposta in un modo su cui il team dovrebbe essere onesto.
Identity and access management. L’IAM è il sistema di record per chi esiste e cosa può fare. Ogni cloud ha il proprio (AWS IAM, Azure Entra ID, GCP IAM); ogni enterprise ha tipicamente un identity provider centrale sopra, spesso Okta o Azure Entra, che emette token usati attraverso sistemi cloud e SaaS via SAML o OIDC. L’obiettivo architetturale è una fonte unica di verità per l’identità, federata ovunque, con single sign-on per gli umani e credenziali short-lived per i workload.
La parte “credenziali short-lived per i workload” merita enfasi. Gli access key long-lived cotti dentro file di config sono una fonte perenne di breach. Il pattern moderno è che i workload assumono ruoli in virtù di dove girano: un’istanza EC2 assume un ruolo attraverso l’instance metadata service; un pod Kubernetes assume un ruolo attraverso IRSA o Workload Identity; un runner CI assume un ruolo attraverso federazione OIDC con il vendor del source control. La credenziale esiste solo dentro il workload, solo per la durata del suo task, e non appare mai in alcuna forma persistita.
Network segmentation. Anche con lo zero trust come principio, i controlli di rete sono uno strato aggiuntivo utile. VPC di produzione separati da quelli di sviluppo. Subnet segmentate per tier, con security group che permettono solo il traffico di cui ogni tier ha bisogno. Network policy di Kubernetes che impongono default-deny tra namespace e regole di allow esplicite tra servizi che hanno bisogno di parlarsi. L’obiettivo non è rendere la rete il confine di sicurezza; è assicurarsi che un attaccante che raggiunge una parte della rete non abbia automaticamente raggiunto ogni altra parte.
Secret management. I segreti sono credenziali, API key, chiavi di firma, materiale crittografico. Non appartengono al source control, alle variabili d’ambiente cotte nelle immagini Docker, o ai fogli di calcolo condivisi. Appartengono a uno store dedicato di segreti: AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, HashiCorp Vault, o una delle opzioni SaaS come Doppler o Infisical. Lo store fornisce versioning, rotazione, audit logging, e controllo degli accessi a granularità fine. I workload tirano i segreti all’avvio, non li scrivono mai su disco, e li ruotano su una cadenza che il security team può verificare.
L’anti-pattern classico è la password di produzione committata in una repo privata. Le repo private trapelano. I backup delle repo private trapelano. I fork fatti per debug trapelano. Qualunque cosa nella history di git è, su una timeline abbastanza lunga, pubblica.
Audit log. Ogni azione amministrativa e ogni accesso a dati sensibili scrive su un log che è append-only, immutabile, e archiviato separatamente dall’ambiente di produzione. CloudTrail, GCP Audit Logs, log di attività di Azure Monitor, più eventi di audit a livello applicativo per il data plane. Il log risponde a domande che il team avrà eventualmente bisogno di rispondere: chi ha cancellato questa risorsa, quando questo utente ha acceduto ai dati di questo cliente, quale ruolo IAM ha fatto questa chiamata API. Una piattaforma che non sa rispondere a queste non è in compliance con la maggior parte dei framework regolatori, ed è anche incapace di investigare i propri incidenti.
La parte “archiviato separatamente” conta. Un attaccante che raggiunge la produzione non dovrebbe raggiungere anche l’audit log, o cancellerà la traccia dietro di sé. Il pattern standard è spedire i log di audit a un account diverso, spesso con credenziali write-only dalla produzione verso l’account dei log.
Il modello di responsabilità condivisa
Il cloud cambia il confine di sicurezza in modi che i team a volte sbagliano. Lo shared-responsibility model è il contratto esplicito tra cloud provider e cliente: il provider mette in sicurezza le parti che controlla; il cliente mette in sicurezza le parti che controlla; il confine dipende dal servizio.
Per l’infrastruttura raw (IaaS, come EC2): il provider mette in sicurezza il data centre fisico, l’hypervisor, il fabric di rete. Il cliente mette in sicurezza il sistema operativo, il codice applicativo, i dati sui volumi, l’IAM che concede accesso a tutto.
Per le piattaforme managed (PaaS, come RDS o BigQuery): il provider mette in sicurezza anche il database engine, il sistema operativo sotto, il patching e i backup dell’engine. Il cliente mette comunque in sicurezza i dati dentro il database, l’IAM che concede accesso, i controlli di rete davanti, il codice applicativo che emette le query.
Per il SaaS (come Snowflake, GitHub, Datadog): il provider mette in sicurezza la maggior parte dello stack. Il cliente è responsabile dell’IAM (chi nella sua organizzazione può loggarsi e come), della classificazione dei dati (cosa carica), e dei controlli di integrazione (come il SaaS si collega ai suoi altri sistemi).
L’errore che fanno i team è assumere che la responsabilità del cloud provider si estenda oltre quanto fa. Il “cifrato di default” di un provider di solito significa cifratura at rest usando la sua chiave, che protegge contro un disco rubato, non contro un attaccante che ha rubato credenziali IAM e può chiedere al servizio di decifrare. I controlli di sicurezza di rete del provider non fermano i bucket pubblici misconfigurati. Le responsabilità del cliente esistono, e il team deve sapere quali si applicano a quale servizio.
Defense in depth, disegnata
flowchart LR
A[Attacker]
P[Public surface<br/>WAF, DDoS, rate limiting]
AU[Authentication<br/>SSO, MFA, mTLS]
AZ[Authorization<br/>IAM, RBAC, ABAC]
N[Network controls<br/>VPC, subnets, security groups]
E[Encryption<br/>at rest, in transit]
S[Sensitive resource<br/>customer data]
L[Audit log]
A --> P --> AU --> AZ --> N --> E --> S
P -.events.-> L
AU -.events.-> L
AZ -.events.-> L
N -.events.-> L
E -.events.-> L
S -.events.-> L
Il punto visivo è che la risorsa sensibile sta dietro diversi controlli, ognuno indipendente dagli altri. Un attaccante deve sconfiggere ognuno a turno. Ogni controllo scrive su un audit log separato che un investigatore può usare per ricostruire cosa è successo. Una violazione di un singolo strato non compromette la risorsa da sola.
Pattern architetturali da interiorizzare
Una breve lista di pattern che dovrebbero essere il default nel 2026, non eccezioni riservate ai sistemi più regolamentati.
Cifratura at rest e in transit, di default. Ogni database cifrato su disco. Ogni connessione tra servizi che usa TLS. Ogni backup cifrato nel bucket. Il costo è approssimativamente zero nei servizi cloud moderni e il beneficio, il giorno in cui un disco viene rubato o viene installato un network tap, è enorme.
Mutual TLS tra servizi. Ogni servizio autentica ogni altro servizio con un certificato client, non solo una API key. I service mesh (Istio, Linkerd, Consul) forniscono mTLS automaticamente. Il mesh rimuove la tentazione di saltare il lavoro perché era difficile da configurare manualmente.
Credenziali short-lived, mai cotte dentro. Niente access key in variabili d’ambiente cotte dentro le immagini. I workload assumono ruoli a runtime; i token scadono in minuti o ore. La rotazione accade automaticamente, non come progetto trimestrale.
L’audit log backuppato separatamente. La produzione non può raggiungere l’archivio dei log. L’archivio dei log non può essere modificato, solo aggiunto. La retention corrisponde al più lungo requisito regolatorio a cui il business è soggetto.
Errori architetturali comuni
L’immagine speculare dei pattern. Ognuno di questi ha prodotto un breach pubblico negli ultimi anni; nessuno è raro; tutti sono prevenibili.
IAM wildcard. Un ruolo con Action: * su Resource: * perché qualcuno aveva bisogno di spedire e il set di permessi più piccolo era difficile da calcolare. Il ruolo viene rubato e l’attaccante ha l’intero account. Prevenzione: tooling che inferisce i permessi necessari dall’uso reale, più review gate sulle policy ampie.
Bucket S3 pubblici. Un bucket marcato come leggibile pubblicamente perché era il modo più facile per condividere un file con un contractor. Il bucket contiene anche, tre anni dopo, una copia di un backup che nessuno ricordava. Prevenzione: settings di block-public-access a livello account e tooling che scansiona i bucket che li bypassano.
Credenziali di default. Una password admin del database impostata su qualcosa di memorizzabile quando il cluster è stato provisionato e mai ruotata. Un pannello admin raggiungibile sull’internet pubblico con admin / admin. Prevenzione: automazione di provisioning che genera password random archiviate nel secret manager, e default leggibili dagli umani resi impossibili dalla configurazione.
Segreti in git. API key in file .env committati per sbaglio. Chiavi private SSH messe dentro per “comodità”. Prevenzione: pre-commit hook che scansionano per pattern di segreti, scanning della repository da parte del vendor del source control, e procedure di rotazione per qualunque segreto sia mai apparso in un commit.
Lo schema in tutti e quattro gli errori è lo stesso: una piccola scorciatoia presa sotto pressione di scadenza, in un contesto in cui la conseguenza era astratta. La difesa architetturale è rendere le scorciatoie più difficili da prendere del percorso giusto.
Cosa significa “fatto bene”
Un team con una postura di sicurezza sana ha l’IAM come sistema di record per l’identità, federato attraverso un provider centrale, con i workload che usano credenziali short-lived e gli umani che usano SSO con MFA. Segmentazione di rete tra ambienti, con regole default-deny e allow list esplicite. Un secret manager con la rotazione imposta. Un audit log spedito a un account separato, backuppato, e interrogato regolarmente. Cifratura attiva di default per ogni data store e ogni connessione. Un threat model documentato che il team rivisita quando l’architettura cambia.
Questo non è solo lavoro del security team. È una proprietà della piattaforma, mantenuta dai proprietari della piattaforma come parte del farla girare. La discussione sull’infrastructure-as-code della lezione 53 si collega direttamente: ogni policy IAM, ogni regola di rete, ogni configurazione del secret store appartiene al codice, in review, e versionata. La configurazione di sicurezza che vive solo nella console cloud è configurazione di sicurezza che drifta.
La prossima lezione è sui framework regolatori che trasformano molti di questi pattern da “buona pratica” in obbligo legale: GDPR, CCPA, le leggi sulla privacy che hanno implicazioni architetturali che la maggior parte dei team sottostima fino al primo email del regolatore.
Citazioni e ulteriori letture
- NIST SP 800-207, “Zero Trust Architecture”,
https://csrc.nist.gov/publications/detail/sp/800-207/final(consultato 2026-05-01). Il documento di riferimento per lo zero trust come modello architetturale formale. - NIST Cybersecurity Framework 2.0,
https://www.nist.gov/cyberframework(consultato 2026-05-01). Il framework di alto livello che lega insieme identità, protezione, detection, response, e recovery. - CIS Controls v8,
https://www.cisecurity.org/controls/v8(consultato 2026-05-01). La lista pratica e prioritizzata di controlli che ogni organizzazione dovrebbe implementare, grosso modo nell’ordine in cui dovrebbe implementarli. - AWS, “Best practices for IAM”,
https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html(consultato 2026-05-01). I consigli canonici AWS sull’IAM, compreso l’avviso sui permessi wildcard e i pattern delle credenziali workload menzionati sopra. - OWASP Top 10,
https://owasp.org/www-project-top-ten/(consultato 2026-05-01). Lo specchio a livello applicativo delle preoccupazioni a livello piattaforma trattate qui.