CVE Policy Reference¶
settings.json → "cve_policy" maps each CVE severity level to an action.
This page is the terse lookup reference — for the workflow and reasoning
behind these choices, see CVE workflow.
Severity levels¶
Severity strings come from Grype's own vocabulary. cve_policy keys are the
lowercase form.
| Grype severity | cve_policy key |
Default action |
|---|---|---|
Critical |
critical |
block |
High |
high |
review |
Medium |
medium |
warn |
Low |
low |
allow |
Negligible |
negligible |
allow |
Unknown |
(not a policy key) | treated as allow — any severity absent from cve_policy defaults to allow |
The four actions¶
| Action | Meaning |
|---|---|
block |
Immediate rejection. The package is quarantined and never reaches storage/the distribution. |
review |
The package is accepted into storage but held back from being published/served (cve_status/manifest status = "pending_review") until an RSSI approves or rejects it via POST /security/packages/{name}/{version}/decide. |
warn |
The package is accepted and published normally. The CVE is recorded and visible, but nothing blocks the flow. |
allow |
Transparent — no visible warning, no action. |
Action per scan mechanism¶
cve_policy is evaluated by four independent mechanisms, at different points
in a package's lifecycle. They don't all honor block the same way.
| Mechanism | Where | block |
review |
warn |
allow |
|---|---|---|---|---|---|
| First-party Grype scan (upload/import) | services/validator_apt.py:_apply_cve_policy() (shared by RPM/APK/Maven/PyPI/npm/OCI, which all call the same function) |
cve_status = "blocked", validation fails, file quarantined |
cve_status = "pending_review" — lands in pool-equivalent storage but not published (not indexed by reprepro/createrepo_c/APKINDEX, hidden from Maven/PyPI/npm listings) |
cve_status = "approved", published normally, warning recorded in validation_steps |
cve_status = "approved", no action |
Dependency CVE scan (npm/Maven/PyPI declared dependencies, services/osv_lookup.py:worst_dependency_action()) |
Evaluated inside finish_npm_publish()/finish_maven_deploy()/finish_pypi_upload(), after the package's own Grype scan already ran |
downgraded to review — never an outright rejection |
pending_review, same RSSI queue |
recorded, doesn't change status | no action |
Dual scan (Grype + Trivy cross-check, SaaS only, services/dual_scan.py:_worst_action_for()) |
Only evaluated for CVEs with detected_by == ["trivy"] (Trivy found it, Grype's original scan missed it) on an already-validated package |
downgraded to review — never an outright rejection or unpublish |
flips manifest status to pending_review, same RSSI queue |
no status change | no action |
CVE re-match (periodic re-scan via stored SBOM, all 7 formats, services/cve_rematch.py:rematch_one()) |
Only evaluated for CVE IDs newly appeared since the last scan (newly_appeared = new_ids - old_ids) on an already-validated package |
routes to pending_review, same as review — never an outright unpublish/reject |
flips manifest status to pending_review, same RSSI queue |
no status change | no action |
Only the first-party Grype scan can ever block outright
Dependency scan, dual scan, and CVE re-match all run after a package
is already published or stored — none of them can retroactively reject a
package. A block-severity match found by any of the three retroactive
mechanisms is instead treated as review, routing to the same RSSI
decision queue (decision_records) as a native review finding.
A previously-known CVE that disappears never re-triggers a decision
Both dual scan and CVE re-match only evaluate new findings against
cve_policy — a CVE that stops matching (engine DB correction, or Trivy
simply not flagging it a second time) is removed from the displayed list
without ever reopening a review.
RSSI decision queue¶
Every mechanism that routes to pending_review uses the same underlying
table, decision_records, and the same endpoint:
Possible decisions: accept_risk, exception, reject, upgrade_required —
see CVE workflow for the full decision
lifecycle and SLA tracking.
SLA fields¶
cve_policy also carries remediation SLA deadlines (days), used by the
sla_check_daily cron job:
| Key | Default | Meaning |
|---|---|---|
sla_critical_days |
0 |
Days allowed for a Critical finding — 0 means immediate/blocked, no grace period. |
sla_high_days |
30 |
Days allowed for a High finding pending decision. |
sla_medium_days |
90 |
Days allowed for a Medium finding pending decision. |
Configuring cve_policy¶
Via the web UI: Settings → Security → CVE Policy (admin role required).
Via the API: