Intro and Setup
You now have the ability to use a managed identity to securely access Azure DevOps (ADO) via rest API calls. Prior to this functionality, the most common way to access Azure DevOps (ADO) was the use of personal access tokens (PAT). This wasn’t as secure or efficient because you would often times manage multiple PATs with no easy way to ensure your users are securely storing them. The use of Managed Identities or Service Principles takes away those fears and ensures your applications or azure resources can securely access Azure DevOps (ADO) via rest APIs.
I’ll briefly describe the setup now however if you require additional instructions, please refer to the resources section. I have an azure function and enable a system managed identity for it. This creates an enterprise app registration in Entra ID. Next, I can go to Azure DevOps Organization and click on Organization settings. From Organization settings, click on users and add your managed identity and give it visibility to projects that it will access. If you receive an error that states you need an email address, it’s usually because ADO is not linked with the Azure tenant ID that holds the managed identity. You’ll need to click Microsoft Entra within Org Settings and switch to the directory that matches your tenant. If your unable to do that and require to be bound to the currently linked Azure Entra ID tenant listed, you can implement a workaround defined here in the FAQ: Use service principals & managed identities – Azure DevOps | Microsoft Learn
I’m already connected so after accessing Org Settings/Users and entering my managed identity and clicking save looks like:
I accessed the project holding my ADO work items, clicked Project Settings/Permissions. Click Readers and added my managed identity.
Using Python, call ADO Rest API’s leveraging Managed Identity
This is the fun part for developers. In my example, I created an AZ Function based on http trigger. I want to make a rest call into an ADO workitem and provide the output to the browser window. I’ll include a link to a github repo that contains this code example.
Diving into source code above
I’m primarily interested in the authentication/authorization aspect of the source code above. If you want to understand overall basics of writing Azure functions in python, please check out my youtube video below in the resources section.
- Line 19 – credential = DefaultCredential() will acquire and use the managed identity to acquire an access token for access to ADO.
- Line 27 – Create an instance of BearerTokenCredentialPolicy and I pass the credential object and the scope which defines that defines which resources the token can access.
- Line 29 – Create an instance of Pipeline class. Without the pipeline, http requests and responses would not be processed properly. Here I’m instructing the pipeline to use the RequestsTransport() for handling HTTP requests and assigning the policy object I defined earlier. This policy simply adds the bearer token to the http request.
- Line 30 – Create an instance of HttpRequest and define the method and URL (this points to my ado rest api endpoint)
- Line 31 – Execute the http request by leveraging Pipeline.Run() and passing in the requests. The response is assigned to response.
After deploying the Azure Function to my Function App, I triggered a function run and voila!
Resources
Use service principals & managed identities – Azure DevOps | Microsoft Learn
AzurePython/samples/ADO-Managed-Identity at main · RussMaxwell/AzurePython (github.com)
Thanks,
Russ Maxwell