Azure DevOps global PAT retirement reaches its hard cutoff on December 1, 2026, when existing global personal access tokens stop working. A .NET release pipeline can still depend on one even when its YAML contains no token: the credential may live in a variable group, a package client, a self-hosted agent setup script, or an external deployment integration. This runbook shows how to find those dependencies, choose a safer replacement, cut over one consumer at a time, and prove that revoking the old token will not interrupt delivery.
Table of Contents
Azure DevOps global PAT retirement: confirm affected tokens
The Azure DevOps global PAT retirement applies to Azure DevOps Services global PATs: tokens created with the access scope set to All accessible organizations. It does not apply to Azure DevOps Server. Microsoft says all existing global PATs will be decommissioned on December 1, 2026 and recommends moving to organization-scoped PATs or Microsoft Entra authentication.
- Open User settings > Personal access tokens in Azure DevOps Services.
- Set Access scope to All accessible organizations and Status to Active.
- Record the token owner, display name, expiration, scopes, and each organization it reaches.
- Do not expect Azure DevOps to reveal the secret value again. A PAT value is shown only when it is created.
This list tells you which credentials are global, but not where their values are consumed. Azure DevOps audit logs record PAT lifecycle events such as creation, update, expiration, and revocation; Microsoft explicitly notes that token access events are not logged. You therefore need a consumer inventory before revoking anything.
Build a consumer inventory before changing secrets
Work from the token outward. For each global PAT, make one row per consumer rather than one row per token. A single token reused by six systems creates six independent cutovers.
| Consumer | Where to inspect | Evidence to capture | Likely replacement |
|---|---|---|---|
| YAML or classic pipeline | Variable groups, secret variables, task inputs, templates | Pipeline, stage, secret name, last successful run | Service connection with workload identity federation, or org-scoped PAT when required |
| NuGet restore or push | NuGet.config, credential provider, feed service connection | Feed URL, organization, restore and push owners | NuGetAuthenticate@1 in Azure Pipelines or Azure Artifacts Credential Provider locally |
| Script calling Azure DevOps REST | PowerShell, Bash, scheduled jobs, Key Vault references | Endpoint, HTTP method, required Azure DevOps permissions | Microsoft Entra token; org-scoped PAT only if the tool cannot use Entra |
| Self-hosted agent registration | Provisioning script, image build, runbook | Pool, organization, token owner, rebuild procedure | Separate short-lived org-scoped registration PAT with only Agent Pools scope |
| External integration | Vendor admin page, connector secret, extension publishing | Supported auth methods and organization boundaries | Microsoft Entra service principal/OAuth, or one org-scoped PAT per organization |
Search repositories for configuration names, not for a literal token. Useful terms include AZURE_DEVOPS_EXT_PAT, AZDO_PAT, VSS_NUGET_EXTERNAL_FEED_ENDPOINTS, System.AccessToken, Authorization: Basic, and your secret-variable names. Also inspect pipeline libraries, secure files, Key Vault-backed variable groups, deployment tools, developer machines, and scheduled automation outside the repository.
Do not print secret variables to identify a token. Match consumers by owner, purpose, scope, organization, and secret name. If ownership is uncertain, rotate in a controlled window instead of exposing the value.
Choose the replacement for each .NET workflow
Do not replace every global PAT with another long-lived PAT by default. Choose the identity from the workload and where it runs.
- Azure-hosted automation: prefer a managed identity when the hosting service and target operation support it.
- Automation outside Azure: use a Microsoft Entra service principal. Prefer workload identity federation or a certificate over a client secret when supported.
- Azure Pipelines deployments: use an Azure DevOps service connection with workload identity federation for Azure resources instead of placing a PAT in YAML.
- Interactive Git: use Git Credential Manager with OAuth rather than a PAT stored in a remote URL.
- Tool with no Entra support: create a separate organization-scoped PAT with the minimum scopes and shortest practical lifetime.
A Microsoft Entra application identity must be added explicitly to each Azure DevOps organization it accesses, then granted the required access level and resource permissions. Adding the identity only to a Microsoft Entra group does not automatically make it available in Azure DevOps.
For PAT fallback, avoid recreating the original blast radius. Use one organization-scoped token per owner and workflow, not one token shared across unrelated build, package, and deployment jobs. Keep an inventory of the owner, purpose, scopes, expiration, secret location, and consumers.
Cut over without breaking releases
Use a replace-test-observe-revoke sequence. Never regenerate the old PAT as the first step because regeneration invalidates its current value immediately.
- Create the replacement. Configure only the target organization and required permissions. Give it a new secret name such as
AZDO_ORG_PAT_V2; do not overwrite the old value yet. - Update one low-risk consumer. Start with a read-only or nonproduction operation that exercises the same organization and permission path.
- Verify authentication and authorization. A successful sign-in with an under-scoped identity can still fail later on feeds, repositories, environments, or approvals.
- Promote the replacement. Update remaining consumers one at a time. Record the deployment or pipeline run proving each change.
- Observe scheduled work. Run or wait for nightly restores, package publication, release triggers, external integrations, and agent-image rebuilds.
- Revoke the global PAT. Re-run critical consumers after revocation. Keep the rollback procedure, not the old secret, as your safety net.
For an organization-scoped PAT, a harmless REST read can serve as the canary. The following PowerShell request lists recent builds and fails fast on authentication or scope errors. Supply the PAT through a secure environment variable; never paste it into the script or log the authorization header.
$organization = "contoso"
$project = "Payments"
$pat = $env:AZDO_ORG_PAT_V2
if ([string]::IsNullOrWhiteSpace($pat)) {
throw "AZDO_ORG_PAT_V2 is not set."
}
$basic = [Convert]::ToBase64String(
[Text.Encoding]::ASCII.GetBytes(":$pat")
)
$headers = @{ Authorization = "Basic $basic" }
$uri = "https://dev.azure.com/$organization/$project/_apis/build/builds?`$top=1&api-version=7.1"
$result = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
"PASS: replacement credential returned $($result.count) build record(s)."
This verifies only the Build read path. Test every material permission separately: repository read, feed restore, package push, environment deployment, service connection use, or extension publication. A green build-list request is not proof that a package push will work.
Verify, revoke, and troubleshoot
| Failure | Likely cause | Next check |
|---|---|---|
401 Unauthorized | Wrong secret, expired/revoked PAT, wrong organization, or invalid Entra audience | Confirm secret version, token status, organization URL, and authentication flow |
403 Forbidden | Identity authenticated but lacks Azure DevOps permission, access level, or resource authorization | Check organization membership, project permissions, feed/repository/environment ACLs |
| Restore succeeds but push fails | Read scope exists but packaging write permission is missing | Test restore and push separately; verify feed permissions and task/service connection |
| One organization works, another fails | Replacement is organization-scoped or application identity was not added to the second organization | Create a separate org-scoped credential or add and authorize the Entra identity in that organization |
| Pipeline works; nightly integration fails later | Undocumented consumer still holds the old secret | Return to the consumer inventory and inspect schedulers, external vendors, and image-provisioning scripts |
After revocation, verify the next scheduled operation for every consumer and filter Azure DevOps auditing for PAT lifecycle events. Remember that the audit log can show that a PAT was created, updated, expired, discovered publicly, or revoked; it cannot prove whether the PAT was used. The durable proof is a completed consumer inventory plus successful runs after the old credential is revoked.
Definition of done
- No active token is scoped to All accessible organizations.
- Every .NET build, test, package, deployment, and integration consumer has an owner and a recorded replacement.
- Non-user automation uses Microsoft Entra authentication where supported.
- Any remaining PAT is organization-scoped, minimally scoped, short-lived, and stored outside source and logs.
- Critical consumers succeeded after the global PAT was revoked.
- PAT policies prevent new global or full-scoped credentials where the organization supports enforcement.
References
- Microsoft DevBlogs: Retirement of Global Personal Access Tokens in Azure DevOps
- Azure DevOps Sprint 270 update
- Use personal access tokens in Azure DevOps
- Authenticate to Azure DevOps with Microsoft Entra ID
- Use service principals and managed identities in Azure DevOps
Found this useful? Support more practical developer content.