Introduction
There are many ways to handle secrets in software development. I have previously blogged about local developer setup with direnv. This blog post expands on that by adjusting the .envrc file used for the local developer environment, where we reference Key Vault.
Check in the .envrc file
I worked with a developer on an application that needed local secrets to send out emails through a third-party API. We wanted a good developer experience with an easy local machine setup procedure. For one, we made the documentation a first-class citizen, clearly referencing documentation explaining the larger system, while keeping the repository-specific information in the README.md file.
We used direnv to load/unload secrets automatically, but kept the .envrc file out of git as it had secrets in clear text. I asked if the company had any preferences or policies on how to manage secrets in local development. I explained our current setup, and the CTO asked: why don´t we load the secrets from KeyVault with the .envrc file and add it to the repo? We changed the file and removed it from .gitignore to something like:
export SmsAPI__ClientId=$(az keyvault secret show --vault-name kv-local-xyzxyz --name smsapi-client-id --query value --output tsv)
export SmsAPI__ClientSecret=$(az keyvault secret show --vault-name kv-local-xyzxyz --name smsapi-client-secret --query value --output tsv)
The secrets are centralized in KeyVault and we can control versions and PIM policies for local development.
We updated our README.md with the basic Azure CLI command needed for local setup:
az login --tenant {tenant-id} --subscription {subdcription-id}
And added a link to the Azure resources PIM role to activate the KeyVault access.
In a perfect world
Ideally, we would set up an Azure App Configuration and create managed identities for our applications consuming the configuration. We could use selectors to load application-specific settings and environment-specific overrides. Additionally, we could assign the app-specific managed identities the Key Vault Secrets User role, scoped to the secrets they need.
Locally, we could utilize DefaultAzureCredential() in our .NET configuration setup and use an Entra ID Group for our team for access. However, we did not have access to create Azure Resources ourselves with Terraform, so we went with the simpler approach of retrieving secrets directly from Key Vault using Azure CLI.