Personal Access Tokens (PATs) are not your friends

Background

Programmatic connection to Azure DevOps cannot be done with your Active Directory credentials. This is because this involves a dialog being shown, and these days usually an MFA check too.

Historically, the solution to this problem was to enable Alternate Credentials, which could be passed as username and password, without the dialog being shown. However, the use of these has been deprecated since 2020, and they have been completely removed since Jan 2024.

So for a number of years the recommended way to programmatically authenticate with Azure DevOps has been to use a Personal Access Token (PAT). However, PATs are not without their own issues.

The problem with PATs

The most critical problem is that PATs expire. By default they expire after 30 days, and the longest you can set them to expire after is a maximum of 1 year. This means that you have to remember to renew them, and if you forget then your automation that rely on them will stop working.

Obviously it is very tempting to just set the expiry to 1 year, but this is not the best idea. The longer the expiry the more time there is for the PAT to be compromised. Just like SSL certificates, or any access token, the shorter period before the expiry the better.

Of course like any authentication and permission model you can grant too many permissions to a PAT, and then if it is compromised you have a problem, but that is on you not following the principle of least privilege, not a fundamental issue of PATs.

But what is the alternative?

Azure DevOps now offers support for Managed Identity & Service Principals. These are a much better way to provide a means to programmatically authenticate. Critically, they do not expire, and the tokens they generate for the actual connections are short lived, and you can of course grant them privileges in line with the principle of least privilege.

When used to access Azure DevOps resource, the only downside is they consume a basic user license.

This form of authentication is perfect for use in automation from locations like Azure Functions, or from the Az CLI.

What about GitHub?

The issue of PATs is not just one for Azure DevOps, the same problems are true for GitHub. On GitHub the solution is to use a GitHub App to authenticate with the GitHub API, and then use the short term token it can generate to authenticate with the GitHub API.

What about other outgoing services from Azure DevOps?

Another place you will see a move away from expiring secrets in Azure DevOps are Service Connections to services to such as Azure. You can now use Workload Identity Federation to authenticate with Azure.

Converting to use Workload Identity Federation is simple, you just press a button in the Azure DevOps UI, and it will create a Service Principal in Azure AD, and then update the Service Connection to use this to authenticate with Azure.

Swap to Workload Identity Federation

Once this is done there will be no need to remember to renew the Service Connection, as it will use the Service Principal to authenticate, and this does not expire.

Summary

So, when using Azure DevOps in many cases you can now avoid the use of PATs, and hence the need to remember to renew them. Giving you one less thing to remember to do, and one less thing to go wrong.