feat(security): fleet-replicated CVE suppression list (#650)

Operators can accept known-benign findings once and have Sencho filter
them out of scan drawers, comparison views, and other read surfaces.
Suppressions replicate from the control instance to every remote node.

* New cve_suppressions table with a COALESCE-based unique index so NULL
  scope slots collide the way users expect
* Admin + paid-tier CRUD routes; writes are rejected on replicas
* Read-time filter enriches vulnerability details and compare payloads
  without mutating stored counts
* Settings > Security panel for managing rules, per-CVE suppress action
  in the scan drawer, dimmed rows with a shield-off indicator
* Vitest unit tests for the filter (glob, expiry, specificity) and
  route tests (auth, tier, replica, UNIQUE conflict)
This commit is contained in:
Anso
2026-04-17 05:16:34 -04:00
committed by GitHub
parent 708d15b2b3
commit 732fc95415
16 changed files with 1568 additions and 41 deletions
+20 -1
View File
@@ -53,6 +53,22 @@ export interface VulnerabilityDetail {
title: string | null;
description: string | null;
primary_url: string | null;
suppressed?: boolean;
suppression_id?: number;
suppression_reason?: string;
}
export interface CveSuppression {
id: number;
cve_id: string;
pkg_name: string | null;
image_pattern: string | null;
reason: string;
created_by: string;
created_at: number;
expires_at: number | null;
replicated_from_control: number;
active: boolean;
}
export interface ScanSummary {
@@ -92,6 +108,9 @@ export interface ScanCompareVulnerability {
installed_version?: string;
fixed_version?: string | null;
primary_url?: string | null;
suppressed?: boolean;
suppression_id?: number;
suppression_reason?: string;
}
export interface ScanCompareResult {
@@ -99,5 +118,5 @@ export interface ScanCompareResult {
scanB: { id: number; scanned_at: number; image_ref: string };
added: ScanCompareVulnerability[];
removed: ScanCompareVulnerability[];
unchanged: Pick<ScanCompareVulnerability, 'vulnerability_id' | 'pkg_name' | 'severity'>[];
unchanged: ScanCompareVulnerability[];
}