|
|
|
|
@@ -527,6 +527,285 @@ type IwoooSSecurityToolClosureMetric = {
|
|
|
|
|
tone: 'steady' | 'warn' | 'locked'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type IwoooSSecurityToolClosureSummary = IwoooSSecurityToolClosureReadbackResponse['summary']
|
|
|
|
|
type IwoooSSecurityToolClosureQueueEntry = IwoooSSecurityToolClosureReadbackResponse['next_executable_queue'][number]
|
|
|
|
|
|
|
|
|
|
const SECURITY_TOOL_CLOSURE_BOOTSTRAP_SUMMARY: IwoooSSecurityToolClosureSummary = {
|
|
|
|
|
source_readback_count: 8,
|
|
|
|
|
tool_track_count: 8,
|
|
|
|
|
p0_tool_track_count: 3,
|
|
|
|
|
source_ready_tool_track_count: 1,
|
|
|
|
|
closed_tool_track_count: 0,
|
|
|
|
|
partial_tool_track_count: 1,
|
|
|
|
|
missing_tool_track_count: 6,
|
|
|
|
|
total_ready_signal_count: 14,
|
|
|
|
|
total_required_signal_count: 42,
|
|
|
|
|
tool_source_readiness_percent: 33,
|
|
|
|
|
tool_runtime_closure_percent: 0,
|
|
|
|
|
tool_closure_percent: 0,
|
|
|
|
|
wazuh_expected_host_scope_count: 6,
|
|
|
|
|
wazuh_manager_registry_accepted_count: 6,
|
|
|
|
|
wazuh_registry_complete_count: 1,
|
|
|
|
|
wazuh_fim_vulnerability_alert_closed_count: 0,
|
|
|
|
|
wazuh_fim_vulnerability_alert_source_verifier_ready_count: 0,
|
|
|
|
|
wazuh_fim_vulnerability_alert_runtime_closed_count: 0,
|
|
|
|
|
wazuh_fim_vulnerability_alert_verifier_ready_count: 0,
|
|
|
|
|
wazuh_fim_vulnerability_alert_verifier_ready_signal_count: 5,
|
|
|
|
|
alert_receipt_observed_count: 0,
|
|
|
|
|
alert_receipt_accepted_count: 0,
|
|
|
|
|
alert_receipt_source_status: 'not_connected',
|
|
|
|
|
controlled_apply_preflight_ready_count: 1,
|
|
|
|
|
owner_review_packet_accepted_count: 1,
|
|
|
|
|
allowlisted_dry_run_result_ref_count: 1,
|
|
|
|
|
supply_chain_scan_closed_count: 0,
|
|
|
|
|
runtime_detection_closed_count: 0,
|
|
|
|
|
web_api_dast_closed_count: 0,
|
|
|
|
|
normalized_detection_schema_closed_count: 0,
|
|
|
|
|
controlled_apply_policy_active_count: 1,
|
|
|
|
|
controlled_apply_candidate_ready_count: 1,
|
|
|
|
|
owner_review_required_for_low_medium_high_count: 0,
|
|
|
|
|
runtime_execution_performed_count: 0,
|
|
|
|
|
secret_value_collection_allowed_count: 0,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const SECURITY_TOOL_CLOSURE_BOOTSTRAP_TRACKS: IwoooSSecurityToolClosureTrack[] = [
|
|
|
|
|
{
|
|
|
|
|
track_id: 'wazuh_detection_response',
|
|
|
|
|
priority: 'P0',
|
|
|
|
|
label: 'Wazuh detection and response',
|
|
|
|
|
tool_ids: ['wazuh'],
|
|
|
|
|
closure_state: 'partial_source_readiness_runtime_open',
|
|
|
|
|
closure_percent: 0,
|
|
|
|
|
source_readiness_state: 'source_readiness_incomplete',
|
|
|
|
|
source_readiness_percent: 83,
|
|
|
|
|
runtime_closure_state: 'partial_source_readiness_runtime_open',
|
|
|
|
|
runtime_closed: false,
|
|
|
|
|
ready_signal_count: 5,
|
|
|
|
|
required_signal_count: 6,
|
|
|
|
|
missing_signal_count: 1,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
execution_candidate_ready: false,
|
|
|
|
|
runtime_execution_performed: false,
|
|
|
|
|
owner_review_required: false,
|
|
|
|
|
critical_break_glass_required: false,
|
|
|
|
|
secret_value_collection_allowed: false,
|
|
|
|
|
next_executable_action: 'attach_incident_case_and_active_response_dry_run_receipts_without_runtime_gate',
|
|
|
|
|
required_verifier: 'wazuh_registry_fim_vulnerability_alert_receipt_post_verifier',
|
|
|
|
|
source_refs: ['apps/api/src/services/iwooos_wazuh_fim_vulnerability_alert_verifier.py'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
track_id: 'supply_chain_sbom_scan',
|
|
|
|
|
priority: 'P0',
|
|
|
|
|
label: 'Supply-chain SBOM and vulnerability scan',
|
|
|
|
|
tool_ids: ['trivy', 'syft', 'grype'],
|
|
|
|
|
closure_state: 'source_missing_runtime_open',
|
|
|
|
|
closure_percent: 0,
|
|
|
|
|
source_readiness_state: 'source_readiness_incomplete',
|
|
|
|
|
source_readiness_percent: 0,
|
|
|
|
|
runtime_closure_state: 'source_missing_runtime_open',
|
|
|
|
|
runtime_closed: false,
|
|
|
|
|
ready_signal_count: 0,
|
|
|
|
|
required_signal_count: 5,
|
|
|
|
|
missing_signal_count: 5,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
execution_candidate_ready: false,
|
|
|
|
|
runtime_execution_performed: false,
|
|
|
|
|
owner_review_required: false,
|
|
|
|
|
critical_break_glass_required: false,
|
|
|
|
|
secret_value_collection_allowed: false,
|
|
|
|
|
next_executable_action: 'attach_sbom_vulnerability_report_and_no_secret_output_guard',
|
|
|
|
|
required_verifier: 'sbom_vulnerability_artifact_post_verifier',
|
|
|
|
|
source_refs: ['docs/security/security-asset-control-ledger.snapshot.json'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
track_id: 'source_control_scorecard',
|
|
|
|
|
priority: 'P1',
|
|
|
|
|
label: 'Source-control hygiene scorecard',
|
|
|
|
|
tool_ids: ['openssf_scorecard', 'gitea_source_policy'],
|
|
|
|
|
closure_state: 'source_missing_runtime_open',
|
|
|
|
|
closure_percent: 0,
|
|
|
|
|
source_readiness_state: 'source_readiness_incomplete',
|
|
|
|
|
source_readiness_percent: 0,
|
|
|
|
|
runtime_closure_state: 'source_missing_runtime_open',
|
|
|
|
|
runtime_closed: false,
|
|
|
|
|
ready_signal_count: 0,
|
|
|
|
|
required_signal_count: 4,
|
|
|
|
|
missing_signal_count: 4,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
execution_candidate_ready: false,
|
|
|
|
|
runtime_execution_performed: false,
|
|
|
|
|
owner_review_required: false,
|
|
|
|
|
critical_break_glass_required: false,
|
|
|
|
|
secret_value_collection_allowed: false,
|
|
|
|
|
next_executable_action: 'map_branch_protection_dependency_update_and_build_policy_readback',
|
|
|
|
|
required_verifier: 'source_control_policy_scorecard_verifier',
|
|
|
|
|
source_refs: ['docs/evaluations/runtime_surface_inventory_latest'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
track_id: 'k8s_policy_attestation',
|
|
|
|
|
priority: 'P1',
|
|
|
|
|
label: 'Kubernetes policy and image attestation',
|
|
|
|
|
tool_ids: ['kyverno', 'cosign'],
|
|
|
|
|
closure_state: 'source_missing_runtime_open',
|
|
|
|
|
closure_percent: 0,
|
|
|
|
|
source_readiness_state: 'source_readiness_incomplete',
|
|
|
|
|
source_readiness_percent: 0,
|
|
|
|
|
runtime_closure_state: 'source_missing_runtime_open',
|
|
|
|
|
runtime_closed: false,
|
|
|
|
|
ready_signal_count: 0,
|
|
|
|
|
required_signal_count: 5,
|
|
|
|
|
missing_signal_count: 5,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
execution_candidate_ready: false,
|
|
|
|
|
runtime_execution_performed: false,
|
|
|
|
|
owner_review_required: false,
|
|
|
|
|
critical_break_glass_required: false,
|
|
|
|
|
secret_value_collection_allowed: false,
|
|
|
|
|
next_executable_action: 'stage_policy_check_mode_image_signature_and_exception_register',
|
|
|
|
|
required_verifier: 'k8s_policy_attestation_post_verifier',
|
|
|
|
|
source_refs: ['docs/security/host-service-config-inventory.snapshot.json'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
track_id: 'runtime_threat_detection',
|
|
|
|
|
priority: 'P1',
|
|
|
|
|
label: 'Runtime threat detection',
|
|
|
|
|
tool_ids: ['falco'],
|
|
|
|
|
closure_state: 'source_missing_runtime_open',
|
|
|
|
|
closure_percent: 0,
|
|
|
|
|
source_readiness_state: 'source_readiness_incomplete',
|
|
|
|
|
source_readiness_percent: 0,
|
|
|
|
|
runtime_closure_state: 'source_missing_runtime_open',
|
|
|
|
|
runtime_closed: false,
|
|
|
|
|
ready_signal_count: 0,
|
|
|
|
|
required_signal_count: 4,
|
|
|
|
|
missing_signal_count: 4,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
execution_candidate_ready: false,
|
|
|
|
|
runtime_execution_performed: false,
|
|
|
|
|
owner_review_required: false,
|
|
|
|
|
critical_break_glass_required: false,
|
|
|
|
|
secret_value_collection_allowed: false,
|
|
|
|
|
next_executable_action: 'stage_rule_dry_run_event_redaction_and_wazuh_correlation',
|
|
|
|
|
required_verifier: 'runtime_detection_event_post_verifier',
|
|
|
|
|
source_refs: ['docs/security/monitoring-alerting-observability-inventory.snapshot.json'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
track_id: 'web_api_dast',
|
|
|
|
|
priority: 'P1',
|
|
|
|
|
label: 'Web and API DAST',
|
|
|
|
|
tool_ids: ['owasp_zap_or_equivalent_dast'],
|
|
|
|
|
closure_state: 'source_missing_runtime_open',
|
|
|
|
|
closure_percent: 0,
|
|
|
|
|
source_readiness_state: 'source_readiness_incomplete',
|
|
|
|
|
source_readiness_percent: 0,
|
|
|
|
|
runtime_closure_state: 'source_missing_runtime_open',
|
|
|
|
|
runtime_closed: false,
|
|
|
|
|
ready_signal_count: 0,
|
|
|
|
|
required_signal_count: 5,
|
|
|
|
|
missing_signal_count: 5,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
execution_candidate_ready: false,
|
|
|
|
|
runtime_execution_performed: false,
|
|
|
|
|
owner_review_required: false,
|
|
|
|
|
critical_break_glass_required: false,
|
|
|
|
|
secret_value_collection_allowed: false,
|
|
|
|
|
next_executable_action: 'prepare_bounded_target_selector_rate_limit_and_baseline_report',
|
|
|
|
|
required_verifier: 'web_api_dast_scope_and_report_verifier',
|
|
|
|
|
source_refs: ['docs/security/ssh-network-access-inventory.snapshot.json'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
track_id: 'normalized_detection_schema',
|
|
|
|
|
priority: 'P1',
|
|
|
|
|
label: 'Normalized detection schema',
|
|
|
|
|
tool_ids: ['sigma', 'ocsf'],
|
|
|
|
|
closure_state: 'source_missing_runtime_open',
|
|
|
|
|
closure_percent: 0,
|
|
|
|
|
source_readiness_state: 'source_readiness_incomplete',
|
|
|
|
|
source_readiness_percent: 0,
|
|
|
|
|
runtime_closure_state: 'source_missing_runtime_open',
|
|
|
|
|
runtime_closed: false,
|
|
|
|
|
ready_signal_count: 0,
|
|
|
|
|
required_signal_count: 4,
|
|
|
|
|
missing_signal_count: 4,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
execution_candidate_ready: false,
|
|
|
|
|
runtime_execution_performed: false,
|
|
|
|
|
owner_review_required: false,
|
|
|
|
|
critical_break_glass_required: false,
|
|
|
|
|
secret_value_collection_allowed: false,
|
|
|
|
|
next_executable_action: 'normalize_wazuh_alertmanager_app_events_into_review_cards',
|
|
|
|
|
required_verifier: 'sigma_ocsf_event_mapping_regression_verifier',
|
|
|
|
|
source_refs: ['docs/security/iwooos-security-operating-system.snapshot.json'],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
track_id: 'ai_agent_controlled_apply',
|
|
|
|
|
priority: 'P0',
|
|
|
|
|
label: 'AI Agent controlled apply loop',
|
|
|
|
|
tool_ids: ['ai_agent', 'mcp', 'rag', 'km_playbook'],
|
|
|
|
|
closure_state: 'source_ready_runtime_open',
|
|
|
|
|
closure_percent: 0,
|
|
|
|
|
source_readiness_state: 'source_ready',
|
|
|
|
|
source_readiness_percent: 100,
|
|
|
|
|
runtime_closure_state: 'source_ready_runtime_open',
|
|
|
|
|
runtime_closed: false,
|
|
|
|
|
ready_signal_count: 9,
|
|
|
|
|
required_signal_count: 9,
|
|
|
|
|
missing_signal_count: 0,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
execution_candidate_ready: true,
|
|
|
|
|
runtime_execution_performed: false,
|
|
|
|
|
owner_review_required: false,
|
|
|
|
|
critical_break_glass_required: false,
|
|
|
|
|
secret_value_collection_allowed: false,
|
|
|
|
|
next_executable_action: 'run_allowlisted_check_mode_with_rollback_post_verifier_and_km_writeback',
|
|
|
|
|
required_verifier: 'ai_controlled_apply_post_verifier_and_learning_writeback',
|
|
|
|
|
source_refs: [
|
|
|
|
|
'docs/security/wazuh-runtime-controlled-apply-preflight.snapshot.json',
|
|
|
|
|
'docs/security/wazuh-runtime-gate-owner-review-readback.snapshot.json',
|
|
|
|
|
'docs/security/wazuh-allowlisted-check-mode-dry-run.snapshot.json',
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
const SECURITY_TOOL_CLOSURE_BOOTSTRAP_QUEUE: IwoooSSecurityToolClosureQueueEntry[] = [
|
|
|
|
|
{
|
|
|
|
|
queue_id: 'P0-03',
|
|
|
|
|
track_id: 'wazuh_detection_response',
|
|
|
|
|
state: 'wazuh_registry_complete_move_to_fim_vulnerability_alert',
|
|
|
|
|
next_action: 'attach_fim_vulnerability_alert_receipt_post_verifier',
|
|
|
|
|
ready_signal_count: 5,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
queue_id: 'P0-07',
|
|
|
|
|
track_id: 'supply_chain_sbom_scan',
|
|
|
|
|
state: 'sbom_and_scan_artifacts_missing',
|
|
|
|
|
next_action: 'stage_trivy_syft_grype_check_mode_reports',
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
queue_id: 'P0-08',
|
|
|
|
|
track_id: 'ai_agent_controlled_apply',
|
|
|
|
|
state: 'preflight_ready_for_controlled_policy_check',
|
|
|
|
|
next_action: 'connect_target_selector_diff_check_mode_rollback_post_verifier_km',
|
|
|
|
|
ready_signal_count: 2,
|
|
|
|
|
controlled_apply_policy_allowed: true,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
const SECURITY_TOOL_CLOSURE_BOOTSTRAP_BOUNDARY_MARKERS = [
|
|
|
|
|
'iwooos_security_tool_source_readiness_percent=33',
|
|
|
|
|
'iwooos_security_tool_runtime_closure_percent=0',
|
|
|
|
|
'iwooos_security_tool_closure_percent=0',
|
|
|
|
|
'iwooos_security_tool_closure_wazuh_manager_registry_accepted_count=6',
|
|
|
|
|
'iwooos_security_tool_closure_alert_receipt_accepted_count=0',
|
|
|
|
|
'iwooos_security_tool_closure_controlled_apply_candidate_ready_count=1',
|
|
|
|
|
'owner_review_required_for_low_medium_high=false',
|
|
|
|
|
'runtime_execution_performed=false',
|
|
|
|
|
'secret_value_collection_allowed=false',
|
|
|
|
|
'readback_endpoint_is_executor=false',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
type IwoooSImmediateVisualMeshNode = {
|
|
|
|
|
key: string
|
|
|
|
|
metric: string
|
|
|
|
|
@@ -16275,8 +16554,9 @@ function IwoooSSecurityToolClosureBoard() {
|
|
|
|
|
const t = useTranslations('iwooos.securityToolClosure')
|
|
|
|
|
const textWrap = { overflowWrap: 'anywhere' as const, wordBreak: 'break-word' as const }
|
|
|
|
|
const [data, setData] = useState<IwoooSSecurityToolClosureReadbackResponse | null>(null)
|
|
|
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
|
const [failed, setFailed] = useState(false)
|
|
|
|
|
const [readbackFresh, setReadbackFresh] = useState(false)
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
let mounted = true
|
|
|
|
|
@@ -16286,10 +16566,12 @@ function IwoooSSecurityToolClosureBoard() {
|
|
|
|
|
setFailed(false)
|
|
|
|
|
try {
|
|
|
|
|
const payload = await apiClient.getIwoooSSecurityToolClosureReadback()
|
|
|
|
|
if (mounted) setData(payload)
|
|
|
|
|
if (mounted) {
|
|
|
|
|
setData(payload)
|
|
|
|
|
setReadbackFresh(true)
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
if (mounted) {
|
|
|
|
|
setData(null)
|
|
|
|
|
setFailed(true)
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
@@ -16303,40 +16585,72 @@ function IwoooSSecurityToolClosureBoard() {
|
|
|
|
|
}
|
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
|
|
const summary = data?.summary
|
|
|
|
|
const statusKey = loading ? 'loading' : failed || !data ? 'failed' : 'ready'
|
|
|
|
|
const tracks = data?.tool_tracks ?? []
|
|
|
|
|
const queue = data?.next_executable_queue ?? []
|
|
|
|
|
const summary = data?.summary ?? SECURITY_TOOL_CLOSURE_BOOTSTRAP_SUMMARY
|
|
|
|
|
const statusKey = readbackFresh ? 'ready' : failed ? 'bootstrap' : loading ? 'syncing' : 'bootstrap'
|
|
|
|
|
const statusTone: 'steady' | 'warn' = readbackFresh ? 'steady' : 'warn'
|
|
|
|
|
const tracks = data?.tool_tracks?.length ? data.tool_tracks : SECURITY_TOOL_CLOSURE_BOOTSTRAP_TRACKS
|
|
|
|
|
const queue = data?.next_executable_queue?.length ? data.next_executable_queue : SECURITY_TOOL_CLOSURE_BOOTSTRAP_QUEUE
|
|
|
|
|
const boundaryMarkers = data?.boundary_markers?.length ? data.boundary_markers : SECURITY_TOOL_CLOSURE_BOOTSTRAP_BOUNDARY_MARKERS
|
|
|
|
|
const primaryQueue = queue[0]
|
|
|
|
|
const metrics: IwoooSSecurityToolClosureMetric[] = [
|
|
|
|
|
{
|
|
|
|
|
key: 'closure',
|
|
|
|
|
value: summary ? `${summary.tool_runtime_closure_percent}%` : '...',
|
|
|
|
|
value: `${summary.tool_runtime_closure_percent}%`,
|
|
|
|
|
icon: ShieldCheck,
|
|
|
|
|
tone: summary && summary.tool_runtime_closure_percent > 0 ? 'steady' : 'locked',
|
|
|
|
|
tone: summary.tool_runtime_closure_percent >= 100 ? 'steady' : summary.tool_runtime_closure_percent > 0 ? 'warn' : 'locked',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'tracks',
|
|
|
|
|
value: summary ? `${summary.source_ready_tool_track_count}/${summary.tool_track_count}` : '...',
|
|
|
|
|
value: `${summary.source_ready_tool_track_count}/${summary.tool_track_count}`,
|
|
|
|
|
icon: SearchCheck,
|
|
|
|
|
tone: summary && summary.partial_tool_track_count > 0 ? 'warn' : 'locked',
|
|
|
|
|
tone: summary.source_ready_tool_track_count > 0 ? 'warn' : 'locked',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'wazuh',
|
|
|
|
|
value: summary ? `${summary.wazuh_manager_registry_accepted_count}/${summary.wazuh_expected_host_scope_count}` : '...',
|
|
|
|
|
value: `${summary.wazuh_fim_vulnerability_alert_verifier_ready_signal_count}/${summary.wazuh_expected_host_scope_count}`,
|
|
|
|
|
icon: Radar,
|
|
|
|
|
tone: summary && summary.wazuh_registry_complete_count > 0 ? 'steady' : 'warn',
|
|
|
|
|
tone: summary.wazuh_fim_vulnerability_alert_runtime_closed_count > 0
|
|
|
|
|
? 'steady'
|
|
|
|
|
: summary.wazuh_fim_vulnerability_alert_verifier_ready_signal_count > 0
|
|
|
|
|
? 'warn'
|
|
|
|
|
: 'locked',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'alerts',
|
|
|
|
|
value: summary ? `${summary.alert_receipt_accepted_count}/${summary.alert_receipt_observed_count}` : '...',
|
|
|
|
|
value: `${summary.alert_receipt_accepted_count}/${summary.alert_receipt_observed_count}`,
|
|
|
|
|
icon: Bell,
|
|
|
|
|
tone: summary && summary.alert_receipt_accepted_count > 0 ? 'steady' : 'warn',
|
|
|
|
|
tone: summary.alert_receipt_accepted_count > 0 ? 'steady' : 'warn',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'runtime',
|
|
|
|
|
value: summary ? `${summary.controlled_apply_candidate_ready_count}/${summary.tool_track_count}` : '...',
|
|
|
|
|
value: `${summary.controlled_apply_candidate_ready_count}/${summary.tool_track_count}`,
|
|
|
|
|
icon: Activity,
|
|
|
|
|
tone: summary && summary.controlled_apply_policy_active_count > 0 ? 'steady' : 'warn',
|
|
|
|
|
tone: summary.controlled_apply_candidate_ready_count > 0 ? 'warn' : 'locked',
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
const guardrails: Array<{
|
|
|
|
|
key: string
|
|
|
|
|
label: string
|
|
|
|
|
value: string
|
|
|
|
|
tone: 'steady' | 'warn' | 'locked'
|
|
|
|
|
}> = [
|
|
|
|
|
{
|
|
|
|
|
key: 'runtimeActions',
|
|
|
|
|
label: t('guards.runtimeActions'),
|
|
|
|
|
value: String(summary.runtime_execution_performed_count),
|
|
|
|
|
tone: summary.runtime_execution_performed_count === 0 ? 'locked' : 'warn',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'criticalSecrets',
|
|
|
|
|
label: t('guards.criticalSecrets'),
|
|
|
|
|
value: String(summary.secret_value_collection_allowed_count),
|
|
|
|
|
tone: summary.secret_value_collection_allowed_count === 0 ? 'locked' : 'warn',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'ownerReview',
|
|
|
|
|
label: t('guards.ownerReview'),
|
|
|
|
|
value: String(summary.owner_review_required_for_low_medium_high_count),
|
|
|
|
|
tone: summary.owner_review_required_for_low_medium_high_count === 0 ? 'steady' : 'warn',
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
@@ -16352,40 +16666,98 @@ function IwoooSSecurityToolClosureBoard() {
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gap: 12,
|
|
|
|
|
background: '#f7faf8',
|
|
|
|
|
borderColor: '#cdded2',
|
|
|
|
|
borderColor: '#c9d8d0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 260px), 1fr))',
|
|
|
|
|
gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 240px), 1fr))',
|
|
|
|
|
gap: 10,
|
|
|
|
|
alignItems: 'stretch',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ minWidth: 0 }}>
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
border: '0.5px solid #d6e1d9',
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
background: '#fff',
|
|
|
|
|
padding: 12,
|
|
|
|
|
minWidth: 0,
|
|
|
|
|
display: 'grid',
|
|
|
|
|
alignContent: 'space-between',
|
|
|
|
|
gap: 10,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8, color: '#315f43', fontSize: 11, fontWeight: 800 }}>
|
|
|
|
|
<SearchCheck size={16} />
|
|
|
|
|
<span>{t('eyebrow')}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<h2 style={{ margin: '6px 0 0', color: '#101513', fontSize: 20, lineHeight: 1.1, ...textWrap }}>
|
|
|
|
|
<h2 style={{ margin: 0, color: '#101513', fontSize: 18, lineHeight: 1.1, ...textWrap }}>
|
|
|
|
|
{t('title')}
|
|
|
|
|
</h2>
|
|
|
|
|
<p style={{ margin: '6px 0 0', color: '#4e5c52', fontSize: 12, lineHeight: 1.45, ...textWrap }}>
|
|
|
|
|
{t('subtitle')}
|
|
|
|
|
</p>
|
|
|
|
|
<div style={{ color: toneColors.warn, fontSize: 46, fontWeight: 950, letterSpacing: 0, lineHeight: 0.95 }}>
|
|
|
|
|
{summary.tool_runtime_closure_percent}%
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ color: '#526058', fontSize: 10.5, fontWeight: 800, ...textWrap }}>
|
|
|
|
|
{t('statusDetail', {
|
|
|
|
|
ready: summary.total_ready_signal_count,
|
|
|
|
|
required: summary.total_required_signal_count,
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 6, color: '#526058', fontSize: 10.5, fontWeight: 800 }}>
|
|
|
|
|
<ToneDot tone={statusTone} />
|
|
|
|
|
<span>{t(`source.${readbackFresh ? 'live' : 'bootstrap'}` as never)}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style={{ border: '0.5px solid #d8e5db', borderRadius: 8, background: '#fff', padding: 11, minWidth: 0 }}>
|
|
|
|
|
<div style={{ border: '0.5px solid #d8e5db', borderRadius: 8, background: '#fff', padding: 12, minWidth: 0 }}>
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
|
|
|
|
|
<span style={{ color: '#64746a', fontSize: 10, fontWeight: 800 }}>{t('statusLabel')}</span>
|
|
|
|
|
<ToneDot tone={statusKey === 'ready' ? 'warn' : 'locked'} />
|
|
|
|
|
<ToneDot tone={statusTone} />
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ marginTop: 7, color: statusKey === 'ready' ? '#9a5d1d' : '#7b2b2b', fontSize: 15, fontWeight: 800, lineHeight: 1.2, ...textWrap }}>
|
|
|
|
|
<div style={{ marginTop: 8, color: statusTone === 'steady' ? '#315f43' : '#9a5d1d', fontSize: 15, fontWeight: 900, lineHeight: 1.2, ...textWrap }}>
|
|
|
|
|
{t(`status.${statusKey}` as never)}
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ marginTop: 7, color: '#64746a', fontSize: 11, lineHeight: 1.35, ...textWrap }}>
|
|
|
|
|
{summary ? t('statusDetail', { ready: summary.total_ready_signal_count, required: summary.total_required_signal_count }) : t('statusDetailFallback')}
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
marginTop: 10,
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
|
|
|
|
|
gap: 7,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{[
|
|
|
|
|
{ label: t('compact.signals'), value: `${summary.total_ready_signal_count}/${summary.total_required_signal_count}` },
|
|
|
|
|
{ label: t('compact.sources'), value: String(summary.source_readback_count) },
|
|
|
|
|
{ label: t('compact.p0'), value: `${summary.p0_tool_track_count}` },
|
|
|
|
|
].map(item => (
|
|
|
|
|
<div key={item.label} style={{ border: '0.5px solid #e3ece6', borderRadius: 8, background: '#f9fcfa', padding: 8, minWidth: 0 }}>
|
|
|
|
|
<div style={{ color: '#66706a', fontSize: 9.5, fontWeight: 800, ...textWrap }}>{item.label}</div>
|
|
|
|
|
<div style={{ marginTop: 4, color: '#18211b', fontSize: 18, lineHeight: 1, fontWeight: 950 }}>{item.value}</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style={{ border: '0.5px solid #e2cbb4', borderRadius: 8, background: '#fffaf3', padding: 12, minWidth: 0 }}>
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 7, color: '#9a5d1d', fontSize: 10, fontWeight: 900 }}>
|
|
|
|
|
<ListChecks size={14} />
|
|
|
|
|
<span>{t('queueLabel')}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ marginTop: 8, color: '#9a5d1d', fontSize: 18, fontWeight: 950, lineHeight: 1 }}>
|
|
|
|
|
{primaryQueue.queue_id}
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ marginTop: 7, color: '#141413', fontSize: 13, fontWeight: 900, lineHeight: 1.2, ...textWrap }}>
|
|
|
|
|
{t(`queue.${primaryQueue.queue_id}.title` as never)}
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ marginTop: 8, display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
|
|
|
|
<span style={{ border: '0.5px solid #e2cbb4', borderRadius: 999, background: '#fff', color: '#9a5d1d', padding: '4px 7px', fontSize: 10, fontWeight: 900 }}>
|
|
|
|
|
{primaryQueue.ready_signal_count ?? 0}/6
|
|
|
|
|
</span>
|
|
|
|
|
<span style={{ border: '0.5px solid #d6e1d9', borderRadius: 999, background: '#fff', color: '#315f43', padding: '4px 7px', fontSize: 10, fontWeight: 900 }}>
|
|
|
|
|
{t('compact.controlled')}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@@ -16419,11 +16791,34 @@ function IwoooSSecurityToolClosureBoard() {
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 7 }}>
|
|
|
|
|
{guardrails.map(item => (
|
|
|
|
|
<div
|
|
|
|
|
key={item.key}
|
|
|
|
|
style={{
|
|
|
|
|
border: `0.5px solid ${item.tone === 'steady' ? '#cddfd5' : item.tone === 'warn' ? '#e2cbb4' : '#d9d6ce'}`,
|
|
|
|
|
borderRadius: 999,
|
|
|
|
|
background: item.tone === 'steady' ? '#f4fbf6' : item.tone === 'warn' ? '#fff8f1' : '#f8f7f2',
|
|
|
|
|
color: toneColors[item.tone],
|
|
|
|
|
padding: '6px 9px',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
gap: 6,
|
|
|
|
|
minWidth: 0,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Lock size={13} />
|
|
|
|
|
<span style={{ fontSize: 10, fontWeight: 900, ...textWrap }}>{item.label}</span>
|
|
|
|
|
<span style={{ fontSize: 12, fontWeight: 950 }}>{item.value}</span>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
data-testid="iwooos-security-tool-closure-tracks"
|
|
|
|
|
style={{
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 210px), 1fr))',
|
|
|
|
|
gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 180px), 1fr))',
|
|
|
|
|
gap: 8,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
@@ -16462,50 +16857,32 @@ function IwoooSSecurityToolClosureBoard() {
|
|
|
|
|
<span>{t(`states.${track.runtime_closure_state}` as never)}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
|
|
|
|
|
{track.tool_ids.slice(0, 4).map(tool => (
|
|
|
|
|
<code
|
|
|
|
|
key={tool}
|
|
|
|
|
style={{
|
|
|
|
|
border: '0.5px solid #dce7df',
|
|
|
|
|
borderRadius: 999,
|
|
|
|
|
background: '#f6faf7',
|
|
|
|
|
color: '#355f43',
|
|
|
|
|
padding: '3px 6px',
|
|
|
|
|
fontSize: 9.5,
|
|
|
|
|
fontWeight: 800,
|
|
|
|
|
...textWrap,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{tool}
|
|
|
|
|
</code>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ color: '#526058', fontSize: 10.5, lineHeight: 1.35, ...textWrap }}>
|
|
|
|
|
{t(`tracks.${track.track_id}.next` as never)}
|
|
|
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 7, alignItems: 'center' }}>
|
|
|
|
|
<span style={{ color: '#66706a', fontSize: 9.5, fontWeight: 800, ...textWrap }}>
|
|
|
|
|
{track.tool_ids.slice(0, 2).join(' / ')}
|
|
|
|
|
</span>
|
|
|
|
|
<span style={{ color: toneColors[tone], fontSize: 11, fontWeight: 950 }}>{track.closure_percent}%</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
<details
|
|
|
|
|
data-testid="iwooos-security-tool-closure-next-queue"
|
|
|
|
|
style={{
|
|
|
|
|
border: '0.5px solid #d6e1d9',
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
background: '#fff',
|
|
|
|
|
padding: 10,
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gap: 8,
|
|
|
|
|
padding: '8px 10px',
|
|
|
|
|
minWidth: 0,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 7, color: '#315f43', fontSize: 10, fontWeight: 900 }}>
|
|
|
|
|
<summary style={{ cursor: 'pointer', color: '#315f43', fontSize: 10.5, fontWeight: 900 }}>
|
|
|
|
|
<ListChecks size={14} />
|
|
|
|
|
<span>{t('queueLabel')}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 190px), 1fr))', gap: 8 }}>
|
|
|
|
|
<span style={{ marginLeft: 6 }}>{t('detailsTitle')}</span>
|
|
|
|
|
</summary>
|
|
|
|
|
<div style={{ marginTop: 9, display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 190px), 1fr))', gap: 8 }}>
|
|
|
|
|
{queue.map(item => (
|
|
|
|
|
<div
|
|
|
|
|
key={`${item.queue_id}-${item.track_id}`}
|
|
|
|
|
@@ -16530,14 +16907,8 @@ function IwoooSSecurityToolClosureBoard() {
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<details style={{ border: '0.5px solid #d6e1d9', borderRadius: 8, background: '#fff', padding: '8px 10px' }}>
|
|
|
|
|
<summary style={{ cursor: 'pointer', color: '#64746a', fontSize: 10.5, fontWeight: 900 }}>
|
|
|
|
|
{t('boundaryTitle')}
|
|
|
|
|
</summary>
|
|
|
|
|
<div style={{ marginTop: 8, display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
|
|
|
|
{(data?.boundary_markers ?? []).slice(0, 10).map(marker => (
|
|
|
|
|
{boundaryMarkers.slice(0, 10).map(marker => (
|
|
|
|
|
<code
|
|
|
|
|
key={marker}
|
|
|
|
|
style={{
|
|
|
|
|
@@ -24510,9 +24881,9 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) {
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<IwoooSSecurityToolClosureBoard />
|
|
|
|
|
<IwoooSWorkspaceSwitcher active={workspaceView} onChange={setWorkspaceView} />
|
|
|
|
|
<IwoooSManagerCockpit />
|
|
|
|
|
<IwoooSSecurityToolClosureBoard />
|
|
|
|
|
|
|
|
|
|
<IwoooSWorkspacePanel active={workspaceView === 'overview'}>
|
|
|
|
|
<IwoooSCommandRail />
|
|
|
|
|
|