Skip to main content

Command Palette

Search for a command to run...

A Guide to Azure DevOps Branch Protection

Updated
7 min read
A Guide to Azure DevOps Branch Protection
Y

Cloud & DevOps Engineer skilled in AWS, Linux/Windows, Bash, PowerShell & Python. Passionate about automation, CI/CD, and continuous learning toward DevOps mastery.

Inception

Hello everyone, this post is aimed at guiding you to protect your branch in Azure Repos and maintain stable, production-ready code. In addition, implementing a lap simulating the situation to explain the concept

Overview

First, let me explain what Azure DevOps is. Azure DevOps is a Microsoft platform that helps teams plan, build, test, and deploy software from idea to production using modern DevOps practices.

Think of it as an all-in-one DevOps toolbox that supports CI/CD, project management, source control, and automation.

It includes Azure Boards – Plan & Track Work, Azure Repos – Source Control, Azure Pipelines – CI/CD, Azure Test Plans – Testing, and Azure Artifacts – Package Management.

So why do teams use Azure DevOps instead?

Due to its end-to-end DevOps platform, Strong enterprise security & RBAC, Deep integration with Azure Cloud, support for large teams & enterprises, and support for Infrastructure as Code & automation.

What are the Azure DevOps Branch Policies & Security?

Azure DevOps Branch Policies and Security help teams protect their source code, enforce quality, and control how changes reach important branches like main, master, or release.

So What Are Branch Policies?

Branch Policies in Azure DevOps define rules that must be met before code can be merged into a protected branch.

For Example:

Require Minimum Reviewers, Check for Linked Work Items, Require Successful Build Validation (CI Pipeline), Require Passed Status Checks, Limit Merge Types, and Automatically Add Reviewers (via Code Owners / path filters). and more ...

How Branch Policies Work (Flow)

  • Developer creates a feature branch.

  • Opens a Pull Request (PR) to merge into main .

  • Branch Policies enforce:

    • Reviewers added

    • Build validation runs

    • Tests executed

    • Comments resolved Once all checks pass, PR can be merged.

This ensures code quality, testing, security, and traceability.

What is Branch Security in Azure DevOps?

Security determines who can read, write, push, delete, or configure policies on a branch.

We will go through the implementation step by step.

Workflow Diagram

Azure DevOps Branch Protection Workflow Diagram

Implementing Steps

  • Go to this website: https://dev.azure.com/, then Login

  • Click New Project

  • Fill in:

    • Project name: FrogTech-Lab

    • Visibility: Private

    • Skip other settings (keep defaults)

  • Click Create

image

Now you have a completely empty Azure DevOps project.

Step one is to create a Repository

  • Go to Repos (left sidebar)

  • Azure DevOps will automatically create a repo for you called FrogTech-Lab as your project's name if not:

    • Click New Repository

    • Name: frogtech-repo

    • Click Create

Now your repo exists, but still empty.

So Step two is to create basic files, so your repo is not empty.

  • In Repos, click New, then File

  • File name: README.md

  • Content: write anything (example: # FrogTech Repository)

  • Click Commit

The main branch now exists.

Step 3 is to create a user group, like Tech Lead + DevOps team, and this is important because we will apply permissions later.

  • Go to Project Settings (bottom-left)

  • Click Permissions

  • Click New Group

    • Group name: Tech-Leads

    • Add your account inside (so you can act as Tech Lead)

  • Click New Group again:

    • Group name: DevOps-Team

    • Add your account inside (so you can act as DevOps too)

image

💡Tip

For the lab, you can add yourself to all groups. In real life, these would be actual people.

Step 4 is to create the branch-name validation pipeline. This is the pipeline that will enforce correct naming.

  • Go to Pipelines

  • Click New Pipeline

  • Choose Azure Repos Git (YAML)

  • Select your repository

  • Choose Starter Pipeline

  • Replace everything with this YAML:

trigger: none

pr:
  branches:
    include:
      - "*"

pool:
  vmImage: ubuntu-latest

steps:
  - bash: |
      echo "🔍 Validating PR source branch..."
      BRANCH="$(System.PullRequest.SourceBranch)"
      BRANCH="${BRANCH#refs/heads/}"
      echo "Detected branch name: $BRANCH"

      REGEX="^(feat|fix|chore|refactor|docs|test)/[0-9]{5,7}-[a-z0-9._-]+$|^release/[0-9]+\.[0-9]+\.[0-9]+$"

      if [[ ! "$BRANCH" =~ $REGEX ]]; then
        echo "❌ Invalid branch name"
        exit 1
      fi

      echo "✔ Valid branch name"
    displayName: "Validate PR branch name"
  • Click Save

  • Name the pipeline: PR-BranchName-Validation for example

  • Commit to main

Pipeline is now created.

The next step is to configure branch policies on main. You will now enforce PR-only merges, Tech Lead required reviewer, Developer cannot approve own PR, and Branch naming validation pipeline must pass

So here's how:

  • Go to Repos then Branches

  • On the main branch row, click the three dots (…)

  • Click Branch Policies

image

Now apply the following settings:

  • Turn ON:

    • Require a minimum number of reviewers → set to 1

    • Do not allow users to approve their own changes (OFF the toggle)

image

This enforces no direct push, and the author cannot approve their own PR

In the same screen:

  • Scroll to Automatically include reviewers

  • Click Add

  • Choose the Tech-Leads group

  • Save

image

Now, every PR MUST include the Tech Lead.

  • Scroll to Build validation

  • Click Add build policy

  • Select pipeline: PR-BranchName-Validation

  • Trigger: Automatic

  • Policy: Required

  • save

image

Now your PR fails if the branch name is wrong.

The step after is to deny direct pushes to main.

  • Go to Repos, then Branches

  • On main, click … then Branch security

  • Now configure:

    • For normal Project Contributors:

      • Find Contributors group then set:

        • Contribute → DENY

        • Force Push → DENY

        • Bypass Policies → DENY

image

This enforces PR-only merges.

  • For Tech-Leads group:

    • Contribute → allow

    • Bypass Policies → allow (optional, for emergencies only)

    • Force push → deny

  • For DevOps-Team

    • Contribute (Allow) → but this is overridden by Deny for main, so they can push to their own branches

    • Create branch (Allow)

Save.

Last step, giving the DevOps Team Repo-level Permissions, so allows DevOps to clone, create branches, push branches.

  • Go to Project settings, then Repositories

  • Choose your repo

  • Click Security

  • Find DevOps-Team

  • then set:

    • Contribute → Allow

    • Create branch → Allow

then save Now DevOps can create branches like: feat/12345-add-dashboard and push them, but cannot push to main.

Finally you can test by

  • Direct push to main. Create a commit on main locally then do git push origin main Expected: rejected

  • Create a branch named:

feat/332200-add_new_pipeline Push it then create a PR to main

Expected: Pipeline passes

another test is to PR from incorrect branch and it should fail

use branch like

feature/login

Issues encountered

Hosted agent issue

when trying to test PR from correct branch, it should succeed but actually, this error returns:

##[error]No hosted parallelism has been purchased or granted. To request a free parallelism grant, please fill out the following form https://aka.ms/azpipelines-parallelism-request
Pool: Azure Pipelines

After investigating the problem, I found that this error is normal when using Azure DevOps for the very first time. Azure DevOps pipelines cannot run until you enable or request parallel jobs.

Here’s the exact meaning of the error:

No hosted parallelism has been purchased or granted.

It means your Azure DevOps organization does not have permission to run Microsoft-hosted agents.

I found 2 different ways:

1- Solution 1 — Request Free Microsoft-hosted Parallelism Microsoft requires you to request free pipeline minutes the first time.

you can hit the link that is in the error https://aka.ms/azpipelines-parallelism-request and it will redirect you to the requesting page.

fill the form and at number 4 "Are you requesting a parallelism increase for Public or Private projects?" select private, Microsoft gives free parallelism for private projects if you request it through the form.

actually i follow this step but not helped me so i went to the solution 2 instead

2- Solution 2 — Use a Free Self-Hosted Agent (Instant Fix)

This bypasses Microsoft-hosted agents entirely.

  • Go to Organization, Settings, then Agent Pools

  • Click Default pool

  • Click New agent

  • Choose your OS (Windows, Linux, macOS)

  • Download the zip file

  • Follow the instructions on the page to configure the agent

Then, in your pipeline YAML, replace:

pool:
  vmImage: ubuntu-latest

with

pool:
  name: Default

Pipeline will now run on your machine, not Microsoft’s cloud.

[!tip] This is instant and works even if Microsoft-hosted agents are blocked.

After passing the Authentication

Screenshot 2025-12-12 161845

pipeline tried to run a bash command on your Windows self-hosted agent

Another issue, after configure host-based agent and when running a job it failed and this error returned:

The process 'C:\WINDOWS\system32\bash.exe' failed with exit code 1

This error means that the pipeline tried to run a bash command on your Windows self-hosted agent, but Windows can't run Linux-style bash commands unless you have WSL (Windows Subsystem for Linux) installed.

As we wrote the pipeline in bash in case we should use ubuntu hosted agent, but after we changed the hosted agent to our local machine, Windows OS, we need WSL (Ubuntu on Windows) installed.

After solving the issue, It works with me now as you see a successful job in the image below:

Screenshot 2025-12-12 182045

Thanks for reading.

References

  • https://eraki.hashnode.dev/locking-down-your-code-a-guide-to-azure-devops-branch-policies-and-security

  • https://learn.microsoft.com/en-us/azure/devops/repos/git/branch-permissions?view=azure-devops

  • https://learn.microsoft.com/en-us/azure/devops/repos/git/gitquickstart?view=azure-devops&tabs=visual-studio-2022

More from this blog

Youssef Blog

12 posts

Cloud & DevOps Engineer, AWS, Linux Sysadmin, Terraform, Kubernetes, Bash & Python scripting, Passionate about DevOps, automation and continuous self-improvement, being a DevOps Expert is my Aim.