Azure Key Vault Plugin
Our Azure Key Vault plugin enables secure loading of secrets from Azure Key Vault using declarative instructions within your .env files.
The plugin automatically integrates with Azure authentication, including Managed Identity for Azure-hosted applications, Azure CLI credentials for local development, and service principal credentials for non-Azure environments.
Features
Section titled “Features”- Zero-config authentication - Just provide your vault URL, authentication happens automatically
- Managed Identity support - No credentials needed for Azure-hosted apps (App Service, Container Instances, VMs, Functions, AKS)
- Azure CLI authentication - Works seamlessly with
az loginfor local development - Auto-infer secret names from environment variable names (e.g.,
DATABASE_URL→database-url) - Support for service principal credentials (for non-Azure environments)
- Support for versioned secrets
- Automatic token caching and renewal
- Lightweight implementation using REST API (47 KB bundle, no heavy Azure SDK dependencies)
Installation and setup
Section titled “Installation and setup”In a JS/TS project, you may install the @varlock/azure-key-vault-plugin package as a normal dependency.
Otherwise you can just load it directly from your .env.schema file, as long as you add a version specifier.
See the plugins guide for more instructions on installing plugins.
# 1. Load the plugin# @plugin(@varlock/azure-key-vault-plugin)## 2. Initialize the plugin - see below for more details on options# @initAzure(vaultUrl="https://my-vault.vault.azure.net/")# ---Authentication options
Section titled “Authentication options”The plugin tries authentication methods in this priority order:
- Service Principal - If all three credentials (
tenantId,clientId,clientSecret) are provided - Managed Identity - Automatically used when running on Azure infrastructure
- Azure CLI - Falls back to
az loginfor local development
Automatic authentication (Recommended)
Section titled “Automatic authentication (Recommended)”For most use cases, you only need to provide the vault URL:
# @plugin(@varlock/azure-key-vault-plugin)# @initAzure(vaultUrl="https://my-vault.vault.azure.net/")# ---How this works:
- Local development: Run
az login→ automatically uses Azure CLI credentials - Azure-hosted apps (App Service, Container Instances, VMs, Functions, AKS): Enable Managed Identity → automatically authenticates (no secrets needed!)
- Works everywhere with zero configuration beyond the vault URL!
Service principal credentials (For non-Azure environments)
Section titled “Service principal credentials (For non-Azure environments)”If you’re deploying outside of Azure (e.g., AWS, GCP, on-premises), wire up service principal credentials:
-
Create a service principal with the necessary permissions (see Azure Setup section below)
-
Wire up the credentials in your config. Add config items for the tenant ID, client ID, and client secret, and reference them when initializing the plugin.
.env.schema # @plugin(@varlock/azure-key-vault-plugin)# @initAzure(# vaultUrl="https://my-vault.vault.azure.net/",# tenantId=$AZURE_TENANT_ID,# clientId=$AZURE_CLIENT_ID,# clientSecret=$AZURE_CLIENT_SECRET# )# ---# @type=azureTenantId @sensitiveAZURE_TENANT_ID=# @type=azureClientId @sensitiveAZURE_CLIENT_ID=# @type=azureClientSecret @sensitiveAZURE_CLIENT_SECRET= -
Set your credentials in deployed environments. Use your platform’s env var management UI to securely inject these values.
Multiple vaults
Section titled “Multiple vaults”If you need to connect to multiple vaults, but never at the same time, you can alter the vault URL using a function:
# @plugin(@varlock/azure-key-vault-plugin)# @initAzure(vaultUrl="https://my-vault-${ENV}.vault.azure.net/")# ---Or if you need to connect to multiple vaults simultaneously, register multiple named instances:
# @initAzure(id=prod, vaultUrl="https://my-vault-prod.vault.azure.net/")# @initAzure(id=dev, vaultUrl="https://my-vault-dev.vault.azure.net/")# ---
PROD_SECRET=azureSecret(prod, "database-url")DEV_SECRET=azureSecret(dev, "database-url")Loading secrets
Section titled “Loading secrets”Once the plugin is installed and initialized, you can start adding config items that load values using the azureSecret() resolver function.
Basic usage
Section titled “Basic usage”The azureSecret() function fetches secrets from Azure Key Vault.
# Auto-infer secret names (DATABASE_URL -> "database-url")DATABASE_URL=azureSecret()API_KEY=azureSecret()
# Explicit secret namesCUSTOM_SECRET=azureSecret("my-custom-secret-name")Versioned secrets
Section titled “Versioned secrets”You can fetch specific versions of secrets by appending @version to the secret name:
# Fetch latest version (default)API_KEY=azureSecret("api-key")
# Fetch specific versionAPI_KEY_V1=azureSecret("api-key@abc123def456")Azure Setup
Section titled “Azure Setup”Required permissions
Section titled “Required permissions”Your managed identity, service principal, or user needs one of:
- Access Policy: “Get” permission for secrets
- RBAC: “Key Vault Secrets User” role
Managed Identity for Azure-hosted apps (Recommended)
Section titled “Managed Identity for Azure-hosted apps (Recommended)”Managed Identity is the Azure-native way to authenticate - no credentials needed!
-
Enable system-assigned managed identity for your Azure resource
Terminal window # For App Serviceaz webapp identity assign --name my-app --resource-group my-rg# For Container Instanceaz container create --assign-identity --name my-container ...# For VMaz vm identity assign --name my-vm --resource-group my-rg -
Grant Key Vault access to the identity
Get the identity’s principal ID:
Terminal window PRINCIPAL_ID=$(az webapp identity show --name my-app --resource-group my-rg --query principalId -o tsv)Then grant access using either RBAC or Access Policy:
Option A: RBAC (Recommended)
Terminal window az role assignment create \--role "Key Vault Secrets User" \--assignee $PRINCIPAL_ID \--scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault-name>Option B: Access Policy
Terminal window az keyvault set-policy \--name my-vault \--object-id $PRINCIPAL_ID \--secret-permissions get -
That’s it! Your app will automatically authenticate using Managed Identity.
Service principal for non-Azure environments
Section titled “Service principal for non-Azure environments”-
Create a service principal
Terminal window az ad sp create-for-rbac --name "varlock-keyvault-reader"Save the
appId,password, andtenantfrom the output. -
Grant Key Vault access
Option A: RBAC (Recommended)
Terminal window az role assignment create \--role "Key Vault Secrets User" \--assignee <appId> \--scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault-name>Option B: Access Policy
Terminal window az keyvault set-policy \--name my-vault \--spn <appId> \--secret-permissions get
Azure CLI for local development
Section titled “Azure CLI for local development”-
Install the Azure CLI if you haven’t already: Installation guide
-
Log in to Azure
Terminal window az login -
Verify your identity
Terminal window az account show -
Grant Key Vault access to your user account (if needed)
Terminal window az keyvault set-policy \--name my-vault \--upn your-email@domain.com \--secret-permissions get
Reference
Section titled “Reference”Root decorators
Section titled “Root decorators”@initAzure()
Section titled “@initAzure()”Initialize an Azure Key Vault plugin instance for accessing secrets.
Key/value args:
vaultUrl(required): Azure Key Vault URL (e.g.,https://my-vault.vault.azure.net/)tenantId(optional): Azure AD tenant ID (directory ID)clientId(optional): Service principal application (client) IDclientSecret(optional): Service principal client secret (password)id(optional): Instance identifier for multiple vaults
# @initAzure(vaultUrl="https://my-vault.vault.azure.net/")# ---Data types
Section titled “Data types”azureTenantId
Section titled “azureTenantId”Represents an Azure AD tenant ID (UUID format). This type is marked as @sensitive.
# @type=azureTenantIdAZURE_TENANT_ID=azureClientId
Section titled “azureClientId”Represents a service principal application (client) ID (UUID format). This type is marked as @sensitive.
# @type=azureClientIdAZURE_CLIENT_ID=azureClientSecret
Section titled “azureClientSecret”Represents a service principal client secret (password). This type is marked as @sensitive.
# @type=azureClientSecretAZURE_CLIENT_SECRET=Resolver functions
Section titled “Resolver functions”azureSecret()
Section titled “azureSecret()”Fetch a secret from Azure Key Vault.
Array args:
instanceId(optional): instance identifier to use when multiple plugin instances are initializedsecretName(optional): secret name or name with version using@syntax. If omitted, uses the variable name (converted to kebab-case).
# Auto-infer secret name (DATABASE_URL -> "database-url")DATABASE_URL=azureSecret()
# Explicit secret nameCUSTOM_SECRET=azureSecret("my-custom-secret")
# Specific versionAPI_KEY_V1=azureSecret("api-key@abc123def456")
# With instance IDPROD_SECRET=azureSecret(prod, "database-url")Troubleshooting
Section titled “Troubleshooting”Secret not found
Section titled “Secret not found”- Verify the secret exists:
az keyvault secret list --vault-name my-vault - Remember: Azure uses hyphens, not underscores (use
database-urlnotdatabase_url) - Check for typos in the secret name
Permission denied
Section titled “Permission denied”- Check your RBAC role:
az role assignment list --assignee <your-id> --scope <vault-scope> - Or check access policies:
az keyvault show --name my-vault --query properties.accessPolicies - Ensure your identity has “Get” permission for secrets
Authentication failed
Section titled “Authentication failed”- Local dev: Run
az loginand ensure service principal env vars are empty - Azure-hosted apps: Verify Managed Identity is enabled and has Key Vault permissions
- Other environments: Verify service principal credentials are correct and properly injected
- Test identity:
az account show
Vault not accessible
Section titled “Vault not accessible”- Verify the vault URL is correct
- Check network access: Ensure firewall rules allow access from your IP/resource
- Verify the vault exists in the specified subscription