How DefaultAzureCredential Simplifies and Secures Azure Key Vault for .NET Developers
As widely recognized, inserting sensitive information directly into an application will exposes it to security vulnerabilities. To address this we are adopting a Azure keyvault approach. This approach not only enhances security but also ensures the safeguarding of confidential data.
Let’s consider a common scenario, such as including the connection string for an database in a WebAPI. Imagine if we were to hardcode the connection string directly into our WebAPI application and then deploy it to a production environment. It’s like handing over a shiny red button labeled “Data Kill” to developers those who are having access to code. Because they could possibly play with the data like a kid in the candy store.
To escape from such horrors, we have a lifesaver in the form of cloud services like Azure Key Vault. This gem lets us tuck away our connection strings and other sensitive information with utmost security. Thanks to this, we can achieve credential-less development, where our secrets remain hidden and our worries take a well-deserved vacation. Alright, Now we’re all know about the importance of securing sensitive info and keeping it away from prying eyes.
But here’s the awesome part— how does our app manage to grab this connection string from Azure Key Vault, instead of just writing it directly into the application’s code?
Let’s dig into the details of how this secret-sharing dance really happens. So, our precious connection string is chilling in the key vault, out of harm’s way. Well, imagine our application as a savvy secret agent, equipped with a top-notch communicator. This communicator knows how to discreetly ask the key vault for the connection string, without revealing the string itself. It’s like our app is sending a coded message saying, “Hey, key vault, can you pass me that secret recipe?”.
Now, This communicator relies on two key tools. First, it’s got a Treasure map that helps it locate the Azure Key Vault. Second, it uses a specially coded message, like “Open Sesame,” to unlock the gate to the Azure AD and access the token to allow it to go inside that treasure cave. With these two tools in hand, our communicator makes contact with the Azure Key Vault. Just like a guard at a secure gate, the Key Vault checks if our communicator is part of the trusted team or just a clever imposter. Once it’s certain our communicator is the real deal, the Key Vault graciously hands over the secret recipe. Our communicator then passes this valuable loot to our top-secret agent for actual use.
In terms of a programming language context, here communicator is a SecretClient class object, which relies on two instances of objects: a URI object for locating the Azure Key Vault and a DefaultAzureCredentials class object for authentication and access.
var secretClient = new SecretClient(new Uri("Keyvault url"),
new DefaultAzureCredential());
In this process, the SecretClient class uses the URI object to find the Key Vault service. Then, the DefaultAzureCredentials class obtains a token by checking credentials against the Key Vault’s access policies. If valid credentials are found, the SecretClient can access all stored secrets, allowing the application to retrieve the necessary database connection string. with this process, we can finally connect with the database and deploy it to production and achieve credentialless development like below.
How does the DefaultAzureCredential class make things easier for developers?
Before the introduction of the ‘DefaultAzureCredential’ class, developers typically had to use explicit credential management when working with Azure services. This means that developers had to manually create and manage the various types of credentials required for authenticating with Azure services to acheive credentialless development These explicit credential management tasks often required the use of different class objects, such as:
- EnvironmentCredential
- ManagedIdentityCredential
- VisualStudioCredential
- VisualStudioCodeCredential
- AzureCliCredential
- AzurePowerShellCredential
- AzureDeveloperCliCredential
Let’s focus on one explicit credential from the list I provided. imagine a simple ASP.NET Core web API application with basic CRUD operations. I have created an Azure App Service and deployed the application to it using CI/CD or another suitable approach. Additionally, I have implemented a Managed Identity credential to retrieve the connection string from Azure Key Vault. When I run the application through the App Service’s URL, it works correctly because I have granted access to the App Service in Azure Key Vault’s access policies. However, when I attempt to run the application locally, it throws an exception.
Because when your application runs in Azure, it can utilize the IMDS (Azure Instance Metadata Service) endpoint to obtain an identity token that allows it to authenticate with Azure services like Azure Key Vault.
http://169.254.169.254/metadata/identity/oauth2/token
When running your application locally, you must provide the connection string explicitly. This is necessary because the IMDS endpoint, which uses the private IP address 169.254.169.254, is designed to allow Azure virtual machines and managed identities to obtain token for authenticating with Azure service. However, it is a private endpoint that is not intended to be directly accessible from outside the Azure environment. Therefore, when you check it from a local command prompt, you will receive a “Destination host unreachable” response.
Similar to other credential class objects like EnvironmentVariableCredential and Visual Studio Credential, these credentials may function correctly on local machines but fail when deployed to a production environment. Therefore, using explicit credential classes can not only be time-consuming for developers but can also introduce challenges related to flexibility, code complexity, and security risks for the application.
To overcome these drawbacks, the DefaultAzureCredential class was introduced in 2020 to simplify the developers experience.
The DefaultAzureCredential class offers a significant advantage known as “Credential Auto-discovery.” It can automatically discover and use various types of Azure credentials based on the developer’s environment, such as environment variables, managed identity, or Visual Studio Code extensions. So developers don’t need to explicitly specify which credential to use. the library handles it based on the available options.
So this is how the DefaultAzureCredential class, simplifies Azure service authentication, making life easier for developers.
. . . . .
“ Thank you for reading! I hope this blog is helpful in your journey, and I look forward to sharing more insights with you in the future.”
Did you like this post? Then I would appreciate you buying me a coffee.