Guide

Branch policies as code in Azure DevOps

Learn how to set, check and review changes to branch policies in Azure DevOps consistently using the CLI or REST API.

Branch policies as code in Azure DevOps can be managed as declarative configuration rather than only being set by clicking through the UI. For Azure Repos, Microsoft points to the az repos policy commands and the REST API for this; source: Microsoft Learn, “Branch policies” and “Securely use Git pull requests and branch policies to protect your important branches”, accessed on 01/11/2026.

A branch policy is a rule for a target branch such as main. A target branch is the branch into which a pull request is intended to be merged.

In practice, this is particularly useful when you do not want to maintain rules separately for each repository. It makes changes more traceable, more repeatable and easier to integrate into a review process.

This article looks at Azure DevOps Services. It focuses on three practical questions:

  • when the CLI is sufficient,
  • when the REST API is a better fit,
  • and how to identify deviations from a desired baseline.

Why configure policies as code

The starting point is fairly straightforward: in Azure Repos, branch policies for the minimum number of reviewers, linked work items, comment resolution, allowed merge types, build validation, status checks and automatically included reviewers are each switched off by default. Microsoft Learn documents this in “Branch policies overview” and “Branch policies”, accessed on 01/11/2026.

That is exactly why an “as code” or declaratively maintained configuration approach is worthwhile. You can roll out the same rules consistently across many repositories, track changes through pull request review, and reapply the desired baseline after creating new projects instead of clicking through every setting in the UI again.

For main, the governance aspect is usually the most important one. In its security baseline, Microsoft recommends, among other things:

  • restricting permissions to bypass policies when completing pull requests and when pushing directly to a small admin group,
  • requiring at least two reviewers,
  • automatically including reviewers for sensitive paths,
  • checking for linked work items,
  • setting build validation,
  • and requiring comment resolution.

The source here is Microsoft Learn, “Securely use Git pull requests and branch policies to protect your important branches”, accessed on 01/11/2026. If you want to define the point about exceptions properly, the article on bypass permissions is the obvious next step.

It is also important to classify merge types correctly: according to Microsoft, this setting is for history governance, not a direct security control. If your audit model depends on the exact commit sequence, Microsoft recommends merge commit strategies rather than squash; same source: “Securely use Git pull requests and branch policies to protect your important branches”, accessed on 01/11/2026.

Policies as code also help prevent projects from quietly drifting apart. If one repository has a required status check and another does not, this often only becomes apparent late on in the UI. If you would first like to understand the individual policy types and their effects in more detail, read the branch policies explained.

The az repos policy commands at a glance

Closed laptop, cogwheel and branching line with nodes as a symbol for policy commands.

The az repos policy commands are especially suitable when you want to set or change policies in a targeted way without first building your own tool for the job. What is meant here is the Azure DevOps CLI: a command-line extension that lets you script Azure DevOps functions.

This is practical for recurring standard cases, for example:

  • bringing a new repository up to a defined minimum standard,
  • rolling out the same policy types repeatedly for a target branch,
  • or making controlled adjustments to individual settings following an internal change decision.

The benefit lies less in “more functionality” than in clear execution. You pass known parameters, run the step reproducibly and can slot it into existing operating processes. For teams with many similar repositories, this is often the simplest way to get started with policies as code.

The CLI is less suitable if your desired target state first has to be assembled from several sources or if you want to assess deviations systematically. As soon as inventory, cross-comparison or your own approval logic come into play, working through the REST API is usually the better fit.

That is why it makes sense to keep the CLI tightly scoped:

  • set standards,
  • roll out clearly named changes,
  • log results,
  • and handle exceptions consciously and separately.

That keeps the command-based approach manageable and maintainable instead of gradually moving half a governance system into scripts.

REST API as an alternative

The REST API becomes interesting as soon as your policy management forms part of a broader operating model. At that point, it is no longer just about setting individual rules, but about reading, comparing and updating in a targeted way. Microsoft explicitly refers to the REST API for this in Microsoft Learn, “Branch policies” and “Securely use Git pull requests and branch policies to protect your important branches”, accessed on 01/11/2026.

One practical advantage is the complete capture of the current state. You can inventory policies across projects and repositories and derive a reliable comparison with your desired state from that. Here, inventory means systematically recording existing settings instead of only checking them selectively in the UI.

This is particularly suitable if you need to answer questions such as:

  • Which repositories deviate from the baseline?
  • Where is a particular policy type still missing entirely?
  • Which settings were changed outside the intended change path?
  • Which projects deliberately require an exception because they need a different level of protection?

The API is also useful when you want to analyse the finer points of individual policies in a targeted way. According to Microsoft Learn, “Branch policies”, accessed on 01/11/2026, the reviewer policy includes options such as “Allow requestors to approve their own changes”, “Prohibit the most recent pusher from approving their own changes” and “Require at least one approval on the last iteration”. In practice, these details often determine the real effect more strongly than simply noting that a reviewer policy exists.

From an operational perspective, the REST API is therefore less a replacement for good standards than a tool for transparency, analysis and controlled change.

Drift detection and review of changes

Magnifying glass over offset cards next to a branching line as a symbol for drift detection and review.

The right target state is not to set policies once and then forget about them. A more sensible model is one in which you check regularly against a defined desired state. Here, “drift” means the deviation between the desired configuration and the configuration actually in place.

A practical workflow consists of three steps:

  • read the current state,
  • compare it with the baseline,
  • and feed deviations into a review process in a traceable way.

For this desired state, a versioned description by repository class or protection level works well. Typical scopes include main, release branches or repositories with particularly sensitive code paths. Versioned here means that the desired configuration is maintained in a traceable state so that changes remain clearly understandable later on.

The topic only really becomes reviewable once UI changes are no longer the normal case. It is better to make adjustments to the baseline by pull request. That way, platform, security and repository owners can see together what protective effect is changing and which exception has been deliberately approved.

Particular attention should be paid to options whose effect is easy to overlook in the UI. In “Branch policies”, accessed on 01/11/2026, Microsoft mentions details such as whether at least one approval on the last iteration is required after new pushes or whether all approvals are reset.

In this model, comment resolution should also not be understood merely as a policy being set, but as a separate check before completing a pull request. Microsoft Learn names this policy type in “Branch policies overview”, accessed on 01/11/2026. Open review threads are therefore not simply “a bit more discussion still to be had”, but a visible part of your merge check.

If you also use PR status values, keep technical checks clearly separate from reviewer votes: human approvals remain human approvals, and machine results belong in status checks.

Common questions you might ask about this

Is a comment function enough as a mandatory check in a pull request?

No. In operational terms, what matters is not whether something is called “review”, but whether Azure Repos can evaluate it as a policy. A comment function provides hints in the pull request, but it neither replaces a required approval nor automatically creates a blocking status.

For a reliable separation, a simple model helps:

  • people give review votes,
  • technical checks report status,
  • discussions are cleared up before completion.

If you want to establish this separation properly in your process, the article on using PR status as a policy is the right next step.

How do you keep the pull request workflow clean organisationally as well?

A workflow that creates order before the actual review begins is useful. This includes drafts for unfinished changes, properly prepared pull requests and a visible way of dealing with open discussions. A draft is a pull request that is not yet intended for substantive review.

In practice, three questions are helpful here:

  • Is the change actually ready for review?
  • Is the purpose of the pull request clearly described?
  • Have open threads really been dealt with?

For this, the articles on draft pull requests, creating pull requests properly and open threads before completion are a good fit.

When do service hooks make sense instead of additional policies?

Whenever you want to feed events from pull requests into other workflows. A service hook is an event notification that Azure DevOps triggers for certain changes.

This is especially useful for downstream responses such as notification, documentation or handing over to your own validation pipelines. For context, see the article on service hooks for pull requests.

What else needs to be checked for agentic PR automation?

This quickly raises issues around data protection, commissioned processing, DORA, NIS2 and co-determination. You should review these questions with your legal department or data protection officer.

If you would like to keep an eye on an emerging approach for Azure DevOps Services: Polier by ballmüller solutions is in development and not yet available. The current state described in each case can be found on the security and data page, the packages and sign-up page, the page for future metrics and in the public changelog.

Next step

Do not start with all repositories at once. A small, binding standard for a few branch classes is more sensible, one that you describe clearly in technical terms and assign clear organisational ownership to.

A short working framework has proved effective for this:

  • define the protected branch and the exception group,
  • allow policy changes only through a governed change path,
  • name the responsibilities for review and approval,
  • check the effectiveness of the baseline at fixed intervals.

This turns individual switches in Azure Repos into a maintainable operational asset.

If you are monitoring agentic PR automation in Azure DevOps Services, the position as of 01/11/2026 is: Polier by ballmüller solutions is in development and not yet available.

All guides