Search code examples
azure.net-coreazure-keyvault

Can't access keyvault from backend appservice


I'm using Azure key vault to hold some sensitive data. i've given in access policy all permissions and the same for the dev app service that holds the dev backend. it works just fine locally and it access the data successfully. the problem when i pushed the update to the dev backend and tried it, the service was down and the whole backend was not working. i had to revert the changes but any idea what am i missing here? My application is hosted on Azure (app service) and the managed identity is activated. here is the backend configuration: in appSetting.json : "your-key-vault-name":"SanedDevKeyVault",

in program.cs : var keyVaultName = builder.Configuration["your-key-vault-name"]; var kvUri = $"https://{keyVaultName}.vault.azure.net"; builder.Configuration.AddAzureKeyVault(new Uri(kvUri), new DefaultAzureCredential());. from azure side : i gave app service for the backend the access polic it needs : access policy

and i added the environment variable in the app service "your-key-vault-name":"SanedDevKeyVault", . it's working locally but not working when i try to run the application hosted on azure after adding those changes.


Solution

  • To access data from Key Vault you need to use specific client of the Key, Secret, Certificate.

    Below given code worked for me.

    I have created a Secret and fetching its value using controller in API

    Controllers/Keyvault.cs:

    using Azure.Security.KeyVault.Secrets;
    using Microsoft.AspNetCore.Mvc;
    
    namespace Dotnet_API.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class KeyVault: ControllerBase
        {
            private readonly ILogger<KeyVault> _logger;
            private readonly  SecretClient _secretClient;
    
            public KeyVault(ILogger<KeyVault> logger, SecretClient secretClient)
            {
                _logger = logger;
                _secretClient = secretClient;
            }
    
            [HttpGet]
            public async Task<IActionResult> GetSecret()
            {
                var secretName = "confidential";
                try
                {
                    KeyVaultSecret secret = await _secretClient.GetSecretAsync(secretName);
                    return Ok(new { SecretValue = secret.Value });
                }
                catch (Exception ex)
                {
                    return StatusCode(StatusCodes.Status500InternalServerError, new { Message = ex.Message });
                }
            }
        }
    }
    

    Program.cs:

    using Azure.Identity;
    using Azure.Security.KeyVault.Secrets;
    using Microsoft.Extensions.DependencyInjection;
    
    var builder = WebApplication.CreateBuilder(args);
    
    
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    builder.Services.AddControllers();
    
    var KeyVaultUrl = builder.Configuration["KeyVault:Url"];
    var secret = builder.Services.AddSingleton(new SecretClient(new Uri(KeyVaultUrl), new DefaultAzureCredential()));
    
    var app = builder.Build();
    
    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    
    app.UseHttpsRedirection();
    app.MapControllers();
    app.Run();
    

    appsettings.json:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "KeyVault": {
        "Url": "https://vivekkeyvault.vault.azure.net"
      }
    }
    

    To allow web app access in Key vault follow the steps:

    • Enable System assigned identity / Add User assigned identity

    • Create access policy in key vault and assign the required access

    My secrete value :

    OUTPUT:

    Locally :

    with swagger

    without swagger

    Azure :