Ultima parte din setul despre Azure Key Vault. În partea 1 am integrat Key Vault cu IConfiguration, iar în partea 2 am acoperit rotația și certificatele. Aici vedem controlul accesului și integrarea cu App Service.
Acces granular prin RBAC
Cu RBAC activat pe Key Vault, poți controla accesul la nivel de secret individual, nu doar la nivel de vault. Aceasta permite principiul least privilege: o aplicație care are nevoie doar de Stripe--ApiKey nu trebuie să aibă acces la toate secretele din vault.
Roluri built-in pentru Key Vault
| Rol | Permisiuni | Use case |
|---|---|---|
| Key Vault Administrator | Full control | Operații de management, nu pentru aplicații |
| Key Vault Secrets Officer | CRUD secrete | CI/CD pipelines care rotesc secrete |
| Key Vault Secrets User | Read secrete | Aplicații care consumă secrete |
| Key Vault Certificates Officer | CRUD certificate | Servicii de management certificate |
| Key Vault Crypto Officer | CRUD chei criptografice | Servicii de criptare |
| Key Vault Reader | Read metadata | Monitorizare, audit |
Atribuire rol la nivel de secret individual
KV_ID=$(az keyvault show \
--name my-app-keyvault \
--resource-group my-rg \
--query id -o tsv)
PRINCIPAL_ID=$(az webapp identity show \
--name my-app-service \
--resource-group my-rg \
--query principalId -o tsv)
# Acces la TOATE secretele din vault
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Key Vault Secrets User" \
--scope $KV_ID
# Acces DOAR la secretul Stripe--ApiKey
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Key Vault Secrets User" \
--scope "$KV_ID/secrets/Stripe--ApiKey"
Scope-ul granular (/secrets/NumeSecret) înseamnă că aplicația poate citi exact secretele de care are nevoie și nimic altceva. Dacă o altă aplicație are nevoie de SendGrid--ApiKey, primește acces separat, pe exact acel secret.
Audit trail complet
# Activare diagnostic logs pentru Key Vault
az monitor diagnostic-settings create \
--name "keyvault-audit" \
--resource $KV_ID \
--logs '[{"category": "AuditEvent", "enabled": true}]' \
--workspace "/subscriptions/.../workspaces/my-workspace"
// Interogare in Log Analytics: cine a accesat ce secret
AzureDiagnostics
| where ResourceType == "VAULTS"
| where OperationName == "SecretGet"
| project TimeGenerated, CallerIPAddress, identity_claim_oid_g, id_s
| order by TimeGenerated desc
Cu audit logging activat, fiecare acces la un secret e înregistrat: ce identitate a accesat, ce secret, la ce oră, de la ce IP. Exact ce lipsea cu variabilele de mediu.
Key Vault References în App Service
Key Vault References e o funcționalitate App Service care permite să referi un secret din Key Vault direct în Application Settings, fără nicio modificare în cod. App Service rezolvă referința la runtime și injectează valoarea reală ca variabilă de mediu.
Sintaxa pentru o referință Key Vault în Application Settings:
@Microsoft.KeyVault(SecretUri=https://my-app-keyvault.vault.azure.net/secrets/Stripe--ApiKey/)
Configurare prin Azure CLI
az webapp config appsettings set \
--name my-app-service \
--resource-group my-rg \
--settings \
"Stripe__ApiKey=@Microsoft.KeyVault(SecretUri=https://my-app-keyvault.vault.azure.net/secrets/Stripe--ApiKey/)" \
"SendGrid__ApiKey=@Microsoft.KeyVault(SecretUri=https://my-app-keyvault.vault.azure.net/secrets/SendGrid--ApiKey/)"
App Service rezolvă referința automat. Aplicația ta citește configuration["Stripe:ApiKey"] și primește valoarea reală — nu referința. Dacă rotești secretul în Key Vault (și omiți versiunea din URI), App Service preia automat noua versiune.
References vs. AddAzureKeyVault
| Criteriu | Key Vault References | AddAzureKeyVault |
|---|---|---|
| Modificări în cod | Zero — transparent | Provider în Program.cs |
| Suport platforme | App Service, Functions, Container Apps | Orice aplicație .NET |
| Prefix filtering | Nu | Da, prin manager custom |
| Reload fără restart | Automat la rotație | Da, cu ReloadInterval |
| Granularitate RBAC | La nivel de secret | La nivel de vault sau secret |
Recomandarea practică: folosește Key Vault References pentru secretele injectate ca variabile de mediu simple, și AddAzureKeyVault când ai nevoie de prefix filtering, reload control granular sau când aplicația nu rulează pe App Service.
Pattern complet: configurație fără niciun secret hardcodat
Combinând Managed Identity cu Key Vault, configurația completă a aplicației arată astfel:
// appsettings.json -- zero secrete, doar structura si valori non-sensitive
{
"Logging": { "LogLevel": { "Default": "Information" } },
"KeyVaultUri": "https://my-app-keyvault.vault.azure.net/",
"CosmosDb": {
"Endpoint": "https://my-cosmos.documents.azure.com:443/",
"DatabaseName": "MyAppDb"
},
"Storage": {
"ServiceUri": "https://mystorage.blob.core.windows.net"
}
// Stripe:ApiKey si SendGrid:ApiKey vin din Key Vault
}
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsProduction())
{
var kvUri = builder.Configuration["KeyVaultUri"]!;
builder.Configuration.AddAzureKeyVault(
new Uri(kvUri),
new DefaultAzureCredential(),
new AzureKeyVaultConfigurationOptions
{
ReloadInterval = TimeSpan.FromMinutes(30)
});
}
var credential = new DefaultAzureCredential();
// Cosmos DB si Blob Storage -- fara secrete (Managed Identity)
builder.Services.AddSingleton(_ => new CosmosClient(
builder.Configuration["CosmosDb:Endpoint"]!, credential));
builder.Services.AddSingleton(_ => new BlobServiceClient(
new Uri(builder.Configuration["Storage:ServiceUri"]!), credential));
// Stripe si SendGrid -- secrete din Key Vault, cu validare la startup
builder.Services.AddOptions()
.BindConfiguration("Stripe").ValidateDataAnnotations().ValidateOnStart();
builder.Services.AddOptions()
.BindConfiguration("SendGrid").ValidateDataAnnotations().ValidateOnStart();
var app = builder.Build();
app.MapControllers();
await app.RunAsync();
Checklist Azure Key Vault
- Key Vault creat cu RBAC activat —
--enable-rbac-authorization true, nu Access Policies - Secretele au date de expirare — și notificări configurate înainte de expirare
- ReloadInterval configurat — pentru rotație fără restart de aplicație
- IOptionsSnapshot sau IOptionsMonitor — în loc de IOptions când ai nevoie de valori actualizate
- RBAC granular — fiecare aplicație are acces doar la secretele de care are nevoie
- Audit logging activat — toate accesele la secrete înregistrate în Log Analytics
- Key Vault References — pentru Application Settings în App Service, fără modificări în cod
- Certificate cu AutoRenew — reînnoire automată cu 30 de zile înainte de expirare
Dacă ai întrebări sau vrei să discuți cum structurezi Key Vault-ul pentru proiectul tău, scrie-mi la contact@ludoprogramming.com.