mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-22 16:16:41 +00:00
feat: add posture reasons and review queue to Security overview (#1462)
Add structured posture reasons derived alongside the posture verb in securityPosture.ts so the masthead and Overview tab can answer why the page is red, what to do first, and what clears it. Backend: - derivePostureReasons() returns blocker, review, and info reasons from the same SecurityPostureFacts used by deriveSecurityPosture() - deriveSecurityPosture() depends on derivePostureReasons() internally - Exposure split: public exposure with KEV, fixable, or EPSS >= 0.1 is a blocker; exposure without any of those is a review item - Fully dismissed exposed images produce no posture reason - postureReasons and primaryAction returned by the overview endpoint Frontend: - ReviewQueueCard on the Overview tab with per-row CTAs for blockers - Action summary in masthead subtitle and desktop primary CTA button - Card gated on posture not being Unknown - Backward compatible with older remote nodes
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import type { SecurityTab } from '@/lib/events';
|
||||
|
||||
export type VulnSeverity = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'UNKNOWN';
|
||||
export type VulnScanStatus = 'in_progress' | 'completed' | 'failed';
|
||||
export type VulnScanTrigger = 'manual' | 'scheduled' | 'deploy' | 'deploy-preflight';
|
||||
@@ -230,6 +232,33 @@ export interface ScanCompareResult {
|
||||
* backend `SecurityPostureState`. */
|
||||
export type SecurityPostureState = 'Action needed' | 'Monitoring' | 'Secure' | 'Unknown';
|
||||
|
||||
/** Kinds of posture reason the backend can report. */
|
||||
export type PostureReasonKind =
|
||||
| 'fixable_cve'
|
||||
| 'known_exploited'
|
||||
| 'secret'
|
||||
| 'dangerous_compose'
|
||||
| 'public_exposure'
|
||||
| 'stale_scan'
|
||||
| 'failed_scan'
|
||||
| 'needs_review';
|
||||
|
||||
/** One structured reason explaining why the security posture is what it is. */
|
||||
export interface PostureReason {
|
||||
kind: PostureReasonKind;
|
||||
count: number;
|
||||
severity: 'blocker' | 'review' | 'info';
|
||||
label: string;
|
||||
description: string;
|
||||
targetTab: SecurityTab;
|
||||
}
|
||||
|
||||
/** Highest-priority action for the masthead CTA. */
|
||||
export interface PostureAction {
|
||||
label: string;
|
||||
targetTab: SecurityTab;
|
||||
}
|
||||
|
||||
/** Node-scoped security posture rollup for the Security page Overview. */
|
||||
export interface SecurityOverview {
|
||||
scannedImages: number;
|
||||
@@ -269,6 +298,11 @@ export interface SecurityOverview {
|
||||
posture?: SecurityPostureState;
|
||||
/** True when the bounded posture pass hit its row cap on this node. */
|
||||
posturePartial?: boolean;
|
||||
/** Structured reasons for the posture (blockers, review, info). Optional for
|
||||
* older remote nodes that do not report them. */
|
||||
postureReasons?: PostureReason[];
|
||||
/** Highest-priority action for the masthead CTA, or null when no blockers. */
|
||||
primaryAction?: PostureAction | null;
|
||||
}
|
||||
|
||||
/** Which detail tab the scan sheet opens on. Matches VulnerabilityScanSheet's tabs. */
|
||||
|
||||
Reference in New Issue
Block a user