
September 09, 2026
12 min read
By Kokil Thapa | Last reviewed: September 2026
Hard-coded passwords in pipeline YAML are a breach waiting to happen. To use Azure Key Vault secrets in pipelines, you store credentials in a vault and let CI/CD fetch them at runtime through managed identity or a service connection. That pattern keeps secrets out of Git, audit logs, and pull-request diffs. If you already understand vault objects, start with our Azure Key Vault keys, secrets, and certificates overview; this guide focuses on wiring those secrets into Azure Pipelines and similar workflows.
How do you use Azure Key Vault secrets in Azure Pipelines?
Azure DevOps can pull secrets from Key Vault in two main ways. Variable groups sync vault secrets into named pipeline variables. The AzureKeyVault task downloads secrets into the job environment for that run only. Both approaches beat pasting values into library variables or YAML files.
On production Laravel deployments I maintain, database URLs and API keys live in vaults. The pipeline reads them during deploy. Local developers use .env files. Production never echoes those values in build logs when masking is configured correctly.
Step 1: Create secrets in the vault
Store each credential as a named secret. Use kebab-case names like prod-db-password or stripe-secret-key. One secret per value makes rotation and auditing simpler than bundling JSON blobs unless your app expects structured config.
az keyvault secret set \
--vault-name "myapp-prod-kv" \
--name "prod-db-password" \
--value "your-strong-password-here" Microsoft documents vault creation and secret management in the Azure Key Vault secrets quickstart. Enable soft delete and purge protection on production vaults. Accidental deletion without recovery is painful during a Friday deploy.
Step 2: Link the vault to a variable group
In Azure DevOps, open Pipelines → Library → + Variable group. Toggle Link secrets from an Azure key vault as variables. Pick your subscription and vault. Select the secrets you need. Azure DevOps maps each secret name to an identically named variable.
- Create the variable group and link the vault.
- Grant the pipeline access when prompted, or configure RBAC manually.
- Reference the group in YAML with
- group: my-prod-secrets. - Use variables as
$(prod-db-password)in tasks and scripts.
Step 3: Use the AzureKeyVault task in YAML
The task approach suits jobs that need fresh secrets each run without syncing a library group. Add it as the first step in a deployment job.
steps:
- task: AzureKeyVault@2
inputs:
azureSubscription: 'my-azure-service-connection'
KeyVaultName: 'myapp-prod-kv'
SecretsFilter: 'prod-db-password,stripe-secret-key'
RunAsPreJob: true
- script: |
php artisan migrate --force
env:
DB_PASSWORD: $(prod-db-password) For broader pipeline design patterns, see our Azure DevOps YAML pipelines practical guide and build your first Azure Pipelines CI/CD pipeline walkthrough.
What permissions does a pipeline need to read Key Vault secrets?
Key Vault access works through Azure RBAC or the legacy access policy model. RBAC is the current default for new vaults. Assign the pipeline identity the Key Vault Secrets User role at vault scope. That role allows get and list on secrets without granting key or certificate permissions.
Two identity options exist. A user-assigned managed identity on a self-hosted agent is clean for long-running infrastructure. Azure DevOps service connections use a service principal or workload identity federation. Both need the same RBAC role on the vault resource.
Assign RBAC with Azure CLI
PRINCIPAL_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
VAULT_ID=$(az keyvault show --name myapp-prod-kv --query id -o tsv)
az role assignment create \
--role "Key Vault Secrets User" \
--assignee-object-id "$PRINCIPAL_ID" \
--assignee-principal-type ServicePrincipal \
--scope "$VAULT_ID" Wait a few minutes after role assignment. Azure RBAC propagation is not instant. A common failure is a 403 on the first pipeline run right after setup. Re-run the job before debugging YAML.
If your vault still uses access policies, add get and list for secrets to the pipeline identity. New projects should migrate to RBAC. The Azure Key Vault overview explains permission models and migration paths.
Self-hosted agents need their own identity configuration. Our self-hosted Azure DevOps agents guide covers network and identity setup for agents outside Microsoft-hosted pools.
How do you reference Key Vault secrets in YAML without leaking them?
Secret variables behave differently from normal variables in Azure Pipelines. They are masked in logs. They are not passed to downstream tasks as plain environment variables unless you map them explicitly. Never print secret variables in scripts, even for debugging.
Variable group reference in multi-stage pipelines
variables:
- group: my-prod-secrets
- name: APP_ENV
value: production
stages:
- stage: Deploy
jobs:
- deployment: DeployWeb
environment: production
strategy:
runOnce:
deploy:
steps:
- script: echo "Deploying with vault-backed config"
- task: AzureWebApp@1
inputs:
azureSubscription: 'my-azure-service-connection'
appName: 'myapp-prod'
appSettings: |
-DB_PASSWORD $(prod-db-password)
-STRIPE_KEY $(stripe-secret-key) Mark non-vault variables as secret in the library when they cannot live in Key Vault yet. Prefer vault for anything that rotates or has compliance requirements. Pair this setup with secrets scanning in Git and CI with Gitleaks so accidental commits get caught early.
Mapping secrets to environment variables for scripts
Shell and PowerShell tasks need explicit env blocks. Laravel Artisan, Composer auth, and npm private registry tokens all follow this pattern.
- script: composer install --no-dev --prefer-dist
env:
COMPOSER_AUTH: $(composer-auth-json) Generate strong local placeholders with our password generator tool during development. Never reuse production vault values on a laptop. Use separate vaults or secret names for dev, staging, and prod.
Azure Key Vault vs variable groups vs pipeline secrets — which should you use?
Teams often mix three storage layers. Understanding the trade-offs prevents duplicate secrets and stale values.
| Method | Best for | Rotation | Audit trail |
|---|---|---|---|
| Azure Key Vault | Production credentials, API keys, connection strings | Central rotation, version history | Azure Activity Log + vault diagnostics |
| Variable groups (non-vault) | Non-sensitive config, feature flags, build numbers | Manual update in Library | Azure DevOps audit events |
| Pipeline secret variables | Single-pipeline tokens, short-lived experiments | Per-pipeline edit | Limited cross-pipeline visibility |
Production systems should default to Key Vault. Variable groups linked to vaults give Azure DevOps a friendly variable surface. Plain library secrets are acceptable for low-risk values like a Slack webhook for build notifications.
HashiCorp Vault and AWS Secrets Manager solve similar problems on other clouds. Read our HashiCorp Vault secrets management guide, AWS Secrets Manager for pipelines, and multi-cloud secrets management comparison if your stack spans providers.
For GitLab-based PHP projects, the same principle applies even without Azure DevOps. External secret files and protected variables replace vault calls. See CI/CD with GitLab CI for Laravel for a parallel workflow on Linux servers I deploy regularly.
What are common mistakes when using Azure Key Vault in CI/CD?
Most failures I troubleshoot are permission or naming issues, not Azure DevOps bugs. The fixes are usually boring and fast once you know where to look.
- 403 Forbidden on fetch: RBAC not propagated, wrong principal, or vault firewall blocking the agent IP.
- Empty variable at runtime: Secret name mismatch between vault and YAML reference. Names are case-sensitive.
- Secret printed in logs: Script echoes the value or passes it as a command-line argument. Use env blocks instead.
- All secrets downloaded: Omitting
SecretsFilterpulls every vault secret into the job. Apply least privilege. - Shared vault across environments: Prod and dev secrets in one vault increases blast radius. Split by environment.
- No rotation plan: Vault stores the secret safely but stale passwords still work until rotated.
Network restrictions on the vault
Production vaults often allow only selected networks. Microsoft-hosted agents use dynamic outbound IPs. Either allow Azure DevOps service tags, use a self-hosted agent on a known subnet, or configure private endpoints with appropriate DNS. This trips teams that lock down vaults before testing pipeline access.
For AKS deployments, secrets often flow vault → pipeline → Kubernetes. Our deploy to AKS with Azure Pipelines and Kubernetes secrets management guide cover the next hop after the pipeline fetch.
Rotation without breaking builds
Key Vault supports secret versioning. Pipelines typically read the latest version. Coordinate rotation with a dual-write window when apps cache credentials. Update the vault value, redeploy, then revoke the old version if your compliance team requires it.
Broader CI/CD hygiene matters too. Follow CI/CD secrets management best practices and build pipeline automation best practices so vault integration fits a larger secure delivery model.
How do you use Key Vault secrets in GitHub Actions or other CI systems?
Azure Key Vault is not limited to Azure DevOps. GitHub Actions uses the azure/login action with OIDC federation, then Azure CLI or SDK calls to read secrets. Jenkins and GitLab CI can authenticate with a service principal and fetch secrets over the REST API.
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Read Key Vault secret
run: |
DB_PASS=$(az keyvault secret show \
--vault-name myapp-prod-kv \
--name prod-db-password \
--query value -o tsv)
echo "::add-mask::$DB_PASS"
echo "DB_PASS=$DB_PASS" >> $GITHUB_ENV The federated identity pattern avoids storing client secrets in GitHub. That is the same trust model Azure DevOps workload identity federation uses. Only the long-lived client ID sits in GitHub secrets; the vault holds everything sensitive.
On client projects where I handle full delivery, vault wiring sits alongside server hardening and deploy automation. That work falls under Linux system administration and enterprise application development when the pipeline deploys to Ubuntu VMs rather than Azure App Service.
Key Takeaways
- Store production credentials in Azure Key Vault; never commit them to YAML, Git, or unlinked library variables.
- Assign Key Vault Secrets User RBAC to the pipeline service principal or managed identity at vault scope.
- Link vault secrets through variable groups or the AzureKeyVault@2 task with an explicit
SecretsFilter. - Map secrets to tasks via
envblocks and treat log masking as mandatory, not optional. - Use separate vaults per environment and pair vault storage with rotation and Git secrets scanning.
- Re-run failed jobs after RBAC changes; propagation delay causes false 403 errors on first attempt.
People Also Ask
Can Azure Pipelines read Key Vault secrets without storing them in the library?
Yes. The AzureKeyVault@2 task fetches secrets directly into the job environment at runtime. Values never persist in the Library UI unless you also link a variable group. Use the task when you want fetch-only access per job.
Do I need a service connection to use Azure Key Vault in pipelines?
Azure DevOps YAML pipelines typically use an Azure Resource Manager service connection backed by a service principal or workload identity. That connection authenticates the AzureKeyVault task and vault-linked variable groups. Self-hosted agents can alternatively use a managed identity without a stored client secret.
Are Key Vault secret names case-sensitive in pipelines?
Yes. A vault secret named Prod-Db-Password will not resolve when YAML references $(prod-db-password). Match names exactly between the vault, variable group mapping, and YAML variable references.
How much does Azure Key Vault cost for CI/CD secret storage?
Key Vault charges per secret operation and per secret stored. Typical CI/CD fetch volumes stay within a few dollars monthly for small teams. At roughly Rs 650/month (~USD 5) for modest secret counts, vault cost is negligible compared to a credential leak or emergency rotation.
Ship pipelines that never store passwords in Git
To use Azure Key Vault secrets in pipelines correctly, treat the vault as the single source of truth for production credentials. Wire RBAC once, link secrets through variable groups or the AzureKeyVault task, and keep YAML free of values. That is the same discipline I apply on booking platforms like Adventure Third Pole Trek and client portals such as Mijar Law Associates, where deploy pipelines must stay auditable.
If you need help connecting Azure Pipelines, Key Vault, and your application stack, review our custom software development services or support and maintenance offerings. For encoding tasks during local setup, the Base64 encoder and decoder is handy—but production secrets belong in the vault, not in chat or tickets.
Contact us to audit your current pipeline secrets setup or plan a migration from plain-text variables to Key Vault-backed deploys.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

