Secure Secrets with Key Vault
Secure secrets with Key Vault in this Azure tutorial step. Learn the core concept, apply it hands-on, and get ready for the next lesson.
Focus: secure secrets with key vault
You've built the infrastructure, wired up the database, and deployed your app — but your connection strings, API keys, and certificates are probably still sitting in plain text in a config file or, worse, committed to your repository. That's a security bomb waiting to explode. In this lesson, you'll learn how to secure secrets with Key Vault, Azure's dedicated service for storing and managing sensitive information, and why it's a non-negotiable part of any production-grade Azure deployment.
The problem this lesson solves
Secrets are the keys to your kingdom — database passwords, storage account keys, service principal credentials, and TLS certificates. When they leak, attackers can read your data, impersonate your services, and rack up huge bills on your dime.
The typical bad practices that lead to leaks: - Hardcoding secrets in application code — then accidentally pushing them to GitHub. - Storing secrets in environment variables — visible to anyone with access to the host VM. - Using the same secret across multiple environments — so a dev leak becomes a production breach. - Rotating secrets manually — a time-consuming chore that often gets skipped.
Azure Key Vault solves these problems by providing a centralized, hardware-backed store for secrets, keys, and certificates, with fine-grained access control and built-in audit logging. Instead of embedding secrets in your app, you reference them at runtime — and Azure handles the rest.
Core concept / mental model
Think of Key Vault as a high-security safe deposit box at a bank. You (your application) get a key to the safe, but the bank (Azure) controls who can open which box and keeps a log of every visit. The box itself is triple-locked — secured by hardware security modules (HSMs) that are FIPS 140-2 Level 2 validated.
Key Vault is not just a password manager for your org; it's a runtime service that your application can query programmatically. Here are the core components:
- Vault: A logical container that holds secrets, keys, and certificates. Each vault has its own access policy and audit log.
- Secret: An opaque string, like a password or connection string. Stored encrypted at rest and in transit.
- Key: A cryptographic key (RSA, EC, or symmetric) used for encryption and signing. Can be backed by HSM.
- Certificate: An X.509 certificate that can be auto-renewed and deployed to resources like App Service.
- Access policy: A set of permissions (get, list, set, delete, etc.) granted to a security principal (user, group, or service principal).
- Managed identity: An Azure-assigned identity for your app that lets it authenticate to Key Vault without any credentials in code.
Pro tip: Always use a managed identity to access Key Vault from your Azure-hosted app. It's the most secure and the easiest to manage — no keys to store, no rotation to worry about.
How it works step by step
Securing secrets with Key Vault follows a consistent pattern across Azure services. Here's the high-level flow:
- Create a Key Vault — A single vault can hold many secrets; you don't need one per app, but you might want separate vaults for dev, staging, and production.
- Store your secrets — Add a database password, storage key, or certificate as a secret in the vault. You can do this via the Azure portal, Azure CLI, PowerShell, or ARM/Bicep templates.
- Grant access — Assign an access policy to the application's identity (user, group, or managed identity) with least-privilege permissions (e.g.,
getonly). - Reference the secret in your app — Use the Azure SDK (Python, .NET, etc.) to fetch the secret at runtime, or use service-specific integrations (e.g., App Service Key Vault references) that inject the secret into your app config.
- Rotate and retire — When a secret is compromised or due for rotation, update it in the vault. Applications that fetch secrets at runtime pick up the change automatically.
Why this matters: Because your app fetches secrets at runtime, you never hardcode anything. If a secret leaks, you can revoke it immediately in the vault and rotate it — no code redeploy required.
Hands-on walkthrough
Let's get practical. In this exercise, you'll create a Key Vault, store a secret, and retrieve it using the Azure SDK for Python. Make sure you have the Azure CLI and Python 3.10+ installed.
1. Create a Key Vault
First, log in and set your subscription:
az login
az account set --subscription "your-subscription-id"
Create a resource group (if you don't have one) and a Key Vault. The vault name must be globally unique:
az group create --name rg-keyvault-demo --location eastus
az keyvault create --name myvault-$RANDOM --resource-group rg-keyvault-demo --location eastus
Note the vault name from the output — you'll need it later.
2. Store a secret
Add a database connection string as a secret:
az keyvault secret set --vault-name <your-vault-name> --name "db-connection-string" --value "Server=tcp:myserver.database.windows.net;Database=mydb;User ID=admin;Password=Secret123!;Encrypt=True;"
3. Retrieve the secret with Python
Install the Azure SDK and create a Python script to fetch the secret:
pip install azure-identity azure-keyvault-secrets
Create get_secret.py:
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
vault_url = "https://<your-vault-name>.vault.azure.net"
credential = DefaultAzureCredential()
client = SecretClient(vault_url=vault_url, credential=credential)
retrieved_secret = client.get_secret("db-connection-string")
print(f"Secret value: {retrieved_secret.value}")
Run it with your Azure CLI credentials:
az login # ensure you are logged in
python get_secret.py
Expected output:
Secret value: Server=tcp:myserver.database.windows.net;Database=mydb;User ID=admin;Password=Secret123!;Encrypt=True;
4. Grant access to a managed identity
In production, you won't use your personal login. Instead, assign a managed identity to your app (e.g., an App Service or VM) and grant it get permission:
# Assign a system-assigned identity to an App Service (example)
az webapp identity assign --name my-app --resource-group rg-keyvault-demo
az keyvault set-policy --name <your-vault-name> \
--object-id <principal-id-from-previous-command> \
--secret-permissions get list
The app can then authenticate with DefaultAzureCredential without any secrets in code.
Pro tip: Use the secret versioning feature — each update to a secret creates a new version. Your app can specify a version to pin, or always use the latest.
Compare options / when to choose what
Securing secrets can be done in several ways. Here's how Key Vault stacks up against the alternatives:
| Approach | Security | Ease of management | Rotation | Auditability | Best for |
|---|---|---|---|---|---|
| Environment variables | Low — visible on the host | Manual | Manual | None | Quick local dev, non-sensitive config |
| Config files (appsettings.json) | Low — often committed to git | Manual | Manual | None | Prototyping only |
| Azure Key Vault | High — hardware-backed, encrypted | Centralized | Built-in, automated | Full audit log | Production apps, regulated workloads |
| Third-party vaults (HashiCorp Vault) | High | Centralized but extra tooling | Built-in | Yes | Multi-cloud or on-prem hybrid environments |
When to choose Key Vault: You're building on Azure and need a fully managed solution with native integration to App Service, Functions, and AKS. Choose third-party vaults if you need a single vault across on-prem and multiple clouds.
Cost consideration: Key Vault has a free tier for up to 10,000 operations per month — plenty for most dev and small prod workloads. Standard tier adds HSM-backed keys.
Troubleshooting & edge cases
Here are common issues you'll hit and how to fix them:
- 403 Forbidden when retrieving a secret — Your identity (or managed identity) doesn't have
getpermission on the vault. Check the access policy and the--object-idyou used. Useaz keyvault show --name <vault> --query properties.accessPoliciesto verify. - The user, group or application '...' does not have secrets get permission — This is the Azure CLI's way of saying the same thing: no access policy. Re-run
az keyvault set-policywith the correct principal ID. - DefaultAzureCredential fails silently in local dev — If you're running outside Azure,
DefaultAzureCredentialtries multiple authentication sources. Make sure you're logged in withaz loginand that theAZURE_CLIENT_ID,AZURE_TENANT_ID, andAZURE_CLIENT_SECRETenvironment variables are not set to invalid values if you're using them. - Secret value is
None— You might be retrieving a secret version that was deleted or never set. List versions withaz keyvault secret list-versions. - The vault name is already in use — Names are globally unique. Append a random suffix or use a different name.
- Soft-delete and purge protection — Vaults now have soft-delete enabled by default. If you delete a secret, it stays in a recoverable state for 90 days. You can recover it with
az keyvault secret recover. If you need to purge, set--enable-purge-protection truewhen creating the vault. - Secret expiration not triggering — You must set an expiration date explicitly. Key Vault doesn't auto-rotate secrets; use lifecycle policies or your own automation.
Edge case: If your app needs to connect to a database in a different region, make sure the vault and the app are in the same region or use a paired region for low latency — there's a small performance cost to cross-region calls.
What you learned & what's next
You now understand why secure secrets with Key Vault is essential: it protects against hardcoded credentials, centralizes secret management, and gives you auditability and fine-grained access control. You've created a vault, stored a secret, retrieved it with Python, and granted access to a managed identity. You've also learned when to choose Key Vault over alternatives like environment variables or third-party vaults.
These skills are the foundation for the next step in your Azure journey: connecting your app to Azure resources (like a Postgres Flexible Server) while keeping credentials out of your code. With Key Vault, you can deploy with confidence, knowing your secrets are safe and easily rotatable.
Practice tip: Create a second secret, update it, and see how the version changes. Then try setting an expiration date and observe how the retrieve behavior works after the expiry.
Practice recap
For a quick hands-on check, create a second secret with an expiration date set to tomorrow (use az keyvault secret set --expires). Then write a Python script that tries to get that secret and see what error you get. Next, grant access to another user (or a group) with only get permission and test the access control by trying to list secrets with that user — you should see a 403 error.
Common mistakes
- Hardcoding vault URL or secret names in your app source code — treat the vault endpoint as config, not a secret, but still store it in app settings, not code.
- Using your personal login credentials in production instead of a managed identity — this breaks if you change jobs and creates a security risk.
- Granting broad permissions (all secrets, all operations) instead of least privilege — a compromised app can then leak or delete all secrets.
- Storing the secret value in a log or error message when retrieving it from Key Vault — logs are often less secure than the vault itself.
- Forgetting to enable soft-delete and purge protection — you can't recover accidentally deleted secrets or protect against malicious deletion.
Variations
- Use Bicep or ARM templates to define your Key Vault and secrets as code, enabling repeatable deployments and better version control.
- Use Key Vault references in App Service or Azure Functions — add
@Microsoft.KeyVault(SecretUri=...)in your app settings to inject secrets without code changes. - For non-Azure apps, use the Key Vault REST API or SDK to retrieve secrets, but you'll need to manage client credentials securely (e.g., a service principal with a certificate).
Real-world use cases
- A web app on App Service connecting to Azure SQL Database — store the connection string in Key Vault and reference it via a service principal.
- A CI/CD pipeline in Azure DevOps that needs a service principal password to deploy — store the password as a Key Vault secret and reference it in the pipeline.
- An application that uses TLS certificates from a public CA — store the certificate in Key Vault and have App Service auto-rotate it before expiry.
Key takeaways
- Azure Key Vault is a centralized, hardware-backed vault for secrets, keys, and certificates with fine-grained access control and audit logging.
- Never hardcode secrets in code or config — always reference them from Key Vault at runtime.
- Use managed identities to authenticate to Key Vault from your Azure-hosted apps — no secrets in code needed.
- Access policies should follow the least-privilege principle; grant only the permissions your app needs.
- Key Vault supports versioning and soft-delete, enabling easy rotation and recovery of secrets.
- Compare Key Vault with environment variables or third-party vaults to choose the right approach for your workload.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.