Monday, July 13, 2020

Packages for using Azure DevOps Rest Clients

Today, I am going to discuss about the ADOAdmin.AzureDevOps.Clients  which can be used to call, patch and post any of the ADO API.

ADOAdmin.AzureDevOps.Clients, as the name suggests it has been aimed for ADO admins who use the ADO api's extensively. This package has got modules for working Azure DevOps  API operations as GET,PATCH and POST. This can be further extended, based on the suggestions.

This package gives facility to avoid the repetition of codes that is being used for API calls.

How to Install it?

1. Click on "Manage Nuget Package" for your solution/project
2. Search for "ADOAdmin.AzureDevOps.Clients"
3. Install it.









How to use it?

1.Once you install it, in namespace as

using ADOAdmin.AzureDevOps.Clients;

2.Once you add it in the package list, create an object for RestAPIClients:

 RestAPIClient adoClient = new RestAPIClient();       

3. To use it for GET operations:

string _jResponse=adoClient.AzureDevOpsGet(string devOpsPat, string apiUrl)

Sample:

string auditRepsonse = adoClient.AzureDevOpsGet(adoPat, adoApiUrl = string.Format(
             @"https://auditservice.dev.azure.com/{0}/_apis/audit/auditlog?startTime={1}&endTime={2}&continuationToken={3}&batchSize=1000&skipAggregation=true&api-version=5.1-preview.1",
               accountName, auditReadStartTime, auditReadEnddate, continuationToken));

4.To use it for POST operations:

string _jResponse=adoClient.AzureDevOpsPost(string devOpsPat, string apiUrl, string jsonData)

5.To use it for PATCH operations:

string _jResponse=adoClient.AzureDevOpsPost(string devOpsPat, string apiUrl, string jsonData)

Without much complications and googling for how you can use httpclients to call ADO API's use can directly use these packages.

The source code for these packages can be found here: Ado_api_Usage

Hope this helps!!!




                

Sunday, May 17, 2020

Manage Azure DevOps License


In this blog, I am going to explain how we can manage the licenses in Azure DevOps in a better way.

We have different type of licenses that are being provided by Microsoft to access Azure DevOps at different price levels and privileges.






















Most widely used licenses to access the ADO are Basic and Basic+Test Plan which costs to $5 and $52 user/month. Allocation of these licenses are pretty easy and can be done seamlessly. But the monitoring of these licenses, whether the people are using these licenses appropriately is very difficult. At times we might have allocated some folks Basic+Test Plans license and he might have moved to some other project with another tool, but still exists in ADO without accessing ADO and wasting the license. Especially during these times when companies are planning about cost-cutting, this document might help them.

The steps to monitor the usage of ADO by users using ADO rest API can be done as below:
1.First get the list of all users with their licenses and last Access date using the User Entitlements - List API:


Example:
  
From the response collect all the users Id, licenses and last access date:




























Now check whether the user’s last access date is more than 30 or not. 30 is a random number which we decided, so that those who have not used ADO for last 30 days, we will send a warning message to use ADO or else the license will be downgraded to stakeholder one.
Now if you want to downgrade directly the license of those users who have not used the ADO from last 30 days you can use API Update user entitlements:
















Once we patch and update the license, we can see in ADO UI as below:






API response:


























We can execute these API’s as a scheduled job which might execute twice a month to monitor the licenses. The entire source will be uploaded to my git repository soon.

Tuesday, May 12, 2020

Create common group which can access all team projects in Azure DevOps


Depending on organizational structure and security, some of the organisations would need a common security group with atleast read access to all projects. This might be for management monitoring or for some secutiry purpose.
So for creating such groups, first of all you need need to collection admin of the organization. Now create a new group in Azure devops at collection level with the basic inherited permissons. Here I have created a goup with name “Allprojectaccessgroup”.


























Now add people to this group who needs read permission to all the projects of your organisation.

Next step would be to create a group a group rule. For this you need to go to Users tab at organizational level.





Select add group rule and add the collection level group to it.

















From the projects dropdown select the required projects in which you need to add this group. If you want add to all projects select “All”.
Once select the projects, save it. Now wait for a moment and check for the group rule being listed under the group rule tab. Select “Manage group rule” from the menu options. 







While managing group rule you can assign to required group and assign the access level:















You can select for all the projects as “Project Readers” and save it.

If we go inside projects “Readers” security group, we would be able to see this collection group being added to the project.











From here on for all the projects we create, we have to either go manually select from manage rules at group rule level or we can do some automation to update the group rule. The easiest way would be creating automated scripts using API’s to update the group rule. We can automate this using some scheduling approach. We have scheduled our script to execute once every day, so that any project created will have the new group added on the same day. I will put the code soon in my github repository.

Hope this works for you!

Thursday, April 2, 2020

Azure DevOps : Creation of custom security groups using ADO Rest API


Depending on organizational structure and security requirements, there can be a need for custom security group(s) at the project level. For example, a project level group that has access only to repos. Now this can be a standard requirement as well, where all projects getting created in the org should have this custom security group created as part of it – this post will focus on explaining how custom security groups can be created using Azure DevOps rest apis.

If you are looking to create a custom security group in all your projects,(existing and the ones getting created) please take a look at this public git repository. This repository consists of an azure function, the way which we used to automate the creation of custom security group. The azure function which  runs daily to check for new projects and created the security group.

Pre-requisites:
  1.       Collection admin privileges on Azure DevOps org.
  2.       Knowledge on ADO Rest APIs and Access Control Entries.

Create the security group

         Create the security group using the ADO rest API.
For this we need:
Ø  the project id and
Ø  the scope descriptor.
To get the project id use the Projects – List API:


Response:


Once you get the project id, use it to find the scope descriptor using Descriptors - Get:


Example: From the above response my project id is 123456789. Use this as storage key:


Response:


Here storageKey refers to the project Id.

Once you get the descriptor create the security group in the project using Groups - Create, by providing the group name and group description in the request body.



Use the below json as body for post:




Response:

















Here display name is the group name, I have given it as “MyGroup” - once you post this you will find a new group getting  created in this project.









The group being created will have the below permissions:





















Make sure that view project-level information is enabled. Else you will have to follow the below same steps to enable the “view project-level information”. Here for me view project -level information is enabled. So below I am going to explain how you can enable the view for repos for this group.

Assign permissions to the newly created security group

Once you create the group you need to set the permissions for this group. For this we should get the list of Namespace IDs, with Security Namespaces – Query :



You will find around 50 plus namespaces with its key permission and bit value as shown below. For example, if you take repo level namespace, it may look like as shown below. Here the namespace id for repo level permissions is 2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87. In order to set the permissions for the group, we should identify:
  • the correct namespace
  • the actions to allow/deny





















Now here we must understand that the permissions/ Access control entries in ADO are controlled by its bit value. For example at repo level if you want to give only Generic Read permission then the “allow” bit value for ACE should be 2 and if you want to give Both Generic read and contribute permission then we have to take sum of both the bits i.e. 2+4=6. In case you need to deny permissions, add up the “deny” bit values for the namespace. Once you get the required, set the group’s permissions using  Access Control Entries - Set Access Control Entries:









Here one tricky thing could be that, we may have to decode the base descriptor using base64.We get the base descriptor in create group step.

Separate the descriptor from vssgp and decode it. Once decoded use this to append with descriptor using in namespace update/ACE update. Here Uy0xLTktMTU1MTM3NDI0NS0zNzMyNDgwMzkxLTIwOTQzODAzNTQtMjkwMjExNjYwMy00NzQwMjk2OTAtMS0zNzI1Njg1NDI4LTI5ODA4NTQ4NTgtMjE3MjE5MTIzNS0zMzMzODgxMDg4, can be decoded to S-1-9-1551374245-3732480391-2094380354-2902116603-474029690-1-3725685428-2980854858-2172191235-3333881088.

Important thing to note here is we need to validate that the descriptor length can be divided by 4.If its length is not divided by four then add “=” at the end of the descriptor until the length becomes divided by 4.

So, the whole body for POST request should look like below:







Now if you check the permissions at the repo level, you will be able to see that both GenericContribute and GenericRead add will be enabled for MyGroup, since allow bit is 6.

GenericContribute=4 + GenericRead=2 = 6

Once POST is successful navigate to ADO repository permissions to see the access to MyGroup:





Hope this helps!








  

















Monday, February 10, 2020

How to Use Azure KeyVault Secrets in Azure Function

In this blog I am going to explain how we can use use values saved in Azure Key Vaults can be used while building Azure Function .

First of all you need to have your Key Vault (https://docs.microsoft.com/en-us/azure-stack/user/azure-stack-key-vault-manage-portal?view=azs-1910) and an Azure Function Created(https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-function-app-portal) in Azure.

Once you have your Azure function, enable the managed service identity which will add an identity in your azure AD. To do this click on Platform Features->Identity













Now change the button from "Off to On" for System Identity














Once you enable the Identity, you will get the below message:



Now go back to Key Vault. Click on the Access Policies inside Key Vault:



















Now Click on "Add Access Policy":












Now on "Add Access Policy" page click on the "Select Principal"













Now on the search pop up search for your azure function, for example here my Az Function name is "MyKeyVault" function

















And now from "Configure from template" provide proper access that is required.














Now click "Add". Now click on "Secrets" and "Generate/Import Secrets" to save new "Secret Values" in Key Vault:




















Once you add the secret, copy the secret identifier:






Now go back to Azure function and select configuration and add a new variable:













Here I am going to add a new Application Setting string "MyPat" and paste the secret identifier copied from key vault to the value text box as shown below:

@Microsoft.KeyVault(SecretUri=Secret Identifier from Key Vault)

@Microsoft.KeyVault(SecretUri=https://arunvarriardevops.vault.azure.net/secrets/myvault/123456789)


Once you add this now we can directly use these as system config values in our azure function as:

string MySecretKey= System.Environment.GetEnvironmentVariable("MyPAT");

Here System.Environment.GetEnvironmentVariable("MyPAT") will fetch the actual key vault secret and save it to the string MySecretKey.

I hope this helps.