
Geschreven door Funs Janssen
Software Consultant
Ik ben Funs Janssen. Ik ontwikkel software en schrijf over de beslissingen die daarbij komen kijken: architectuur, ontwikkelmethoden, AI-tools en de zakelijke impact van technische keuzes. Deze blog is een verzameling praktische aantekeningen van echte projecten: wat schaalbaar is, wat misgaat en wat in blogvriendelijke voorbeelden vaak over het hoofd wordt gezien.
Open Project Settings > Service connections in almost any Azure DevOps organization today and the list starts with warnings. Pipelines log them too. Microsoft is retiring the Azure DevOps issuer for workload identity federation, and every affected connection has to move to the Microsoft Entra issuer before 1 July 2027.
Microsoft's guidance makes it look like a one-click job: open the connection, press Update, done. For a lot of connections that's true. The hard part is everything around that button: finding every affected connection across dozens of projects, the identities owned by another team, the Terraform that quietly puts the old values back, and proving to someone that the job is actually finished.
In this post I'll walk you through the full runbook: what changes, how to build an org-wide inventory with one script, how to convert connections and handle the ones that fail, the errors you'll actually see, and a per-project checklist that tells you when you're really done.
What's changing, and when
Azure DevOps issuer vs Microsoft Entra issuer
A workload identity federation service connection doesn't store a secret. When a pipeline needs Azure access, Azure DevOps presents a token, and Microsoft Entra ID checks it against a federated credential on your app registration or managed identity. That credential trusts one specific issuer and subject.
- Azure DevOps issuer (retiring):
https://vstoken.dev.azure.com/<organization id>, with a subject built from names:sc://<organization>/<project>/<service connection>. - Microsoft Entra issuer (the new default):
https://login.microsoftonline.com/<tenant id>/v2.0, with a subject built from IDs instead of names.
That second difference matters more than it looks. Because the old subject contains names, renaming a project or a service connection broke the federation. The Entra issuer uses Entra-minted tokens and an immutable subject, so that class of breakage goes away.
The timeline: warnings now, end of life on 1 July 2027
According to the official retirement announcement:
- Since 1 July 2026, new connections use the Microsoft Entra issuer.
- Until June 2027, existing connections on the old issuer show warnings in the UI and in pipeline runs.
- On 1 July 2027, the Azure DevOps issuer is no longer supported. Connections that haven't moved will stop authenticating.
Nine months sounds like plenty. In my experience, the time doesn't go into the conversion itself. It goes into waiting for the team that owns the identity.
Part of a bigger shift to Entra-issued tokens
This isn't an isolated change. Azure DevOps is moving its authentication onto Microsoft Entra across the board: pipeline builds are moving to Entra-issued access tokens, and global PATs are being retired. If you're also working on that one, my post on the Azure DevOps global PAT retirement covers the user-token side. Treat both as one identity cleanup and you'll only have to talk to your identity team once.
Is your connection in scope?
Affected connections
The Microsoft Learn conversion guide lists what's in scope: workload identity federation connections that still use the Azure DevOps issuer and target a single-tenant app registration or managed identity in the Azure public cloud. In practice that means:
- Azure Resource Manager service connections (the vast majority)
- Docker registry connections that use workload identity federation
- Connections created by extensions that use the same mechanism
Out of scope
- Connections targeting Azure Government, Azure operated by 21Vianet or Azure Stack
- Multitenant app registrations. The Entra issuer doesn't support them, so if you want to move, convert the app to single-tenant first.
- Connections that use a secret or certificate. They aren't affected by this change, although moving them to workload identity federation is still a good idea.
- Third-party OIDC setups, such as the AWS Toolkit for Azure DevOps. AWS has confirmed these use their own trust configuration and fall outside this retirement.
Build an org-wide inventory first
The per-project view
Affected connections appear at the top of the service connections list with a warning. That's fine for one project. With thirty projects it means thirty clicks, no record of what you saw, and no way to track progress.
A scripted inventory with the Azure DevOps CLI
The service endpoint API returns the issuer in each connection's authorization parameters (workloadIdentityFederationIssuer, alongside workloadIdentityFederationIssuerType). That's enough for a full inventory. This script loops through every project and lists every workload identity federation connection that isn't on the Entra issuer yet:
1ORG="https://dev.azure.com/your-org"23az devops project list --org "$ORG" --query "value[].name" -o tsv |4while IFS= read -r PROJECT; do5 az devops service-endpoint list --org "$ORG" --project "$PROJECT" \6 --query "[?authorization.scheme=='WorkloadIdentityFederation'].[name, type, authorization.parameters.workloadIdentityFederationIssuer]" \7 -o tsv | sed "s|^|$PROJECT\t|"8done | grep -v "login.microsoftonline.com" > wif-issuer-inventory.tsv
Each row gives you the project, connection name, type and current issuer. If a row shows an empty issuer, check that connection in the UI rather than assuming it's fine. The script-based guide on Microsoft Learn documents these fields if you want to build on this.
Sort into three buckets
Don't start converting yet. First sort each row into one of three buckets:
- One-click. Azure DevOps created the identity, and you have rights on it. The Update button will handle it.
- Needs the identity owner. The app registration or managed identity was created by hand, by Terraform, or by another team. You'll need someone with rights in Entra to add a federated credential.
- Out of scope or blocked. Multitenant apps, sovereign clouds, cross-tenant setups. These need a decision, not a click.
Bucket 2 drives your schedule. Send those requests to the identity team this week, with the exact list, so their backlog isn't what makes you miss the deadline.
Converting a connection
The Update button
For bucket 1, the flow is short: open the flagged connection, select Update, confirm, and wait a minute or two. Azure DevOps creates the new federated credential on the identity and switches the connection to the Entra issuer. There's no downtime. Pipelines that are running keep running, and the next run uses the new issuer.
My advice: convert a non-production connection first and trigger a pipeline that uses it, so you've seen a successful conversion before you touch the connection behind your production deployment.
When it fails: the manual federated credential
If the conversion can't update the identity, Azure DevOps shows the Issuer and Subject identifier values it needs. Then:
- Copy both values exactly as shown. Don't build them by hand.
- In the Azure portal, open the app registration or managed identity, go to Federated credentials, and choose Add credential > Other.
- Paste the issuer and subject, give the credential a clear name such as
ado-entra-<connection>, and save. - Back in Azure DevOps, select Try again to finish the conversion.
If someone else owns the identity, this is exactly what you hand them: two values and four steps. It's a five-minute job for them if you give them everything they need.
Required permissions on both sides
- Azure DevOps: administrator on the service connection.
- Managed identity: Managed Identity Federated Credential Contributor or equivalent.
- App registration: owner, or an Entra role that can manage federated credentials.
Errors you'll actually see
The workload identity troubleshooting page has the full list. These four are the ones that come up during this migration:
- AADSTS70021: no matching federated identity record. The issuer on the identity doesn't match what Azure DevOps presents. Usually a manual credential has a typo, or someone created it with the old issuer. Compare it with the values in the conversion dialog.
- AADSTS700213: no matching federated identity record found for presented assertion subject. The subject doesn't match. On the old issuer this almost always means something was renamed. Fix the subject, or convert, which ends the problem for good.
- AADSTS70025: no federated credentials configured. The identity has none at all. Common when the conversion half-failed or someone cleaned up too early.
- AADSTS70052: the identity is multitenant. Convert the app registration to single-tenant before migrating.
Make the change stick
Update Terraform, Bicep and scripts
This is the trap no conversion guide warns about. If your federated credentials are managed as code, and that code hardcodes https://vstoken.dev.azure.com/... or builds an sc:// subject from names, the next deployment can overwrite or recreate the old credential. The connection then fails at the worst possible moment.
Before you convert connections that are managed as code:
- Search your repos for
vstoken.dev.azure.comandsc://. Every hit is a candidate. - Read the issuer and subject from the service connection's outputs instead of composing them. Recent versions of the Terraform
azuredevopsprovider expose them as attributes on the service connection resource. - Run a plan after converting and check for drift before you merge anything.
Remove the old credential once pipelines are green
The old federated credential stays on the identity after conversion. Leave it in place until every pipeline that uses the connection has run successfully at least once on the new issuer, then delete it. Fewer trusted issuers means a smaller attack surface, and anyone auditing the identity later won't be left guessing.
Make sure new connections use the Entra issuer
New connections already default to the Entra issuer, so the risk lies in templates and scripts that create connections with explicit issuer values. Update them once and the problem doesn't come back.
A rollout plan per project, with proof it's done
Sequence it
- Week 1: run the inventory, sort into buckets, send bucket 2 to the identity owners.
- Weeks 2 to 4: convert non-production connections and fix your IaC.
- Weeks 4 to 8: convert production connections, one project at a time, after a green pipeline run on a non-production connection.
- Final pass: rerun the inventory script. An empty file is your proof.
I'd aim to finish well before spring 2027. The deadline is fixed, and your release freeze periods aren't going to move for it.
A done checklist per project
A migration like this falls apart in the long tail: the project nobody owns, the connection someone converted but whose old credential nobody removed. I track it the same way I'd track any piece of work that has to be truly finished: one work item per project, with a checklist that blocks the move to Done.
A checklist that works:
- Inventory rows for this project reviewed and bucketed
- All in-scope connections converted to the Entra issuer
- One successful pipeline run per converted connection
- IaC searched and updated, plan shows no drift
- Old federated credentials removed
- Out-of-scope connections documented with an owner and decision
I use my own Checklist Extension for Azure DevOps for this: define the template once, apply it to each migration work item, and configure it so the item can't move to Done until every box is ticked. It's the same pattern I describe in making "Done" mean done in Azure DevOps Boards, and it gives you an audit trail for free. If you followed my Node 16 end-of-life inventory, you'll recognize the approach: find everything first, then track it to zero.
Conclusion
The Azure DevOps issuer retirement is a small change per connection and a large one per organization. The Update button covers most connections. The real work is everything around it:
- An org-wide inventory instead of thirty project pages
- Three buckets, so requests to identity owners leave in week one
- Non-production first, then production, with a green pipeline as proof
- IaC fixed before conversion, so the old values don't come back
- Old credentials removed and a final inventory that comes back empty
Finishing is what makes or breaks this migration. If you want each project's migration to stay open until every step is truly done, install the Checklist Extension for Azure DevOps. It's free, and a migration checklist template takes about five minutes to set up.
Frequently asked questions
Reacties
Nog geen reacties. Wees de eerste om te reageren.
Plaats een reactie

Geschreven door Funs Janssen
Software Consultant
Ik ben Funs Janssen. Ik ontwikkel software en schrijf over de beslissingen die daarbij komen kijken: architectuur, ontwikkelmethoden, AI-tools en de zakelijke impact van technische keuzes. Deze blog is een verzameling praktische aantekeningen van echte projecten: wat schaalbaar is, wat misgaat en wat in blogvriendelijke voorbeelden vaak over het hoofd wordt gezien.
