Safeguard
Application Security•

How do you run SAST in Azure DevOps without slowing every pull request?

Add SAST to Azure DevOps with scoped pull request scans, a full main branch scan and a build validation policy. Decide what blocks a merge first.

Safeguard Security Team
5 min read

To run static application security testing (SAST) in Azure DevOps, add a pipeline that runs your scanner as a step, attach it to the target branch as a build validation policy, scan changed code on pull requests, and run a full scan on the main branch on a schedule. Decide what blocks a merge before you switch the gate on.

What do you need to know about SAST first?

OWASP's source code analysis tools page describes SAST as analyzing source code or compiled code to find security flaws, and says it can run inside your IDE. Its strengths: it scales and can be run repeatedly, as in nightly builds or continuous integration; it finds well-known flaws such as buffer overflows and SQL injection; and it points developers to file, line and code snippet.

Its weaknesses matter for gate design. OWASP says current tools can identify only a relatively small percentage of application security flaws, produce many false positives, usually cannot find configuration issues because those are not in the code, and have difficulty with code that cannot be compiled. It also lists authentication problems, access control issues and insecure use of cryptography as hard for automation to find.

NIST's Secure Software Development Framework (SP 800-218) gives the wider reason to bother: a core set of high-level secure development practices, added to whatever life cycle you use, meant to reduce vulnerabilities in released software and address root causes so they do not recur.

Which Azure DevOps pieces are involved?

Microsoft's documentation describes Azure Pipelines as the part of Azure DevOps that combines continuous integration, testing and delivery. A pipeline is usually defined in an azure-pipelines.yml file in the repository, and a script step runs a script with cmd.exe on Windows and Bash on other platforms. The script step has properties including failOnStderr, continueOnError and condition, which you can use to control whether a scanner failure stops the build.

The gate is a branch policy. In the Azure DevOps branch policy documentation, build validation lets you choose a build pipeline, an optional path filter, a trigger of automatic or manual, and a policy requirement of Required or Optional. If it is Required, the build must complete successfully before the pull request can complete. Optional only notifies on failure. You can also set a build expiration so that updates to the protected branch do not break changes in open pull requests.

How should you structure it?

Three scans, three jobs:

  1. Pull request scan. Fast and scoped: analyze changed files, or the whole repository if the tool is quick. Start as Optional, so developers see results without being blocked while you tune.
  2. Main branch scan. Full analysis after merge. Results become tickets, not blockers.
  3. Scheduled scan. A nightly or weekly run on the main branch with the most thorough rules, plus an update of your baseline.

A constructed example: a team of 30 developers turns on a SAST step as a Required build policy on day one. The first run finds 900 issues in old code, and half the pull requests turn red for reasons unrelated to the change. Developers add the skip comment everywhere within a week. A better path would have been to record the 900 as a baseline, show only new findings on pull requests, set the policy to Optional for two weeks, and make it Required only for new high-confidence findings.

What should block a merge?

Choose a narrow rule at first: new findings, high severity, high confidence, in changed code. Everything else goes to a backlog with an owner. Review the false positive rate every two weeks, and tighten the rules when developers trust the results.

How to check or apply this

  1. Pick a scanner that supports your languages, and run it locally on one repository to see the output and run time.
  2. Write a script in the repository that runs the scan, writes results to a file, and returns a failure only for the new, high-severity findings you chose.
  3. Add a pipeline file that calls the script in a script step, with a condition so it runs on pull requests and on the main branch.
  4. Create a baseline from the first full run, and filter known findings out of the pull request view.
  5. Add the pipeline as a build validation policy on the main branch. Choose Optional for the first two weeks, with a path filter if the repository holds several projects.
  6. Switch to Required once the false positive rate is acceptable, and set a build expiration.
  7. Limit who can edit the pipeline file and the policy, since removing the check is the easiest way around the gate.
  8. Pair SAST with dependency checks and, for running apps, dynamic testing.

Quick check

Should SAST fail the build on every finding?

No. Because of false positives and legacy code, start by failing only on new, high-confidence, high-severity findings, and send the rest to a backlog.

Can a developer bypass the check?

If they can edit the pipeline file or the branch policy, yes. Protect both with permissions and review.

Sources

Last reviewed: 18 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.