Suppressing findings
A finding you have reviewed can be hidden three ways. Each keeps the reason in version control.
| Use | When |
|---|---|
.vulkro/triage.toml | One finding: false positive or accepted risk. |
| In-source comment | A line or file, with the reason next to the code. |
[[suppress]] in vulkro.toml | A rule or a path across the repository. |
To see everything that is hidden, run with VULKRO_NO_SUPPRESS=1.
Triage file
.vulkro/triage.toml holds decisions keyed by finding id. Every surface reads it (the CLI, the local console, the VS Code extension, the MCP server), so a finding marked once disappears everywhere. The console and the extension write it for you; vulkro explain <ID> prints an entry ready to paste.
schema = 1
[[finding]]
id = "js-taint-sql-001:3ad26e6c1266780c"
rule = "js-taint-sql-001"
file = "src/routes/users.js"
status = "false_positive" # open | confirmed | false_positive | accepted_risk | fixed
reason = "Table name comes from a fixed allowlist."
expires = "2026-12-31" # optional
false_positive and accepted_risk need a reason. Commit the file and make sure git does not ignore it.
In-source comments
// vulkro:disable next-line <rule-id>[, <rule-id>, ...]
// vulkro:disable-line <rule-id>
// vulkro:disable-file <rule-id>
// vulkro:disable-file (every rule in the file)
/* vulkro:disable next-line <rule-id> */
<!-- vulkro:disable next-line <rule-id> -->
// vulkro:disable next-line cors-wildcard reason="public read-only API"
app.use(cors({ origin: "*" }));
Use # in Python. The rule id is the detector slug (for example cors-wildcard) or an OWASP code (API1); * means every rule. A directive inside a string literal is ignored. The scan prints how many findings comments suppressed.
Repo-wide suppressions in vulkro.toml
[[suppress]]
rule = "literal-string-secret" # exact rule slug, or a full <rule>:<hash> id
path = "tests/**"
reason = "test fixtures"
expires = "2026-12-31" # optional review date
rule must match exactly. Get the slug from vulkro explain <ID> or the rule field in JSON. An entry with only path hides everything under that glob. After expires, the entry stops matching and the scan warns.
Team policy (org-wide enforcement)
[team_policy]
require_suppression_reason = true
require_suppression_expiry = true
max_suppression_days = 90
[team_policy.quality_gate]
max_critical_findings = 0
fail_on_new_high = true
An entry that breaks the policy is not applied, and the scan says why. Gate floors merge with [quality_gate] (the stricter wins) and run on every scan, exiting 1 on a breach.
See also: Baselines, vulkro explain