Credentialed Access to Azure DevOps
This document covers Azure DevOps patterns and practices for the use of credentials to programmatically interface with Azure DevOps services. This is a living document and will be updated as these patterns solidify.
Use Cases
There may be times when teams want to use Azure DevOps data to create a report or other custom application. A more specific example of this use case is leveraging the data from Azure DevOps to create a more in depth and personalized work item analytics report in Power BI.
To create the Power BI report in the screenshot above (which is one of many reports developed for the PoC), data was copied from Azure DevOps into Cosmos DB using Azure DevOps API and Microsoft Graph API. For this work, various credentials were required. There is full documentation as well as source code available in the mlife-metrics-services repo.
The other potential use cases that could be covered in this document are related to when we need to access an artifact or a cloud service from a pipeline. This is covered in the Secrets Management P&P. The summary is to use Azure Key Vault to store the secret (or key or file or other credential).
Definitions
A common term that is used when talking about access within Azure DevOps is a PAT. PAT stands for Personal Access Token (so don't call it a PAT token ;) ). A PAT is used as an alternative password to authenticate into Azure DevOps.
The other term to know for this document is service credentials. These allow developers to connect to external and remote services to execute tasks in a job, without creating a PAT tied to a specific person. These connections can be used in multiple pipelines.
Best practices for using credentials
- Never give the PAT more rights than it needs. Another term used for this concept is to follow the guidance of least privilege access.
- Do not reuse PATs. Create multiple PATs for multiple use cases.
- Related - make sure to give descriptive names to the PATs so you know which use case they were created for.
- Store the PAT in Azure Key Vault so you can version it and have a secure copy of it (not in a file).
- Never check the PAT into source control. Follow best practices and use good secrets management to provide the PAT to code. Remember a PAT should be treated like a password.
- If you don't want the credential associated with a personal account, create a service account and generate PATs with it following all the same things as above.
- Never use a personal account's PAT in Production.
Token Expiry
When a PAT is created an expiration date must be specified. Currently there is a maximum lifetime of one year for all Azure DevOps PATs. It is possible to extend the lifetime of a PAT and the string of the PAT does not change. From a security standpoint it is best practice to rotate secrets, so the best option is to consider the expiration of secrets as part of the product release checklist. If a secret is expected to expire before the next product release, that is a great time to create and/or update PATs.
Other applications (such as GitHub) allow for a never expiring token experience. Based on some posts in Microsoft's Developer Community, it does appear that a resolution is in the works (either an API to programmatically update the PAT or to allow never expiring PATs as some other applications already do). However, this is not available as of November 2020.
References
- https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page
- https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/authentication-guidance?view=azure-devops
- https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml
- https://developercommunity.visualstudio.com/idea/817953/allow-personal-access-tokens-that-do-not-expire.html
- https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops