mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-18 06:23:18 +00:00
feat: purge scan data for deleted images and stacks (#1467)
Vulnerability scan rows were never cleaned up when their image was removed from Docker or their stack was deleted, so the Security Overview (including the Top exploit-risk findings card) kept surfacing findings for artifacts that no longer exist. Scan results now reflect what is still on the host: - Deleting a stack immediately purges its stack:<name> compose-config scan. - A background reconciliation in the monitor janitor removes scans whose image is gone from the node, or whose stack folder no longer exists. It is fail-safe: a scan is only removed when its artifact is positively known to be gone, the Docker image list is read with a timeout (skipped on failure), and stack scans are reconciled only when the stack list is non-empty. - An opt-out "Remove scans for deleted images and stacks" setting (on by default, per-node) lets operators retain scan history for removed artifacts. Scan deletes remove child findings explicitly, since SQLite foreign-key cascade is not enabled on the connection.
This commit is contained in:
@@ -25,6 +25,7 @@ const ALLOWED_SETTING_KEYS = new Set([
|
||||
'audit_retention_days',
|
||||
'mesh_auto_recreate',
|
||||
'scan_history_per_image_limit',
|
||||
'prune_orphaned_scans',
|
||||
'prune_on_update',
|
||||
'reclaim_hero',
|
||||
'snapshot_documentation',
|
||||
@@ -54,6 +55,7 @@ const SettingsPatchSchema = z.object({
|
||||
audit_retention_days: z.coerce.number().int().min(1).max(365).transform(String),
|
||||
mesh_auto_recreate: z.enum(['0', '1']),
|
||||
scan_history_per_image_limit: z.coerce.number().int().min(5).max(1000).transform(String),
|
||||
prune_orphaned_scans: z.enum(['0', '1']),
|
||||
prune_on_update: z.enum(['0', '1']),
|
||||
reclaim_hero: z.enum(['0', '1']),
|
||||
snapshot_documentation: z.enum(['0', '1']),
|
||||
|
||||
@@ -1047,6 +1047,7 @@ stacksRouter.delete('/:stackName', async (req: Request, res: Response) => {
|
||||
DatabaseService.getInstance().deleteStackExposureIntents(req.nodeId, stackName);
|
||||
DatabaseService.getInstance().deleteStackExposure(req.nodeId, stackName);
|
||||
DatabaseService.getInstance().deleteStackProjectEnvFiles(req.nodeId, stackName);
|
||||
DatabaseService.getInstance().deleteStackScans(req.nodeId, stackName);
|
||||
if (debug) console.debug(`[Stacks:debug] Delete: db OK`, { stackName: sanitizedName });
|
||||
} catch (dbErr) {
|
||||
console.error('[Stacks] Database cleanup failed for %s; files already removed:', sanitizeForLog(stackName), dbErr);
|
||||
|
||||
Reference in New Issue
Block a user