Suppressions
Ignore rules that hide matching findings and inventory components, where they come from, how they expire, and the review, approve and reject actions.
A suppression (an “ignore” rule) hides the findings it matches from the findings list, reports and later scans. It also skips matching crypto and AI inventory components in vulnetix cbom and vulnetix aibom and in the console. Every rule is listed on Configuration › Suppression Policies (/resolve/suppression-policies).
A rule is anchored on what the finding is, not only on one row, so it keeps covering the copies the next scan writes. Withdrawing the rule reverses everything it did: the suppressed triage, the record of which findings it covered, and its VEX.
Where rules come from
sourceKind |
Made by |
|---|---|
console |
Ignore on a finding or inventory page, or POST /v1/suppressions |
bulk |
Bulk suppress on the findings list (POST /v1/findings/bulk/suppress) |
console with type false_positive |
Triaging a finding as false_positive. See Findings and triage. |
cli_ignore |
vulnetix ignore add |
cli, nosec |
Suppressions a scan reports, such as an inline nosec marker (nosec) or another CLI-side rule (cli) |
vex |
A false positive or won’t fix statement in an OpenVEX, CycloneDX VEX or CSAF VEX document you upload, or vulnetix vex apply --upload. A statement with a structured justification is active at once; one where only prose says so starts as reviewState=pending. A newer statement for the same vulnerability, product and repository replaces the older VEX rule. VEX never changes a rule a person made in the console or CLI. |
A VEX statement of not_affected or fixed changes the finding’s triage and makes no rule.
Types
suppressionType |
Label | Who sets it |
|---|---|---|
false_positive |
False positive | a person |
wont_fix |
Won’t fix | a person |
risk_accepted |
Risk accepted | a person (the CLI default) |
mitigated |
Mitigated | a person |
deferred |
Deferred | a person |
rego_rule |
Rule | the CLI, when the anchor is a rule id |
nosec |
nosec | the scanners |
The API stores any non-empty string; the console and CLI offer the values above.
Anchors and scope
A rule needs at least one anchor, or the request is 400 one of findingUuid, ruleId, targetValue or filePath is required.
| Field | Anchors on |
|---|---|
findingUuid |
One finding. You must own it (404 finding not found otherwise). |
ruleId |
A scanner rule id (the rego file id) or a finding id such as a CVE |
targetValue |
An inventory component: an algorithm SPDX id, a certificate subject, a purl or a model name. Used with category crypto or ai. |
filePath |
A file, optionally narrowed by lineNumber or lineRange (10-14) |
Narrowing fields: category (sast, secrets, iac, container, sca, license, malware, crypto, ai), repositoryFullName, branchName, githubRepositoryId, githubBranchName. A rule with no repository applies across the organisation.
ignoreDays sets an expiry that many days from now. Omitted, the rule does not expire.
Creating a rule
curl -sS -X POST https://www.vulnetix.com/api/site/v1/suppressions \
-H "Authorization: ApiKey $VULNETIX_ORG_ID:$VULNETIX_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"suppressionType":"risk_accepted","ruleId":"CVE-2024-3094","category":"sca","repositoryFullName":"acme/payments","reason":"Not shipped in the runtime image","ignoreDays":90}'
The response is {"suppression": {...}}, the full rule row. The same from the CLI:
vulnetix ignore add --finding CVE-2024-3094 --category sca --type risk_accepted \
--reason "Not shipped in the runtime image" --expires-in 90
vulnetix ignore (alias suppress) also has list, remove and sync. Rules are written to .vulnetix/memory.yaml and, when you are signed in, to your organisation.
Changing a rule
PATCH /v1/suppressions/{uuid} with an action:
action |
Allowed on | Effect |
|---|---|---|
extend |
any rule not pending review (409 if pending) | Reactivates the rule. ignoreDays sets a new expiry; reason replaces the reason. |
review |
any | Records you and the date as its last review |
deactivate |
any | Inactive. deactivatedReason is recorded. The findings it covered come back. |
approve |
reviewState=pending only (409 otherwise) |
Active, approved, applied |
reject |
reviewState=pending only (409 otherwise) |
Inactive, rejected |
Any other action is 400. DELETE /v1/suppressions/{uuid} removes the rule and what it applied; the audit entry for the deletion is kept.
Listing rules
GET /v1/suppressions returns up to 2000 rules, newest first.
| Parameter | Values |
|---|---|
findingUuid, category, repo, targetValue |
exact filters |
sourceKind |
console, cli, cli_ignore, nosec, vex, bulk (anything else is 400) |
reviewState |
pending, approved, rejected (anything else is 400) |
active=true |
live rules only |
unreviewed=true |
live rules never reviewed, plus every pending rule, oldest first |
Each row carries its anchors, its actor (actorKind, actorLabel, actorEmail, actorVerified), its provenance (sourceDocumentId, sourceStatementRef, gitCommit and so on), applicationCount (how many findings it covers now) and evidence, the identity chain behind the actor.
Governance
The compliance reports treat an active rule last reviewed more than a year ago as overdue and an active rule past its expiry as expired. Use review to record a review. Every create, review, approve, reject, apply and delete is in the audit feed (GET /v1/review/audit), which the Reviewers tab of /resolve/logs shows.