Tre controlli rispondono alla stessa domanda: che cosa succede quando qualcuno, per errore o per dolo, prova a cancellare. Il blocco risorsa ferma la richiesta prima che raggiunga il provider, Azure Backup fa sopravvivere i dati alla cancellazione, e l’infrastruttura come codice evita che questi controlli dipendano da chi si ricorda di riapplicarli dopo il prossimo deploy.
Blocchi risorsa: solo control plane, davvero
I livelli sono due. CanNotDelete (nel portale «Delete») lascia leggere e modificare ma non eliminare; ReadOnly («Read-only») riduce chiunque, in pratica, ai permessi del ruolo Reader. La differenza rispetto a RBAC è sostanziale: il blocco vale per tutti gli utenti e tutti i ruoli, Owner compreso. Non è un permesso, è un veto.
Il blocco si eredita verso il basso e vince sempre il più restrittivo della catena. Le risorse di estensione ereditano da quella a cui sono applicate: bloccando un account di archiviazione non elimini più l’impostazione di diagnostica agganciata a un suo blob. Un blocco di eliminazione su una sola risorsa fa fallire l’eliminazione dell’intero gruppo di risorse, perché una cancellazione parziale non esiste. Ai gruppi di gestione i blocchi non si applicano.
Il punto che fa male in produzione è che i blocchi coprono solo le operazioni di control plane, quelle dirette a management.azure.com. Un ReadOnly su un account di archiviazione non protegge i dati: la File Shares - Delete del provider fallisce, la Delete Share di data plane riesce.
E poiché il blocco intercetta anche le POST, gli effetti collaterali sorprendono:
ReadOnly su storage account -> List Keys negato; niente assegnazioni RBAC sull'account o sul contenitore
ReadOnly su gruppo con VM -> nessuno avvia o riavvia le macchine virtuali
CanNotDelete sul gruppo creato da Azure Backup -> i backup falliscono: il servizio non ripulisce i punti di ripristino (massimo 18)
Per creare o rimuovere un blocco servono le azioni Microsoft.Authorization/locks/*: le hanno Owner e User Access Administrator, non Contributor.
Azure Backup: rendere il vault non svuotabile
Primo strato, l’eliminazione temporanea: se cancelli il backup di una VM i dati restano 14 giorni aggiuntivi, senza costo. La versione avanzata la rende always-on, non più disattivabile.
Il vault immutabile è lo strato che conta contro un attaccante. Ha tre stati: Disabled, Enabled (blocca le operazioni distruttive ma si può disattivare) ed Enabled and locked, che aggiunge l’archiviazione WORM ed è irreversibile. Con immutabilità attiva non puoi interrompere la protezione eliminando i dati, non puoi ridurre la retention di un criterio né sostituirlo con uno più corto; puoi aumentarla e cambiare la pianificazione. Attenzione al perimetro: l’immutabilità non copre i backup operativi di blob, file e dischi.
Sui livelli di sicurezza del vault: «Excellent» richiede immutabilità o soft delete irreversibile e MUA; uno solo dei due vale «Good», la sola MUA «Fair».
Multi-user authorization: la seconda chiave sta altrove
La MUA usa una risorsa separata, il Resource Guard, come autorizzatore aggiuntivo per le operazioni critiche del vault. Il prerequisito che la fa funzionare o la annulla è uno solo: l’amministratore del backup non deve avere Contributor, Backup MUA Admin né Backup MUA Operator sul Resource Guard. Gli serve il ruolo Reader per abilitare la MUA sul vault, nient’altro. Quando deve eseguire un’operazione critica chiede — via PIM, con revoca a scadenza — il ruolo Backup MUA Operator, che consente le operazioni protette ma non l’eliminazione del Resource Guard. Concedere Contributor «solo per stavolta» dà anche il diritto di cancellarlo: è l’errore che vanifica tutto.
Due operazioni sono obbligatorie e non escludibili: disabilitare il soft delete e rimuovere la protezione MUA. Le altre sono opzionali, e un default va ricordato — il ripristino è escluso di default, quindi non è protetto finché non lo abiliti. L’isolamento massimo si ottiene mettendo il Resource Guard in un tenant diverso. E la MUA copre solo le operazioni sul vault: quello che accade sulla sorgente dati è fuori dal suo raggio.
Infrastruttura come codice: scrivere il controllo una volta sola
Nei modelli, la regola dei blocchi è la posizione dello scope: si omette quando il blocco ha lo stesso ambito del deployment (gruppo di risorse o sottoscrizione), si imposta quando blocchi una risorsa interna al deployment.
Bicep, blocco sul gruppo di risorse: resource lockRg 'Microsoft.Authorization/locks@2016-09-01' (nessuno scope)
Bicep, blocco su una risorsa: aggiungi scope: webSite
Assegnazione di criterio: 'Microsoft.Authorization/policyAssignments@2023-04-01' con scope: resourceGroup()
Il flusso policy as code è quello da riconoscere: definizioni e assegnazioni in controllo del codice sorgente, prima assegnazione con enforcementMode disabled lontano dalla produzione (audita senza bloccare), poi identità gestita concessa all’assegnazione e prova delle attività di correzione per gli effetti deployIfNotExists e modify, infine passaggio a enabled e promozione progressiva. Microsoft raccomanda un deploy centralizzato — GitHub workflows o Azure Pipelines — con i permessi di scrittura sulle risorse di criterio limitati alla sola identità della pipeline.
Lo spostamento a sinistra si fa con l’estensione Microsoft Security DevOps per Azure DevOps: Template Analyzer (ARM e Bicep), Checkov, Terrascan e Trivy per l’IaC, più Bandit, BinSkim ed ESLint. Per installarla serve Project Collection Administrator. Due dettagli operativi: l’input break è false di default, quindi la pipeline non fallisce sui rilievi ad alta severità finché non lo imposti; e l’artefatto deve chiamarsi CodeAnalysisLogs, altrimenti Defender for Cloud non ingerisce i risultati SARIF. CredScan è deprecata dal 2023: quel ruolo è passato a GitHub Advanced Security for Azure DevOps.