Acesta e primul dintr-un set de trei articole despre Azure Key Vault. Aici acoperim integrarea cu sistemul de configurare. În partea a doua urmează rotația secretelor și certificatele, iar în a treia accesul granular prin RBAC și Key Vault References.
De ce Key Vault și nu doar variabile de mediu
În articolul despre Managed Identity am eliminat secretele pentru resursele Azure — aplicația accesează Cosmos DB și Blob Storage fără nicio credențială stocată. Dar există întotdeauna un reziduu: chei API pentru servicii terțe (Stripe, SendGrid, Twilio), credențiale pentru sisteme legacy care nu suportă token-based auth, certificate TLS gestionate centralizat.
Variabilele de mediu în App Service sunt o soluție acceptabilă pentru un singur serviciu. Devin o problemă când ai mai multe:
- Același secret replicat în Application Settings pentru 5 App Service-uri — când îl rotești, trebuie să îl schimbi în 5 locuri
- Nu există audit trail — nu știi cine a citit sau modificat o variabilă de mediu
- Nu există versioning — nu poți reveni la o versiune anterioară a unui secret
- Nu există notificări la expirare — un certificat poate expira fără să știe nimeni
Azure Key Vault rezolvă toate acestea. E un serviciu managed dedicat exclusiv stocării și gestionării secretelor, cheilor criptografice și certificatelor — cu audit complet, versioning, politici de expirare și integrare nativă cu ecosistemul Azure.
Crearea unui Key Vault
# Creare Key Vault
az keyvault create \
--name my-app-keyvault \
--resource-group my-rg \
--location westeurope \
--sku standard \
--enable-rbac-authorization true # important: folosim RBAC, nu Access Policies
# Verifica ca RBAC e activat
az keyvault show \
--name my-app-keyvault \
--resource-group my-rg \
--query properties.enableRbacAuthorization
Parametrul --enable-rbac-authorization true e important. Key Vault suportă două modele de acces: Access Policies (modelul vechi) și RBAC (modelul recomandat). RBAC e consistent cu restul ecosistemului Azure, permite acces granular la nivel de secret individual și se integrează cu Azure Policy și Privileged Identity Management. Configurarea detaliată a rolurilor o acoperim în partea a treia.
Integrare cu IConfiguration prin AddAzureKeyVault
Cel mai simplu mod de a folosi Key Vault în ASP.NET Core este ca provider de configurare. Secretele devin accesibile prin IConfiguration, exact ca orice altă valoare din appsettings.
dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
dotnet add package Azure.Identity
// Program.cs
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsProduction())
{
var kvUri = builder.Configuration["KeyVaultUri"]
?? throw new InvalidOperationException("KeyVaultUri nu e configurat");
builder.Configuration.AddAzureKeyVault(
new Uri(kvUri),
new DefaultAzureCredential());
}
// Dupa aceasta linie, secretele din Key Vault sunt accesibile
// prin builder.Configuration["NumeSecret"]
// sau prin IOptions cu BindConfiguration
Convenția de naming în Key Vault: deoarece Key Vault nu acceptă caracterul : în numele secretelor, configurarea ierarhică folosește -- (double dash) ca separator. Astfel Stripe--ApiKey în Key Vault devine Stripe:ApiKey în ASP.NET Core.
# Adauga secrete in Key Vault
az keyvault secret set \
--vault-name my-app-keyvault \
--name "Stripe--ApiKey" \
--value "sk_live_..."
az keyvault secret set \
--vault-name my-app-keyvault \
--name "SendGrid--ApiKey" \
--value "SG.xxx..."
// Consum prin IOptions -- recomandat fata de citirea directa
public class StripeOptions
{
[Required]
public string ApiKey { get; set; } = default!;
}
builder.Services.AddOptions()
.BindConfiguration("Stripe")
.ValidateDataAnnotations()
.ValidateOnStart();
// In serviciu:
public class StripeService
{
private readonly StripeOptions _options;
public StripeService(IOptions options)
=> _options = options.Value;
}
Validarea la startup (ValidateOnStart) îți spune imediat la deploy dacă un secret lipsește din Key Vault, în loc să afli abia la primul request care îl folosește.
Prefix filtering — Key Vault-uri per mediu
Când ai mai multe medii (Development, Staging, Production) și vrei să stochezi secretele lor în același Key Vault, poți folosi prefix filtering. Secretele cu prefix Production-- sunt vizibile doar în mediul de Production:
# Secrete cu prefix per mediu
az keyvault secret set --vault-name my-app-keyvault \
--name "Production--Stripe--ApiKey" --value "sk_live_..."
az keyvault secret set --vault-name my-app-keyvault \
--name "Staging--Stripe--ApiKey" --value "sk_test_..."
// Custom manager pentru prefix filtering
public class EnvironmentPrefixKeyVaultManager : KeyVaultSecretManager
{
private readonly string _prefix;
public EnvironmentPrefixKeyVaultManager(string environment)
=> _prefix = $"{environment}--";
// Incarca doar secretele cu prefixul mediului curent
public override bool Load(SecretProperties secret)
=> secret.Name.StartsWith(_prefix, StringComparison.OrdinalIgnoreCase);
// Elimina prefixul din numele cheii de configurare
public override string GetKey(KeyVaultSecret secret)
=> secret.Name[_prefix.Length..]
.Replace("--", ConfigurationPath.KeyDelimiter);
}
// Utilizare in Program.cs
builder.Configuration.AddAzureKeyVault(
new Uri(kvUri),
new DefaultAzureCredential(),
new AzureKeyVaultConfigurationOptions
{
Manager = new EnvironmentPrefixKeyVaultManager(
builder.Environment.EnvironmentName)
});
Acum fiecare mediu vede doar secretele proprii, iar prefixul e eliminat automat din cheie — codul aplicației rămâne identic indiferent de mediu.
Ce urmează
În partea a doua vedem cum implementezi rotația automată a secretelor fără restart de aplicație (ReloadInterval, IOptionsSnapshot, IOptionsMonitor) și cum gestionezi certificate X.509 în Key Vault cu reînnoire automată.
În partea a treia acoperim accesul granular prin RBAC la nivel de secret individual, audit trail-ul complet și Key Vault References în App Service.
Întrebări? Scrie-mi la contact@ludoprogramming.com.