Azure DevOps Workload Identity Federation
Use Azure Resource Manager service connections with Workload Identity Federation for new Azure DevOps pipelines. Avoid service principal secrets and publish profiles.
Recommended service connection options
- App registration with workload identity federation (automatic) when the creating user has sufficient permissions and the environment supports it.
- Managed identity with workload identity federation when using an existing user-assigned managed identity or when app registration creation is restricted.
- Manual workload identity federation only when automatic options cannot be used.
Do not grant access permission to all pipelines by default. Authorize only the pipelines that require the service connection.
Subject shape
Azure DevOps service connection subjects commonly use:
sc://<organization>/<project>/<service-connection-name>New service connections created since November 2025 (and all connections after the legacy issuer retires on 2027-07-01) use the Microsoft Entra issuer https://login.microsoftonline.com/<tenant-id>/v2.0 with an immutable, ID-based subject:
<entra-prefix>/sc/<organization-id>/<service-connection-id>The two shapes coexist: manually created connections may still carry the sc:// subject with the Entra issuer. Never construct the subject string from names or IDs in automation ; read the actual issuer and subject from the service connection instead:
- REST API / pipeline variables:
workloadIdentityFederationIssuer,workloadIdentityFederationSubject - Terraform
azuredevops_serviceendpoint_azurerm:workload_identity_federation_issuer,workload_identity_federation_subject
AzureCLI@3 pattern
steps:
- task: AzureCLI@3
displayName: Verify Azure context
inputs:
azureSubscription: azure-prod-wif
scriptType: bash
scriptLocation: inlineScript
visibleAzLogin: false
inlineScript: |
az account show --query "{tenantId:tenantId, subscriptionId:id, user:user.name}" -o jsonUse allowNoSubscriptions: true only when the identity intentionally has no subscription access, such as tenant-level checks.
Azure SDK in pipeline code
When code running inside the pipeline uses the Azure SDK directly, prefer the credential supported by the current SDK/task combination. Some SDK scenarios require SYSTEM_ACCESSTOKEN or task-provided OIDC variables. Keep token-related variables scoped to the task that needs them.
Terraform note
For Terraform, use provider-supported OIDC/workload identity environment variables scoped to the Terraform task. Do not persist token values as pipeline variables or artifacts.
Migration from legacy service connections
- Convert existing eligible Azure Resource Manager service connections to workload identity federation.
- Canary non-production first.
- Keep the legacy secret-backed service connection only for the shortest practical overlap.
- Track owner, removal date, and migration issue.
- Remove the client secret after successful release evidence.
Common failures
| Error/symptom | Likely cause | Fix |
|---|---|---|
AADSTS700016 |
App/client ID used by service connection no longer exists or is wrong | Verify service connection identity/client ID |
AADSTS70021 |
No matching federated identity record; issuer or subject mismatch | Compare issuer and subject exactly |
AADSTS700211 |
No matching issuer | Create/update federated credential with correct issuer |
AADSTS700213 |
No matching subject | For legacy sc:// subjects: update after org/project/service-connection rename. ID-based subjects survive renames — verify which shape the credential uses before editing |
AADSTS700223 or AADSTS700238 |
Tenant restricts workload identity federation | Ask tenant admin to allow the workload identity type/issuer |
AADSTS70025 |
Identity has no federated credentials configured at all | Create the federated credential on the app registration/managed identity using the issuer and subject shown in the service connection |
AADSTS700024 |
Client assertion outside its valid time range (commonly expired in a long-running job). Verify the exact AADSTS700024 text against the current Microsoft error-code reference. | Move token-acquiring commands earlier, split job, or evaluate managed-identity-backed service connection/task support |
403 Forbidden |
Token exchange worked, Azure RBAC is missing or not propagated | Fix role scope or wait/retry |