Securing Azure Key Vault Access: Eliminate Client Secrets with Managed Identity
Table of Contents
As Solution Architects, we’re responsible for defining cloud-native architectures that are secure, compliant, maintainable, and cost-effective.
A recurring security flaw I encounter in many Azure-based applications — even enterprise-grade ones — is the storage of Azure Key Vault client secrets in configuration files or pipelines. This practice, while common, violates security best practices and increases the surface area for compromise.
In this article, I’ll walk through the architectural reasoning behind replacing client secrets with Azure Managed Identity, demonstrate a practical implementation path, and show how this aligns with modern cloud security and governance models.
Problem: Secrets in Configs Are a Risk and a Liability
Storing secrets in configuration files (appsettings.json
, .env
, YAML files) may seem simple at first, but it introduces several risks:
Risk Landscape:
Source code exposure (e.g., secrets committed to Git)
Lack of rotation discipline (leading to long-lived secrets)
Credential sprawl (copied across environments and systems)
Violation of Zero Trust principles (over-trusting applications)
Real Case: A Fortune 500 org used client secrets across 20+ microservices. A leaked repo exposed three long-lived secrets, leading to external access to internal APIs — costing $150k+ in damage control and compliance remediation.
Solution: Use Azure Managed Identity (MI) for Key Vault Access
Azure Managed Identity is a fully managed identity platform that enables Azure resources to authenticate to supported services without any credentials in your code.
It leverages Azure AD behind the scenes to issue and manage tokens — just like how users authenticate to apps — but designed for services.
Why It’s Architecturally Sound:
- No secrets = no leaks
- Auth is handled by Azure AD, not by the developer
- Supports least-privilege access (RBAC or access policies)
- Uniform authentication model across services
Types of Managed Identity
Type | Description | Use Case |
---|---|---|
System-assigned | Tied to a single Azure resource | Good for isolated apps |
User-assigned | Standalone identity reusable by multiple resources | Good for shared auth across apps or environments |
Implementation Path
Step 1: Enable Managed Identity
For Azure App Service:
- Go to Azure Portal > App Service > Identity
- Enable System-assigned identity
- Save changes — Azure provisions an identity in Azure AD
✅ You now have a trusted identity your app can use to access Azure resources securely.
Step 2: Grant Access to Key Vault
You can choose either of the following depending on your governance model:
A. Access Policies (Classic)
- Go to Key Vault > Access policies
- Add your app’s managed identity
- Grant permissions like
Get
,List
,Set
on Secrets
B. Azure RBAC (Recommended for enterprise use)
- Go to Key Vault > IAM > Add role assignment
- Assign role: Key Vault Secrets User
- Assign to: App’s Managed Identity
- Scope: This resource (or resource group)
Step 3: Consume in Code (No Secret Needed)
With Azure SDKs, authentication becomes environment-aware:
var vaultUri = new Uri("https://your-vault.vault.azure.net/");
var client = new SecretClient(vaultUri, new DefaultAzureCredential());
var dbSecret = client.GetSecret("DbConnectionString");
Console.WriteLine($"Secret: {dbSecret.Value.Value}");
Why DefaultAzureCredential
?
- In development: uses your local Azure CLI login
- In Azure: uses the Managed Identity automatically
- No changes needed across environments
Enterprise Use Case: Secure API Backend with Managed Identity
Scenario:
A multi-region B2B SaaS platform hosted in Azure has APIs deployed on Azure App Service accessing:
- Key Vault for DB credentials
- Azure Storage for document processing
Before:
- Used
appsettings.json
with Azure AD client secrets - Secrets rotated manually every 90 days
- Risk of misconfigurations in CI/CD pipelines
After:
- App Services configured with System-assigned Managed Identity
- Key Vault access via RBAC
- Code refactored to use
DefaultAzureCredential
Outcomes:
- Zero secrets in source, config, or pipelines
- Centralized access governance via Azure AD
- Significantly reduced audit scope and risk exposure
What If Managed Identity Is Not an Option?
There may be cases where Managed Identity is not immediately viable — such as:
- Your app runs outside of Azure (e.g., on-prem, legacy hosting)
- You are using a third-party integration that cannot use Azure AD tokens
- You’re in a hybrid cloud model or containerized environment without direct MI support
In such scenarios, here’s how you can still follow secure design principles:
1. Use Azure AD Client Credentials Flow (with precautions)
If you must use a client ID + secret, ensure the following:
Secure Storage
- Store secrets in Azure Key Vault, not in code/config
- Use tools like Azure App Configuration to reference secrets at runtime
- For local development, use User Secrets (in .NET) or Environment Variables
Limit Exposure
- Grant minimal RBAC access for the app’s Azure AD app registration
- Rotate secrets frequently (automate if possible)
- Never expose secrets in logs or CI/CD output
2. Use Certificates Instead of Client Secrets
Instead of storing client secrets, consider using Azure AD certificate-based authentication:
- Create a certificate (self-signed or CA-issued)
- Upload the public key to Azure AD App Registration
- Store the private key in a secure location (e.g., Azure Key Vault or HSM)
Benefits:
- Certificates can have expiration policies and stronger protection
- Harder to brute-force or leak accidentally
Risk Mitigation:
- Enforce password protection and limited read access on certificate stores
- Use key vault references or automation tools like Azure DevOps Key Vault task
3. Use Encryption-at-Rest & In-Transit
Even if secrets must be stored
- Use Azure Storage encryption, Key Vault-backed disks, and TLS 1.2+
- For app configs, encrypt sensitive fields with AES-256, and manage keys via Key Vault
- Mask or hash values in logs or telemetry (especially for PII or credentials)
Key Takeaways
Never store secrets in configuration files – even for internal or dev environments. This introduces unnecessary security risk and audit overhead.
Azure Managed Identity should be the default authentication model for services running on Azure. It eliminates credentials, simplifies code, and aligns with Zero Trust principles.
DefaultAzureCredential simplifies multi-environment setups, making it easy to run the same code locally and in production – securely.
In cases where Managed Identity cannot be used, adopt secondary secure patterns like:
- Client certificates over client secrets
- Secrets stored in Azure Key Vault, not in code
- Environment-level encryption and access control
Least privilege access control (via RBAC or access policies) is essential when assigning Key Vault permissions – never use broad “owner” rights for apps.
Automate secret rotation and access audit logging to meet enterprise compliance and governance needs.
Architecture decisions must account for edge cases (e.g., hybrid, multi-cloud, 3rd party integrations) and should include risk mitigation strategies from day one.