Secure secrets using Azure KeyVault -Approach II

Secure secrets using Azure KeyVault

Today in this article we will see how to secure secrets using Azure KeyVault using a non-MSI approach.

Updated October 2026: an RBAC permissions section, guidance on protecting the client secret and local development, and an FAQ.

Today in this article, we will cover below aspects,

Here we will use configuration values for the below variables declaratively,

  • AZURE_CLIENT_ID,
  • AZURE_TENANT_ID,
  • AZURE_CLIENT_SECRET.

Let’s look into step by step how to get the above-used key vault URL and define secretes value for DbPassword.

Prerequisites

Before we get started with actual Azure Vault implementation please make sure you have the below prerequisites defined already in your Azure cloud account,

  • Create a Resource group( if not already exist )
  • Create an App Service plan
  • Create Azure WebApp (App Service) in the App service plan

For more details on the above steps, please visit this article – Secure secrets using Azure KeyVault MSI with examples

Please make sure to define variables AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_CLIENT_SECRET as Environment variables or as Application settings are defined with values.

Azure App Service Configuration page showing application settings AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID with hidden values.

Get Value for AZURE_CLIENT_ID , AZURE_TENANT_ID , AZURE_CLIENT_SECRET

Let’s now see how to get value for “AZURE_CLIENT_ID”, “AZURE_CLIENT_SECRET”, “AZURE_TENANT_ID” .

All these IDs (AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET ) are needed to authenticate/Identify the Application with Azure cloud.

To get the defined values please go to the Azure default directory and click on the Application object

Home -> Default Directory – > App registrations

Azure KeyVault java example

So above,

  • “AZURE_CLIENT_ID” is equal to Application(client) ID as defined in the above screenshot.

  • “AZURE_TENANT_ID” is equal to Directory(tenant) ID as defined in the above screenshot.

So so far we got the value “AZURE_CLIENT_ID” and “AZURE_TENANT_ID” using the above-highlighted credentials.

Next “AZURE_CLIENT_SECRET” can be generated for the application object using the below steps.

Please go to Azure Directory- > App registration -> Click on your Application

Next click on the Certificates and Secretes -> Click on New Client Secretes

Azure KeyVault node js example

private IActionResult GetClientScrets()
        {
            SecretClientOptions options = new SecretClientOptions()
            {
                Retry =
                {
                    Delay= TimeSpan.FromSeconds(2),
                    MaxDelay = TimeSpan.FromSeconds(16),
                    MaxRetries = 5,
                    Mode = RetryMode.Exponential
                }
            };

            string keyVaultUrl = _configuration["VaultURI"];
            var client = new SecretClient(vaultUri: new Uri(keyVaultUrl), credential: new DefaultAzureCredential(),options);
            KeyVaultSecret secret = client.GetSecret("YourSecreteCode");
            return Ok("Your Secrete is " + secret.Value);
        }

Let’s now execute the WebApp URL and verify the Vault secrets.

Browser window at thecodebuzzappserviceplan.azurewebsites.net displaying the text 'Your Secrete is -you are beautiful !'

Approach 2 – Authenticate the Application using MSI ( Managed Service Identity

We can bootstrap the authentication code within the ASP.NET API pipeline using managed service identity feature of the Azure cloud.

Managed Service Identity (MSI) is a technique to automatically manage the identity in Azure Active Directory(Azure AD). Key Vault service can be leveraged without having any token or credentials in your code which is generally needed as the first-time validation/authentication.

For more details please visit this article- Secure secrets using Azure KeyVault MSI with examples

Other references :



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published (2026) best practices and guidelines for software design and development.



Protect the client secret and run locally without it

The client secret is a credential, and it expires. Treat it like a password: keep it only in App Service application settings or environment variables, never in source control, and set a calendar reminder to rotate it before the expiry date.

How do you rotate an expiring client secret?

An expired secret is a common cause of authentication failures that appear suddenly with no code change. Rotate in this order so the app never has a gap:

  1. Create: add a new client secret to the app registration.
  2. Update: put the new value in the AZURE_CLIENT_SECRET setting and restart the app.
  3. Delete: remove the old secret once the app works with the new one.

Which credentials are stronger than a client secret?

A client secret is a shared string that anyone can copy. These options reduce that risk:

  • Certificate credential: harder to leak by accident, but you must manage certificate renewal.
  • Federated credentials or workload identity: no stored secret at all, but the host must be able to issue a trusted token.
  • Managed identity: Azure handles the credential for you, and it is the best choice when the host supports it.

The client secret is still reasonable for hosts outside Azure and for quick setups. Just keep its scope small and its lifetime short.

Should you use DefaultAzureCredential in production?

Use a narrower credential in production. DefaultAzureCredential is convenient, but it tries several credential types in sequence. Its environment credential is the one that reads AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_CLIENT_SECRET.

When something fails, you then have to work out which of those attempts mattered. A single specific credential, or a ChainedTokenCredential with only the types you expect, gives you a shorter and clearer error.

In plain English: A credential chain is like trying keys on a ring until one opens the door. A short ring is quicker to check when the door stays shut.

How do you run locally without a client secret?

Put AzureCliCredential in the chain and sign in with az login. Your own account then reads the vault, so no secret is saved on your machine. Your account needs permission on the vault.

For developer-only values, layer user secrets on top of the Key Vault configuration source. Add them after the vault so they override it locally.

What should you check when authentication still fails?

  • Reuse one client: SecretClient is thread-safe, so create one instance and share it instead of building a new one per request.
  • Tenant ID: confirm AZURE_TENANT_ID is the directory that owns the app registration.
  • Vault firewall: check the vault’s networking settings allow calls from your app’s network.

Frequently asked questions

Which RBAC role does an app need to read Azure Key Vault secrets?

Assign Key Vault Secrets User to the app’s service principal. It gives read-only access to secret values. If the app loads secrets through the AddAzureKeyVault configuration provider, also assign Key Vault Reader so the provider can list the secrets. Reader alone can’t read values, because it only sees metadata. Scope the role to the whole vault, or to a single secret if you want tighter control.

Why do I get 403 Forbidden from Key Vault right after granting access?

Role assignments can take several minutes to propagate, so wait a few minutes and retry first. If the 403 persists, check these:

  • Access model: the vault must use RBAC rather than access policies, or your role assignment is ignored.
  • Principal: the role must be assigned to the right service principal, the one behind your AZURE_CLIENT_ID.
  • Tenant: AZURE_TENANT_ID must be the correct directory.
  • Client secret: it must not have expired.
  • Firewall: the vault’s network rules must allow the caller.

How do I name nested settings like Db:Password in Key Vault?

Use a double dash in the secret name. Key Vault secret names can’t contain colons, so you create a secret called Db--Password. When the Key Vault configuration provider loads it, the name maps to the configuration key Db:Password, and your existing IConfiguration code works unchanged.

Does the app pick up Key Vault secret changes without a restart?

Not by default. The configuration provider’s ReloadInterval option defaults to null, so secrets are loaded once at startup. Set ReloadInterval to a TimeSpan and the provider polls the vault for changes. If you call SecretClient directly, as in the example above, it reads the current value on every call, so decide deliberately how long to cache it. Create one SecretClient and reuse it rather than building a new one per request.

Leave a Reply

Your email address will not be published. Required fields are marked *