Well-Architected Framework
Secure Azure DevOps CI/CD secrets with HashiCorp Vault
Azure DevOps pipelines do not expose a single native pipeline JWT that Vault can validate directly the way other platforms do. Instead, Azure DevOps integrates with Vault by establishing Azure identity through an Azure Resource Manager service connection. Azure DevOps can then use that identity to authenticate to Vault's Azure auth method. This keeps static credentials out of Azure DevOps and moves authorization to Vault roles and policies.
For most Azure-connected pipelines, workload identity federation on the Azure Resource Manager service connection is the strongest native option. For self- hosted agents, the best Vault auth method still depends on where the agent runs and what identity the job can already prove.
Architecture
The pipeline-to-Vault authentication flow follows the same high-level pattern as the other CI/CD integrations in this section, but the verification step depends on the identity source available to the Azure DevOps pipeline. For Microsoft-hosted agents and most Azure-connected pipelines, the common pattern is Azure auth through a service connection:
- The pipeline authenticates to Azure using an authorized service connection
- Azure issues an access token scoped to the resource Vault expects
- The pipeline presents that token to Vault's Azure auth method
- Vault validates the token with Azure and maps the identity to a Vault role
- Vault issues a token scoped to that role's policies
The pipeline can now retrieve secrets based on the policy for that role.

Agent hosting and auth method selection
The right auth method depends on the following identity sources the pipeline job can prove:
- Azure service connection used for Vault login — Use Azure auth. This applies when the pipeline authenticates to Vault through an Azure Resource Manager service connection, regardless of where the agent runs.
- Self-hosted agent on Kubernetes without a service connection — Use Kubernetes auth. The pod's service account token is a stronger identity than a static credential.
- Self-hosted agent on AWS or GCP without a service connection — Use the corresponding cloud provider auth method. The instance or workload identity is stronger than a static credential stored in Azure DevOps.
- No cloud identity available — Use AppRole with response wrapping, or TLS cert auth if mTLS is already part of your security posture.
Authentication options
Use Azure auth for most Azure DevOps deployments that already rely on Azure Resource Manager service connections. Depending on your use case, there are additional auth methods that may be appropriate for self-hosted agents in your environment.
The following table summarizes when each auth method fits best.
| Auth method | Security posture | Credential lifecycle | Best suited for |
|---|---|---|---|
| Azure | High; federated Azure identity through a service connection | Short-lived Azure access token; no static secret required in the pipeline | Pipelines that authenticate to Vault through an Azure Resource Manager service connection |
| Cloud provider auth methods | High; identity is the underlying compute platform | Managed by cloud provider; no rotation required | Self-hosted agents on AWS or GCP where no Azure service connection is used |
| Kubernetes | Highest for in-cluster | Short-lived projected service account token on modern Kubernetes; legacy patterns vary | Self-hosted agents running as pods in Kubernetes where no Azure service connection is used |
| TLS Certificate | High; mutual authentication | Certificate with defined expiry; requires rotation process | Long-lived self-hosted agents where mTLS is already part of the security posture |
| AppRole | Moderate; requires secure secret ID delivery | Secret ID is single-use with response wrapping; RoleID is long-lived | Azure DevOps Server or isolated environments where no stronger platform identity is available |
Azure auth is the right choice when the pipeline authenticates to Vault through an Azure Resource Manager service connection. Microsoft supports the following three workload identity federation service connection patterns:
- App registration (automatic) — Azure DevOps manages the app registration and federated credential. Use this for new pipelines unless your organization requires manual control over the app registration.
- Existing user-assigned managed identity — Use this when a managed identity already exists and you want to reuse it across multiple service connections.
- App registration or managed identity (manual) — Use this when your organization requires explicit control over the federated credential configuration.
Role configuration
Azure DevOps pipelines commonly use a dedicated auth mount because the Azure token audience differs from the default audience used in other Azure auth flows. Bind the Vault role to the specific Entra ID object behind the service connection, and keep the token TTL short.
The client_secret in the auth mount config is Vault's own credential for
calling Azure APIs to validate pipeline tokens. It is separate from the service
connection credential and does not affect the pipeline's passwordless auth flow.
For Vault Enterprise, plugin WIF can eliminate this static secret from the Vault
config as well.
# Enable a dedicated Azure auth path for Azure DevOps
vault auth enable -path=ado azure
# Configure Vault's Azure auth mount with its own Azure API credentials
vault write auth/ado/config \
tenant_id="00000000-0000-0000-0000-000000000000" \
client_id="00000000-0000-0000-0000-000000000000" \
client_secret="<vault-azure-auth-client-secret>" \
resource="https://management.azure.com/"
# Bind the Vault role to the Entra ID object behind the service connection
vault write auth/ado/role/azure-devops-production \
token_policies="azure-devops-production-policy" \
token_ttl=15m \
token_type=batch \
bound_service_principal_ids="00000000-0000-0000-0000-000000000000"
The auth mount configuration lets Vault validate Azure-issued tokens for this integration path. The role binds Azure DevOps to a specific Entra ID object and limits the resulting Vault token to the attached policy set.
For automatic WIF service connections, bound_service_principal_ids is the
object ID of the enterprise application that Azure DevOps creates. For
user-assigned managed identity service connections, use the managed identity's
principal ID. Using bound_service_principal_ids means the pipeline does not
need to pass subscription or resource group metadata at login.
Workflow configuration
The example assumes the agent image includes the Vault CLI. The
AzureCLI@2 task authenticates to Azure through the service connection and
retrieves an access token that Vault validates.
steps:
- task: AzureCLI@2
displayName: Authenticate to Vault with Azure auth
env:
VAULT_ADDR: https://vault.example.com
inputs:
azureSubscription: 'AzureRM Service Connection for Vault'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
JWT="$(az account get-access-token \
--resource https://management.azure.com/ \
--query accessToken \
--output tsv)"
VAULT_TOKEN="$(vault write -field=token auth/ado/login \
role=azure-devops-production \
jwt="$JWT")"
echo "##vso[task.setvariable variable=VAULT_TOKEN;issecret=true]$VAULT_TOKEN"
- bash: |
export VAULT_ADDR=https://vault.example.com
export DATABASE_PASSWORD="$(vault kv get -field=password secret/ci/production/db)"
./deploy.sh
displayName: Retrieve secret from Vault
env:
VAULT_TOKEN: $(VAULT_TOKEN)
The first step exchanges the Azure access token for a short-lived Vault token. The second step uses that Vault token only for the secret read needed by the deployment.
Policy
The Vault policy for any Azure DevOps role should follow least privilege. A pipeline that deploys to production should not be able to read staging secrets, and a build pipeline should not inherit deployment credentials.
# Vault policy: scope to exactly the paths this pipeline needs
path "secret/data/ci/production/db" {
capabilities = ["read"]
}
path "secret/data/ci/production/api" {
capabilities = ["read"]
}
The policy limits the pipeline to the exact production secret paths it needs. Separate policies for other environments help prevent broad service connection identities from reading unrelated secrets.
Azure DevOps service connections are usually broader than repository- or branch-scoped identities from other CI/CD platforms. For that reason, use separate service connections, separate Vault roles, and separate policies for different environments or trust boundaries.
Security considerations
The following Azure DevOps-specific security considerations align with your organizational risk tolerance and operational constraints:
- Service connections are a coarse trust boundary: Azure Resource Manager service connections are project-level resources. If one service connection is shared across development, staging, and production pipelines, the Vault role bound to that identity becomes correspondingly broad. Use separate service connections per environment or privilege boundary.
- Authorize service connections per pipeline: Do not grant a Vault-related service connection to all pipelines unless every pipeline in the project should share the same trust boundary. Pipeline authorization is one of the main controls that prevents unrelated builds from using the same Azure identity.
- Prefer workload identity federation over service connection secrets: Azure Resource Manager service connections still support secret-based and other legacy auth models for compatibility. For new integrations, prefer workload identity federation to avoid storing long-lived service principal secrets in Azure DevOps.
- Azure Key Vault integrations create a different trust boundary: The
AzureKeyVault@2task and linked variable groups retrieve secrets into Azure DevOps variables rather than having the pipeline authenticate directly to Vault. Use those integrations when Azure Key Vault is the intended secret store, but do not treat them as equivalent to direct Vault-based secret access. - Use Microsoft-hosted agent networking carefully: If Vault or related Azure resources rely on IP allow lists, remember that Microsoft-hosted agent ranges change over time. Validate network controls before depending on hosted agents for production secret access.
For a list of additional security considerations, refer to the CI/CD security considerations page.
Integrate HCP Vault Radar
Before migrating to Vault-based secrets management, Vault Radar can scan Azure Pipelines YAML, repository content, and shared scripts for credentials stored as hardcoded values. This is particularly useful in organizations that have years of copied pipeline templates, variable groups, and release automation spread across many projects.
After migration, Vault Radar can monitor repositories continuously for new secret introductions — catching cases where developers add static credentials to pipeline YAML or helper scripts instead of retrieving them from Vault.
Refer to the HCP Vault Radar quick start tutorials to learn about HCP Vault Radar.
HashiCorp resources
Vault
- Read the Azure auth method documentation to configure Vault to validate Azure-issued tokens.
- Read the Kubernetes auth method documentation to authenticate pods using projected service account tokens.
- Read the AWS auth method documentation to authenticate self-hosted agents running on AWS compute.
- Read the GCP auth method documentation to authenticate self-hosted agents running on Google Cloud.
- Read the AppRole auth method documentation to configure bootstrap credentials for isolated environments.
- Read the TLS certificate auth method documentation to configure mTLS-based authentication for persistent agents.
- Read the Response wrapping documentation to learn how to deliver single-use secret IDs securely.
- Follow the Batch tokens tutorial to choose the right token type for CI/CD pipelines.
- Follow the Dynamic secrets: database credentials tutorial to generate short-lived database credentials from Vault.
HCP Vault Radar
- Read What is HCP Vault Radar for an overview of how Vault Radar scans for exposed secrets.
- Follow the Get started with HCP Vault Radar tutorial to enable continuous scanning for your repositories.
External resources
- Read Integrating Azure DevOps pipelines with HashiCorp Vault for an end-to-end walkthrough of the integration.
- Read Use an Azure Resource Manager service connection to configure workload identity federation in Azure DevOps.
- Read the Azure CLI v2 task reference for the full list of inputs and authentication options.
- Read the Azure Key Vault v2 task reference to retrieve Azure Key Vault secrets in pipelines.
- Read Link a variable group to secrets in Azure Key Vault to connect pipeline variable groups to Key Vault.
- Read Use Azure Key Vault secrets in Azure Pipelines to retrieve Key Vault secrets within release pipelines.
- Read the Azure DevOps provider for Terraform documentation to manage DevOps pipelines and service connections as code.
Next steps
In this section of managing CI/CD secrets, you learned how to use Azure Resource Manager service connections and infrastructure-native identities to authenticate Azure DevOps pipelines to Vault. Secure Azure DevOps CI/CD secrets with HashiCorp Vault is part of the Secure systems pillar.
If you are deciding when to use static secret synchronization versus direct runtime retrieval, review CI/CD dynamic and static secrets.