Quality Gate
The Primus Quality Gate lets you define fine-grained pass/fail thresholds for security scans — similar to SonarQube Quality Gates but local, config-file driven, and zero-egress.
How it works
After a ScanAsync() call, the scanner evaluates your configured thresholds against the findings. The result is attached to ScanResult.QualityGate and a QualityGateStatus string ("PASSED" or "FAILED") is available at the top level.
Configuration
In appsettings.json:
{
"PrimusSecurity": {
"QualityGate": {
"MaxCritical": 0,
"MaxHigh": 0,
"MaxMedium": 5,
"MaxLow": -1,
"MaxSecrets": 0,
"MaxCriticalDependencies": 0,
"MaxUnreviewedHotspots": -1,
"BlockOnNewSecrets": true
}
}
}
A value of -1 disables that threshold (no limit). The defaults block on any Critical or High finding and on any hardcoded secret.
Preset gates
// Block on any Critical or High + zero secrets
services.AddPrimusSecurity(opts =>
{
opts.QualityGate = QualityGate.Strict;
});
// Never fail — for informational / exploratory scans
services.AddPrimusSecurity(opts =>
{
opts.QualityGate = QualityGate.InfoOnly;
});
Reading the result
var scanResult = await scanner.ScanAsync("/path/to/project");
Console.WriteLine($"Quality Gate: {scanResult.QualityGateStatus}");
// → "PASSED" or "FAILED"
var gate = scanResult.QualityGate;
if (!gate.Passed)
{
foreach (var violation in gate.Violations)
Console.Error.WriteLine(violation);
// → "Quality gate failed: 2 Critical vulnerabilities found (threshold: 0)."
// → "Quality gate failed: 1 hardcoded secret(s) detected — zero tolerance enforced."
}
// Counts always available
Console.WriteLine($"Critical: {gate.CriticalCount}, High: {gate.HighCount}");
CI integration
// Program.cs — fail the process on gate failure
var result = await scanner.ScanAsync(args[0]);
Console.WriteLine(result.QualityGateStatus);
if (result.QualityGate?.Passed == false)
{
foreach (var v in result.QualityGate.Violations)
Console.Error.WriteLine(v);
return 1; // non-zero exit → CI pipeline fails
}
return 0;
See the CI/CD Integration guide for GitHub Actions and Azure DevOps templates.
Threshold reference
| Field | Type | Default | Description |
|---|---|---|---|
MaxCritical | int | 0 | Max Critical severity findings. 0 = any fails. -1 = no limit. |
MaxHigh | int | 0 | Max High severity findings. |
MaxMedium | int | -1 | Max Medium findings. -1 by default. |
MaxLow | int | -1 | Max Low findings. |
MaxSecrets | int | 0 | Max secret findings. Always 0 — secrets must be zero. |
MaxCriticalDependencies | int | 0 | Max Critical CVE dependency findings. |
MaxUnreviewedHotspots | int | -1 | Max unreviewed Security Hotspots. Hotspots require human triage. |
MaxDuplicateBlocks | int | -1 | Max duplicated code blocks (Phase 7). Requires EnableDuplicationDetection = true. -1 = disabled. |
BlockOnNewSecrets | bool | true | Always fail if any secret is found, regardless of MaxSecrets. |
Disabled | bool | false | Skip gate evaluation entirely — scan always passes. |
Suppression store
The .primus-suppressions.json file is a persistent triage store — suppressions recorded here survive between scans and carry a full audit trail.
{
"suppressions": [
{
"ruleId": "PS-SEC-001",
"fingerprint": "PS-SEC-001|Controllers/UserController.cs|42",
"status": "accepted",
"reason": "tableName is an internal enum, not user input",
"author": "akki@primussoftware.com",
"date": "2026-03-01"
}
]
}
Enable it in options or via CLI:
// appsettings.json
{ "PrimusSecurity": { "SuppressionsPath": ".primus-suppressions.json" } }
primus-scan ./MyApp --suppressions .primus-suppressions.json
Accepted findings are excluded from quality gate counts but remain visible in reports for audit trail purposes — matching SonarQube Developer Edition behaviour.
A–E security ratings
Every ScanResult now includes Ratings — a SonarQube-style letter grade:
var result = await scanner.ScanAsync("./MyApp");
Console.WriteLine(result.Ratings?.Security); // A, B, C, D, or E
Console.WriteLine(result.Ratings?.Reliability);
Console.WriteLine(result.Ratings?.Maintainability);
| Rating | Condition |
|---|---|
| A | 0 active vulnerabilities |
| B | ≥1 Low finding |
| C | ≥1 Medium finding |
| D | ≥1 High finding |
| E | ≥1 Critical finding |
Ratings are also included in SARIF output as securityRating, reliabilityRating, and maintainabilityRating properties — readable by CI scripts without parsing the full results list.