Azure DevOps security and policies

Azure DevOps (VSTS) by default has a model where any contributor can contribute to any branch in any Repo of projects for which they are Contributors.

Many organizations desire to apply more rigid controls and we will explore various options in constraining changes to GIT Repositories within Azure DevOps.

Security on GIT Repositories:


Many of the settings are self explanatory but we can go through them:

  1. Bypass policies when completing pull requests - This is useful for admins and service users.  I personally never enable as i prefer to hold myself to the same rules.  But this could be used, for instance, in a global cleanup script user
  2. Bypass policies when pushing  - Users with this can skip any branch policies set when pushing. For instance, locked branches.  Again, not a permission i tend to ever enable.
  3. Contribute - This is the normal push commits and lock branch abilities
  4. Contribute to pull requests - can create, vote and comment in PRs
  5. Create branch
  6. Create repository - we will need this to be allow to create forked repos
  7. Create tag
  8. Delete repository
  9. Edit policies
  10. Force push (rewrite history, delete branches and tags) - This is pretty key - without this, users cannot delete branches which is critical in completing Pull Requests - if you disable this, then all branches live forever (which is a bad idea).  You also need force history to split GIT repos, scrub history - such as if you find a cricital key or password was accidentally left in, or someone checked in some binaries that have inflated the repo.
  11. Manage notes - for GIT Notes
  12. Manage permissions - permissions for the repository
  13. Read - This is another very useful one - we disable this on a group to take a group of valid users (a “team” in the project) and remove source access for them.
  14. Remove others' locks
  15. Rename repository

A Common Agile Security Policy:

One of the most common models today is the GIT Flow pattern which uses “develop” as a stable main and “master” becomes a stable ‘released’ destination.


  1. Create a develop branch from master
  2. Set as default branch with elipse, set as default branch
  3. Set branch policies - (below) This just means when a person does “git clone”, the default checkout branch is “develop” instead of the default “master”

4. set branch policies

You'll see it as the second tab

A common Branch Policy:

Let’s walk through those a bit.

Require a minimum number of reviewers:  This is the minimum needed to approve a Pull Request.  By not checking the “Allow users to approve their own changes” it necessitates someone other than the author to review the changes.

Reset code reviewer votes when there are new changes: This to me is one of the best features that I did not encountered in GH Enterprise - namely, after a person approves a PR, if the author (or anyone else who can commit to the feature branch) pushes a followup change, it removes approvals.  This prevents un-reviewed changes from sneaking in after an approval.

Check for linked work items: If one uses “Boards”* then any PR needs to link to a valid Work Item (ticket describing the merits of change).

Check for comment resolution: Again, a great feature we used to follow just by practice in GH Enterprise.  If a person adds a feedback comment - that by itself blocks processing the PR until either the author or another marks the comment “resolved”.  This ensures all feedback is addressed before a Pull Request can be completed.

Enforce a Merge Strategy - I often do not set this, but one can force either ‘no-fast-forward merge’ which brings ALL the commits in or force ‘Squash merge’.  I tend to trust the developer as some developers (like myself) tend to put a lot of debug junk commits in while working, and other developers commit infrequently.  But perhaps you want all merges to master squashed to keep the changes just singular.  

We will get to Build Validation and Automatically including code reviewers next.