Cloud Security

Azure DevOps Personal Access Tokens in 2026: Rotation, Scoping, and Replacement

PATs remain the most common credential leak in Azure DevOps incidents. We trace the patterns that actually reduce risk and the migration paths that retire them entirely.

Shadab Khan
Security Engineer
7 min read

Personal Access Tokens (PATs) in Azure DevOps have been the single most common credential involved in incident postmortems touching the platform over the last several years. The pattern is familiar: a developer creates a PAT to integrate Azure DevOps with a build tool or a script, the PAT is given full-scope permissions because the docs example shows that scope, the PAT lands in a config file or environment variable that gets committed or logged, an attacker discovers it, and the resulting access has roughly the same blast radius as the developer's full identity. Microsoft has tightened the surrounding controls considerably through 2025 and into 2026 — administrative PAT policies, restricted creation, scoping enforcement, and improved auditing — but the underlying credential pattern has not changed, and "we have PAT policies in place" does not protect an organization whose teams still treat PAT creation as routine. This is the defender's guide to making the controls actually stick.

What is a PAT actually authorized to do?

A PAT is a bearer token tied to a user account. When the PAT is used, Azure DevOps treats the request as coming from that user, scoped to the permissions selected at PAT creation time. The permission scopes are granular — read code, manage build pipelines, manage release pipelines, manage packaging, and so on — but the granularity is wasted if every PAT is created with "Full access" because that is the path of least resistance. A "Full access" PAT held by a developer with administrator rights on a project is a near-complete handover of project control to whoever holds the token. Even a "Read code" PAT, if held by a user with broad repository access, can exfiltrate source for every repository the user can see. The mental model that works is: a PAT is the user, with the permissions they checked at creation time, until the PAT expires or is revoked.

What does scoping actually look like in practice?

The right pattern is: every PAT has the minimum scope required for its use case, an expiration no longer than the period of legitimate use, and a name that identifies the use case. A PAT created for a single CI integration should have only the scopes that integration uses (typically "Build read & execute" and "Code read" for most build scenarios), should expire within a few weeks, and should be named after the integration it serves. The wrong pattern is the catch-all PAT created by an administrator "for the team to use," which then gets passed around, lives for the maximum allowed lifetime, and survives team turnover. Administrators should disable user-creation of PATs above a defined scope ceiling, require justification for long-lived tokens, and review the inventory of active PATs at least quarterly with rotation enforced for tokens that look stale or unscoped.

# List all active PATs across users in an organization (admin scope required)
az devops invoke \
  --area Token --resource pats \
  --route-parameters subjectDescriptor='*' \
  --query-parameters displayFilterOption=active \
  --org "https://dev.azure.com/myorg"

What should replace PATs for service integrations?

Three options, in roughly increasing order of operational maturity. The first is OAuth applications: third-party tools that need Azure DevOps access can authenticate via OAuth on behalf of a user, with consent flows that record what access was granted. This is appropriate for SaaS tools and gives users clear visibility into what they have authorized. The second is service principals from Microsoft Entra ID: a workload identity in Entra is granted access to Azure DevOps resources, and the workload authenticates with a managed identity or a federated credential rather than a PAT. This is appropriate for any integration that runs as a service rather than as a user. The third is workload identity federation: a CI runner or build agent running outside Azure DevOps (a GitHub Actions runner, an external Kubernetes cluster) authenticates using its own OIDC token, federated through Entra, eliminating the need for any durable secret at all. By 2026, this is the recommended pattern for most CI integrations.

How do you actually retire existing PATs?

The migration is not technically difficult; the political work is the hard part. The steps are: inventory every PAT in active use (most organizations are surprised at how many exist), categorize each by purpose (CI integration, third-party tool, ad-hoc script, mystery token nobody admits to creating), identify the replacement for each category (workload identity federation, service principal, OAuth app, decommission), implement the replacement in parallel for a sample, validate, and then run a forced expiration program for the rest. The political work is convincing teams who have working integrations to migrate; the lever that works is administrative policy that caps PAT lifetimes at progressively shorter windows, so the migration is not voluntary but the timing is owner-controlled. A program that announces "PAT lifetimes capped at 30 days starting in Q2, 7 days starting in Q3" produces faster migration than one that asks teams to volunteer.

What about leaked PATs that are already in the wild?

The realistic assumption in 2026 is that some PATs your organization has created are already in attacker-accessible locations: committed to public repositories by accident, exfiltrated through a third-party breach where you used the PAT, captured by an info-stealer on a developer's workstation, or scraped from a misconfigured logging system. The defense is to assume leakage and detect rapidly. Azure DevOps's secret-scanning detects PATs committed to repositories on the platform, but does not detect PATs leaked elsewhere. GitHub's secret-scanning, GitLab's similar feature, and several vendor services scan public sources broadly. The audit log shape of PAT abuse is distinctive: API calls from unexpected IP ranges, sudden access to repositories the user does not normally touch, bulk reads, and access at unusual times. Wire those signals into your SIEM with alerting, and treat any anomaly as a credential incident with full revocation rather than investigation-first.

How does this fit with broader Entra and Azure identity practice?

Azure DevOps's identity story is increasingly converged with Entra ID. A PAT used today should be a vestige; the durable identity is the Entra user or workload, and PATs are just one of several token types that user or workload can mint. The supply chain implication is that hardening Azure DevOps PATs without hardening the broader Entra environment is half a defense. The defender's checklist extends beyond PAT scoping to: Entra Conditional Access policies that gate PAT issuance and use on managed devices and network locations, Privileged Identity Management for administrative roles in Azure DevOps so that PAT creation policy changes require just-in-time access, and Continuous Access Evaluation that revokes tokens (PAT included) on risky sign-in events. The PAT then becomes a minor part of a defense in depth rather than the load-bearing credential it has been historically.

What does a healthy state look like?

In a defended organization in 2026: PAT creation is restricted to a narrow set of scopes and lifetimes by administrative policy, most service integrations have migrated to workload identity federation or service principals, the remaining PATs are inventoried with owner, purpose, and rotation date, audit logging on PAT use is wired into the SIEM with alerting on anomalies, leaked-PAT detection covers public sources and is acted on within hours, and the trend over time is a falling PAT count rather than a stable or growing one. The number of active PATs in the organization is itself a useful metric for the security team to track; if it is not going down, the migration program is not working.

How Safeguard Helps

Safeguard inventories every PAT across your Azure DevOps organizations along with its scope, owner, lifetime, last-use timestamp, and the integrations that consume it — surfacing unused tokens, over-scoped tokens, and PATs that violate your administrative policy. Policy gates block infrastructure-as-code changes that introduce new PATs into automation when a workload-identity-federation path exists, and flag CI configuration files that contain PAT references for migration. Griffin AI correlates PAT-related audit events with downstream artifact pushes, pipeline runs, and repository accesses, so an anomalous use pattern surfaces as an incident with full context rather than a noisy log line. Continuous monitoring of Entra ID identity posture, secret-scanning results, and PAT lifecycle turns the long migration away from PATs into a tracked program rather than a perpetual aspiration.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.