In Azure Repos there are a lot of places where you can set security:
- At the Branch level (develop, master)
- At the Branches level (default for all branches)
- At the Tag level
- At the Tags level (default for all tags)
- At the Repository level (PartsUnlimited-GDBC)
- At the Git Repositories level (for all repositories in a project)
But there is no UI to set the security at the Organization level. This is fine if you're happy with the default security settings in Azure DevOps, but if you want certain settings to apply to all projects (also newly created projects), then it's sometimes useful to set the permissions at the Organization level.
For the Global DevOps Bootcamp we have a few challenges that require changes to be committed to Git through an automated process in order to cause a disruption.
To ensure the changes are able to bypass any branch policies and protected branches, we needed to make sure the service account that makes the change is able to bypass policies.
If you've dug into the security innards of Azure DevOps in the past, you'll have found out that certain permissions are granted to persons or groups and are linked to a token. This token is usually built up out of a root object and a bunch of GUIDs. For example, this is the token for a specific Git Repository:
Simplest way I know of to find these details, is to capture the web request made when a permission is changed:
Once you understand this, it's easy to find the token for the "All Repositories in a Team Project" token. Just take off the Git Repository GUID at the end:
And, using the same reasoning, to get to the token for "All repositories in the Project Collection/Organization" token. Just take off the Team Project GUID at the end:
And now that we have this token, we can use
tfssecurity to set Organization level git permissions:
tfssecurity /a+ "Git Repositories" repoV2/ "PullRequestBypassPolicy" adm: ALLOW /collection:https://dev.azure.com/org ^ ^ ^ ^ ^ ^ | | | | | -- Allow or Deny the permission | | | | -- The Group (in this case "Project Collection Administrators") | | | -- The Permission we want to set | | -- The Token we found above | -- The Secuity Namespace -- Add (a+) or Remove (a-) this permission
And, as you can see below, this trick actually works :).
You can use the same technique to secure branches. The token of a branch uses the token of the Repository as a basis and adds the branch to that. Because a
/ is a token separator, a branch reference is escaped by replacing
repoV2/daec401a-49b6-4758-adb5-3f65fd3264e3/f59f38e0-e8c4-45d5-8dee-0d20e7ada1b7/refs^heads^master/ ^ ^ ^ ^ | | | | | | | -- The branch | | -- The Git Repository | -- The Team Project Guid | -- The root object (Repositories)
This was very useful for the Global DevOps Bootcamp. Instead of having to customize the permissions for 3000 Team Projects, we could now simply set this permission in the 7 organizations that were setup for the event.
Note: You can use the REST API to manage security as well, but it requires a little more work to look up the correct identifiers for the Group or User, the Namespace Identifier and more. While generally more complete, the REST API is even harder to understand.
tfssecurity you can now also use
az devops permissions to set permissions. You still need most of the intricate knowledge of the tokens:
- Use TFSSecurity to manage groups and permissions for Azure DevOps
- Azure DevOps REST API - Security
az devops security
Photo credit: Stephen Edmonds.