Proteggere una soluzione di Azure AI non significa solo scrivere buon codice di inferenza: significa decidere come un client prova la propria identità e da dove può raggiungere la risorsa. In AI-102 questi due assi — identità e rete — vengono valutati insieme, tipicamente in scenari “quale opzione scelgo e perché”.

Autenticazione: chiave, token e Microsoft Entra ID

Ogni risorsa Azure AI (Azure AI Foundry, Azure OpenAI, Speech, Vision, Language, Document Intelligence) espone tre modalità di accesso al piano dati:

  • Subscription key: due chiavi statiche rigenerabili, passate nell’header Ocp-Apim-Subscription-Key. Semplici ma sono segreti condivisi: chi le possiede è la risorsa, senza granularità né tracciabilità dell’utente. Vanno rigenerate periodicamente e non dovrebbero mai finire nel codice.
  • Token temporaneo: alcune API (es. Speech) scambiano la chiave per un token JWT a breve durata, utile per client che non devono conservare la chiave.
  • Microsoft Entra ID: il chiamante ottiene un access token OAuth 2.0 dal tenant e viene autorizzato tramite RBAC. È l’approccio raccomandato perché elimina i segreti, abilita Conditional Access e MFA, e registra chi ha fatto cosa.

Managed identity vs chiavi statiche

Quando il client è a sua volta un servizio Azure (App Service, Functions, Container Apps, VM, AKS), la scelta corretta è quasi sempre una managed identity, non una chiave in una app setting.

  • System-assigned: legata al ciclo di vita della singola risorsa, creata e distrutta con essa. Ideale per un’identità 1:1 non riutilizzabile.
  • User-assigned: risorsa Entra ID indipendente, assegnabile a più servizi e persistente anche se la risorsa che la usa viene ricreata. Preferibile quando più componenti condividono lo stesso ruolo o quando vuoi pre-configurare i permessi prima del deploy (evita il problema “chicken-and-egg” delle pipeline).

Con DefaultAzureCredential l’SDK usa automaticamente la managed identity in Azure e le credenziali dello sviluppatore in locale, senza cambiare codice.

RBAC a privilegio minimo

Assegna il ruolo più stretto che copre lo scenario, sullo scope più ristretto (la singola risorsa, non l’intera subscription):

  • Cognitive Services User: consente le chiamate al piano dati (inferenza) e la lettura delle chiavi. È il ruolo giusto per un’app che invoca il modello.
  • Cognitive Services OpenAI User: variante specifica per Azure OpenAI / model deployment.
  • Evita Contributor o Cognitive Services Contributor per un semplice client: darebbero permessi di gestione non necessari.

Restringere l’accesso di rete

Di default l’endpoint è pubblico. Puoi stringerlo progressivamente:

  • IP firewall / selected networks: consenti solo indirizzi o VNet specifici. Con il binding di service endpoint una subnet può raggiungere la risorsa restando sul backbone Azure, ma il traffico usa comunque l’IP pubblico del servizio.
  • Private endpoint (Azure Private Link): crea una NIC privata nella tua VNet con un IP privato. Il traffico non tocca Internet e va risolto via Private DNS zone (es. privatelink.cognitiveservices.azure.com), altrimenti il nome continua a puntare all’endpoint pubblico. È l’opzione da scegliere quando il requisito è “nessuna esposizione pubblica”. Ricorda di impostare Public network access = Disabled.

La combinazione che l’esame ama

Disabilitare l’accesso a chiave locale (disableLocalAuth) forza l’uso di Entra ID: da quel momento le subscription key non funzionano più e ogni chiamata deve presentare un token con il ruolo RBAC adeguato. Le managed identity non servono solo per un’app verso l’AI: abilitano l’accesso service-to-service senza segreti. Esempio classico: Azure AI Search che indicizza documenti in Azure Storage o chiama un modello in Azure OpenAI usando la propria managed identity, a cui assegni Storage Blob Data Reader o Cognitive Services OpenAI User — nessuna connection string nel data source.

Trappole tipiche d’esame

  • “Nessun segreto nel codice, il servizio gira su App Service” → managed identity + ruolo Cognitive Services User, non una chiave in Key Vault.
  • “L’identità deve pre-esistere al deploy o essere condivisa da più risorse”user-assigned managed identity, non system-assigned.
  • “Forzare l’autenticazione solo Entra ID” → imposta disableLocalAuth = true; le chiavi smettono di funzionare (aspettati 401 se qualcuno le usa ancora).
  • “Endpoint non raggiungibile via Internet, solo dalla VNet”private endpoint con Private Link + Private DNS zone e Public network access disabilitato; il solo IP firewall non basta.
  • “AI Search deve leggere lo Storage senza connection string” → managed identity di Search + ruolo dati sullo Storage, non una SAS o account key.