The mission: recurring vulnerability assessment across C# and TypeScript codebases, enforced automatically — a PR with a new critical finding cannot merge. No security review meetings, no spreadsheets.
[ PIPELINE PARAMS ]
- SCANNER
- SonarCloud (SAST + quality gate)
- CI
- Azure DevOps multi-stage YAML
- LANGUAGES
- C# (.NET) · TypeScript
- GATE
- new criticals = merge blocked
- CADENCE
- every PR + nightly full scan
#Pipeline Flow
PR opened ──▶ build ──▶ unit tests ──▶ SONAR SCAN
│
quality gate PASS? ── no ──▶ ✖ MERGE BLOCKED
│ (finding linked
yes in the PR)
▼
✔ MERGE ALLOWED ──▶ CD stages
#Step 1 — The Scan Stage
| |
#Step 2 — Make the Gate a Wall
A scan that only reports is decoration. Two switches make it enforcement:
- SonarCloud quality gate:
new_critical_violations = 0, coverage on new code ≥ 80%. - Azure DevOps branch policy: the
Analyzestage is a required status check onmain.
#Step 3 — Kill the Noise in Week One
The first scan on a real codebase produces hundreds of findings. Triage them once, aggressively:
// Exclusions are a security decision — document each one
sonar.exclusions = "**/migrations/**, **/*.generated.cs, **/vendor/**"
sonar.cpd.exclusions = "**/dto/**" // DTOs duplicate by design
sonar.issue.ignore.multicriteria = "e1" // reviewed 2026-03: false positive
#Results
| Metric | Before | After 90 days |
|---|---|---|
| Criticals reaching production | untracked | 0 |
| Mean fix time (critical) | weeks | inside the PR |
| Coverage on new code | — | ≥ 80% enforced |
| Security review meetings | weekly | 0 |