Perché la managed identity elimina i secret
Quando un’applicazione ospitata su Azure (App Service, Functions, Container Apps, VM, AKS) deve autenticarsi verso un altro servizio — Azure Key Vault, Azure Storage, Azure SQL, un endpoint di Azure AI Foundry — la strada peggiore è mettere una connection string o una chiave nel codice o in configurazione. La managed identity risolve il problema: è un’identità gestita da Microsoft Entra ID e associata alla risorsa, che ottiene automaticamente token OAuth2 senza che tu debba custodire alcun secret. Il rotation delle credenziali è trasparente e gestito dalla piattaforma.
System-assigned vs user-assigned
Le due varianti rispondono a scenari architetturali diversi:
- System-assigned: creata e legata al ciclo di vita di una singola risorsa. Nasce quando la abiliti sulla risorsa e viene eliminata automaticamente quando la risorsa viene distrutta. Relazione 1:1. Ideale quando l’identità serve a un solo workload e non deve sopravvivergli.
- User-assigned: una risorsa Azure standalone che crei separatamente e poi condividi tra più risorse (più App Service, uno scale set, più container). Ha un ciclo di vita indipendente. È la scelta giusta quando vuoi assegnare i ruoli una volta sola e riutilizzare la stessa identità su più deployment, oppure quando l’identità deve esistere prima della risorsa (pre-provisioning delle role assignment in pipeline).
Assegnare i ruoli RBAC
Avere l’identità non basta: senza autorizzazioni il token viene emesso ma l’accesso è negato. Devi creare una role assignment che leghi il principal dell’identità a un ruolo su uno scope preciso (resource, resource group, subscription). Principi chiave:
- Usa ruoli data-plane, non solo control-plane. Per leggere segreti da Key Vault serve Key Vault Secrets User, non “Reader” o “Contributor”. Per un blob serve Storage Blob Data Reader/Contributor, non “Storage Account Contributor”.
- Applica il least privilege: assegna al livello di scope più stretto possibile (il singolo Key Vault, non l’intera subscription).
- Il principal a cui assegni il ruolo deve essere quello giusto: l’object ID della system-assigned identity di quella risorsa, oppure l’object ID della user-assigned identity condivisa.
Come funziona DefaultAzureCredential
DefaultAzureCredential della Azure SDK (Azure.Identity) è pensata per far girare lo stesso codice in locale e in cloud senza modifiche. Al primo GetToken prova in sequenza una catena di credential e usa la prima che riesce:
- Environment (variabili
AZURE_CLIENT_ID/TENANT_ID/SECRETper service principal) - Workload Identity / Managed Identity (in cloud)
- Visual Studio / VS Code
- Azure CLI (
az login) / Azure PowerShell / Azure Developer CLI
In produzione scatta la managed identity; sullo sviluppatore scattano le sue credenziali interattive (az login). Il pattern d’uso è semplicemente passare la credential al client:
var client = new SecretClient(
new Uri("https://kv-app.vault.azure.net/"),
new DefaultAzureCredential());
Il caso della user-assigned identity
Qui sta la sottigliezza più importante: se la risorsa ha più identità (es. la system-assigned più una o più user-assigned), l’Instance Metadata Service non sa quale usare e la richiesta di token è ambigua. Devi disambiguare passando il client ID:
var cred = new DefaultAzureCredential(
new DefaultAzureCredentialOptions {
ManagedIdentityClientId = "<user-assigned-client-id>"
});
Senza questo, la credential può fallire o autenticarsi con l’identità sbagliata — token emesso ma accesso negato dal RBAC.
Trappole tipiche d’esame
- App con user-assigned identity ma senza client ID nella credential → l’autenticazione fallisce o è ambigua: imposta
ManagedIdentityClientId(o la env varAZURE_CLIENT_ID) suDefaultAzureCredentialOptions. - Role assignment fatta al principal sbagliato (es. all’utente sviluppatore o alla system-assigned invece che alla user-assigned condivisa) → in produzione arriva 403. Assegna il ruolo all’object ID dell’identità effettivamente usata dall’app.
- Assegnato “Contributor” ma l’app non legge i segreti → serve il ruolo data-plane (Key Vault Secrets User, Storage Blob Data Reader), non un ruolo control-plane.
- “Funziona in locale, fallisce in cloud” → in locale usa le credenziali dello sviluppatore; in cloud manca la managed identity abilitata o la role assignment: verifica che l’identità sia attiva e correttamente autorizzata.
- Serve un’identità che sopravvive alla risorsa o condivisa tra più app → scegli user-assigned; se deve morire con la risorsa e serve a un solo workload, system-assigned.