From 5820ca90cca0653398850a2175846cb72c531446 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 18 Jun 2026 10:24:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(iwooos):=20=E6=96=B0=E5=A2=9E=E5=A4=96?= =?UTF-8?q?=E9=83=A8=E5=85=A5=E4=BE=B5=E4=B8=BB=E6=A9=9F=E9=98=B2=E5=A0=B5?= =?UTF-8?q?=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/messages/en.json | 67 +- apps/web/messages/zh-TW.json | 67 +- apps/web/src/app/[locale]/iwooos/page.tsx | 215 +- docs/LOGBOOK.md | 31 + ...ERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md | 128 + .../HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md | 21 +- docs/security/IWOOOS-POSTURE-PROJECTION.md | 9 +- ...intrusion-prevention-control.snapshot.json | 3519 +++++++++++++++++ ...alue-config-control-coverage.snapshot.json | 75 +- .../iwooos-posture-projection.snapshot.json | 137 +- ...ernal-host-intrusion-prevention-control.py | 657 +++ .../high-value-config-control-coverage.py | 42 +- .../security/iwooos-config-control-guard.py | 76 +- .../security-mirror-progress-guard.py | 278 +- 14 files changed, 5194 insertions(+), 128 deletions(-) create mode 100644 docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md create mode 100644 docs/security/external-host-intrusion-prevention-control.snapshot.json create mode 100644 scripts/security/external-host-intrusion-prevention-control.py diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index bdd5b7885..9ac442a63 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -17967,6 +17967,67 @@ } } }, + "externalHostIntrusionPreventionControl": { + "eyebrow": "外部入侵主機防堵控制", + "title": "把主機、入口、網路與供應鏈先收成 P0 防堵矩陣", + "subtitle": "這張卡把公開入口、SSH、端口、防火牆、Nginx、runner、secret、Docker / systemd、K8s、Wazuh、套件更新、backup / restore 與跨專案同步放進同一條防堵線;目前只顯示主機別名、候選數、必填 owner 欄位與 0/false 邊界。", + "checkLabel": "優先", + "stateLabel": "狀態", + "boundaryTitle": "外部入侵防堵邊界", + "boundaryIntro": "以下鍵值固定:防堵矩陣不是主機操作授權;沒有 owner、維護窗口、rollback、validation 與 postcheck 前,不執行 SSH、firewall、Nginx reload、Wazuh active response、套件更新、secret 輪替或 production write。", + "summary": { + "domains": { + "label": "控制域", + "detail": "12 個控制域涵蓋主機、入口、網路、供應鏈、偵測與復原。" + }, + "candidates": { + "label": "P0 候選", + "detail": "14 個候選全部需要 owner packet 與 reviewer check。" + }, + "hosts": { + "label": "alias", + "detail": "4 個主機別名與 1 個 sensor alias,前台不顯示內部識別資訊。" + }, + "runtimeGate": { + "label": "執行期", + "detail": "host write、firewall、reload、active response 與 action button 都是 0。" + } + }, + "items": { + "gateway": { + "title": "公開入口先 freeze", + "body": "Nginx、TLS、route、upstream 與 WebSocket 需要 source-to-live diff、維護窗口與 rollback owner。" + }, + "sshFirewall": { + "title": "SSH / 端口 baseline", + "body": "SSH、sudo、authorized_keys、known_hosts、firewall、WireGuard 與 NodePort 需 before / after state。" + }, + "hostRuntime": { + "title": "主機 runtime 與持久化", + "body": "Docker、systemd、process、port binding、package 與 persistence 需 Wazuh event 與主機鑑識 ref。" + }, + "runnerSecret": { + "title": "Runner / workflow / secret freeze", + "body": "runner、workflow、deploy key、webhook 與 secret metadata 變更必須串回高價值配置 gate。" + }, + "wazuhResponse": { + "title": "Wazuh response 先 dry-run", + "body": "active response 只能先做 dry-run、blast radius 與 rollback 評估,不能直接啟用。" + }, + "backupRestore": { + "title": "復原退路要先驗", + "body": "backup、restore、offsite、escrow、retention 與 rollback 需可驗證,不用 UI 可見代替。" + }, + "packagePatch": { + "title": "套件修補排維護窗口", + "body": "套件、kernel、Docker、Nginx 或 agent 更新要有維護窗口、影響評估與 postcheck。" + }, + "sync": { + "title": "跨專案與多 Session 防衝突", + "body": "任何會影響服務的防堵都要先同步 operator、其他 session 與受影響產品 owner。" + } + } + }, "criticalConfigPriority": { "eyebrow": "P0 配置控管優先序", "title": "先看最可能造成即時資安或服務風險的配置", @@ -18103,7 +18164,7 @@ }, "dockerSystemd": { "title": "Docker / systemd 主機服務", - "body": "只讀清冊、負責人回覆驗收、主機服務變更證據驗收與事故後回讀計畫已納入 9 個範圍;目前只讀成熟度 64%,28 個審查檢查項、10 條結果分流、41 類禁止動作。Docker daemon、compose、systemd、失敗單元、port binding、public/admin route、AI provider、監控告警、跨專案同步、防再發與 no-false-green 驗收仍全部為 0。" + "body": "只讀清冊、負責人回覆驗收、主機服務變更證據驗收、事故後回讀計畫與外部入侵防堵矩陣已納入;目前只讀成熟度 68%,主機 runtime、process、port binding、package 與 persistence 都進入 P0 防堵候選。Docker daemon、compose、systemd、失敗單元、port binding、AI provider、監控告警、跨專案同步、防再發與 no-false-green 驗收仍全部為 0。" }, "aiProvider": { "title": "AI 供應商 / 模型路由", @@ -18111,7 +18172,7 @@ }, "sshNetwork": { "title": "SSH / network / firewall", - "body": "repo-only 清冊已納入 16 個 SSH / network access surface,owner response acceptance、事故型端口 / 防火牆變更證據驗收與 post-incident readback plan 已固定;目前成熟度 64%,14 個事故回讀候選、24 個 reviewer checks、10 條 outcome lanes、34 類 blocked action。下一步仍需 actor、before / after、service / AI provider / monitoring impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check evidence,readback accepted 與 runtime gate 仍全部為 0。" + "body": "repo-only 清冊已納入 16 個 SSH / network access surface,並新增外部入侵防堵矩陣;目前成熟度 70%,SSH、sudo、known_hosts、firewall、WireGuard、NodePort 與 NetworkPolicy 都需要 before / after state、維護窗口與 rollback owner。防火牆變更、port close / open、SSH 寫入、host write、readback accepted 與 runtime gate 仍全部為 0。" }, "k8sGitops": { "title": "K8s / ArgoCD GitOps", @@ -18123,7 +18184,7 @@ }, "monitoring": { "title": "監控與告警設定", - "body": "已新增 60 個 monitoring / alerting / observability surface、事故後回讀計畫與 Wazuh / 主機入侵 readback plan;目前只讀成熟度 72%,Wazuh 回讀固定 6 個候選、2 個 host alias、30 個必填欄位、24 個 reviewer checks、12 條 outcome lanes、49 類 blocked action。Wazuh event、主機鑑識、containment、recovery proof、active response、runtime gate 與 action button 仍全部為 0。" + "body": "已新增 60 個 monitoring / alerting / observability surface、事故後回讀計畫、Wazuh / 主機入侵 readback plan 與外部入侵防堵矩陣;目前只讀成熟度 74%。Wazuh event、主機鑑識、containment、recovery proof、active response、host write、runtime gate 與 action button 仍全部為 0。" } } }, diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index bdd5b7885..9ac442a63 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -17967,6 +17967,67 @@ } } }, + "externalHostIntrusionPreventionControl": { + "eyebrow": "外部入侵主機防堵控制", + "title": "把主機、入口、網路與供應鏈先收成 P0 防堵矩陣", + "subtitle": "這張卡把公開入口、SSH、端口、防火牆、Nginx、runner、secret、Docker / systemd、K8s、Wazuh、套件更新、backup / restore 與跨專案同步放進同一條防堵線;目前只顯示主機別名、候選數、必填 owner 欄位與 0/false 邊界。", + "checkLabel": "優先", + "stateLabel": "狀態", + "boundaryTitle": "外部入侵防堵邊界", + "boundaryIntro": "以下鍵值固定:防堵矩陣不是主機操作授權;沒有 owner、維護窗口、rollback、validation 與 postcheck 前,不執行 SSH、firewall、Nginx reload、Wazuh active response、套件更新、secret 輪替或 production write。", + "summary": { + "domains": { + "label": "控制域", + "detail": "12 個控制域涵蓋主機、入口、網路、供應鏈、偵測與復原。" + }, + "candidates": { + "label": "P0 候選", + "detail": "14 個候選全部需要 owner packet 與 reviewer check。" + }, + "hosts": { + "label": "alias", + "detail": "4 個主機別名與 1 個 sensor alias,前台不顯示內部識別資訊。" + }, + "runtimeGate": { + "label": "執行期", + "detail": "host write、firewall、reload、active response 與 action button 都是 0。" + } + }, + "items": { + "gateway": { + "title": "公開入口先 freeze", + "body": "Nginx、TLS、route、upstream 與 WebSocket 需要 source-to-live diff、維護窗口與 rollback owner。" + }, + "sshFirewall": { + "title": "SSH / 端口 baseline", + "body": "SSH、sudo、authorized_keys、known_hosts、firewall、WireGuard 與 NodePort 需 before / after state。" + }, + "hostRuntime": { + "title": "主機 runtime 與持久化", + "body": "Docker、systemd、process、port binding、package 與 persistence 需 Wazuh event 與主機鑑識 ref。" + }, + "runnerSecret": { + "title": "Runner / workflow / secret freeze", + "body": "runner、workflow、deploy key、webhook 與 secret metadata 變更必須串回高價值配置 gate。" + }, + "wazuhResponse": { + "title": "Wazuh response 先 dry-run", + "body": "active response 只能先做 dry-run、blast radius 與 rollback 評估,不能直接啟用。" + }, + "backupRestore": { + "title": "復原退路要先驗", + "body": "backup、restore、offsite、escrow、retention 與 rollback 需可驗證,不用 UI 可見代替。" + }, + "packagePatch": { + "title": "套件修補排維護窗口", + "body": "套件、kernel、Docker、Nginx 或 agent 更新要有維護窗口、影響評估與 postcheck。" + }, + "sync": { + "title": "跨專案與多 Session 防衝突", + "body": "任何會影響服務的防堵都要先同步 operator、其他 session 與受影響產品 owner。" + } + } + }, "criticalConfigPriority": { "eyebrow": "P0 配置控管優先序", "title": "先看最可能造成即時資安或服務風險的配置", @@ -18103,7 +18164,7 @@ }, "dockerSystemd": { "title": "Docker / systemd 主機服務", - "body": "只讀清冊、負責人回覆驗收、主機服務變更證據驗收與事故後回讀計畫已納入 9 個範圍;目前只讀成熟度 64%,28 個審查檢查項、10 條結果分流、41 類禁止動作。Docker daemon、compose、systemd、失敗單元、port binding、public/admin route、AI provider、監控告警、跨專案同步、防再發與 no-false-green 驗收仍全部為 0。" + "body": "只讀清冊、負責人回覆驗收、主機服務變更證據驗收、事故後回讀計畫與外部入侵防堵矩陣已納入;目前只讀成熟度 68%,主機 runtime、process、port binding、package 與 persistence 都進入 P0 防堵候選。Docker daemon、compose、systemd、失敗單元、port binding、AI provider、監控告警、跨專案同步、防再發與 no-false-green 驗收仍全部為 0。" }, "aiProvider": { "title": "AI 供應商 / 模型路由", @@ -18111,7 +18172,7 @@ }, "sshNetwork": { "title": "SSH / network / firewall", - "body": "repo-only 清冊已納入 16 個 SSH / network access surface,owner response acceptance、事故型端口 / 防火牆變更證據驗收與 post-incident readback plan 已固定;目前成熟度 64%,14 個事故回讀候選、24 個 reviewer checks、10 條 outcome lanes、34 類 blocked action。下一步仍需 actor、before / after、service / AI provider / monitoring impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check evidence,readback accepted 與 runtime gate 仍全部為 0。" + "body": "repo-only 清冊已納入 16 個 SSH / network access surface,並新增外部入侵防堵矩陣;目前成熟度 70%,SSH、sudo、known_hosts、firewall、WireGuard、NodePort 與 NetworkPolicy 都需要 before / after state、維護窗口與 rollback owner。防火牆變更、port close / open、SSH 寫入、host write、readback accepted 與 runtime gate 仍全部為 0。" }, "k8sGitops": { "title": "K8s / ArgoCD GitOps", @@ -18123,7 +18184,7 @@ }, "monitoring": { "title": "監控與告警設定", - "body": "已新增 60 個 monitoring / alerting / observability surface、事故後回讀計畫與 Wazuh / 主機入侵 readback plan;目前只讀成熟度 72%,Wazuh 回讀固定 6 個候選、2 個 host alias、30 個必填欄位、24 個 reviewer checks、12 條 outcome lanes、49 類 blocked action。Wazuh event、主機鑑識、containment、recovery proof、active response、runtime gate 與 action button 仍全部為 0。" + "body": "已新增 60 個 monitoring / alerting / observability surface、事故後回讀計畫、Wazuh / 主機入侵 readback plan 與外部入侵防堵矩陣;目前只讀成熟度 74%。Wazuh event、主機鑑識、containment、recovery proof、active response、host write、runtime gate 與 action button 仍全部為 0。" } } }, diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx index 0acf802fe..80fd3776e 100644 --- a/apps/web/src/app/[locale]/iwooos/page.tsx +++ b/apps/web/src/app/[locale]/iwooos/page.tsx @@ -271,6 +271,14 @@ type WazuhIntrusionReadbackItem = { tone: 'steady' | 'warn' | 'locked' } +type ExternalHostIntrusionPreventionControlItem = { + key: string + check: string + state: string + icon: typeof ShieldCheck + tone: 'steady' | 'warn' | 'locked' +} + type HighValueConfigOwnerPacketItem = { key: string gate: string @@ -2135,7 +2143,7 @@ const wazuhIntrusionReadbackBoundaries = [ 'wazuh_intrusion_readback_plan_secret_value_collection_allowed_count=0', 'wazuh_intrusion_readback_plan_runtime_gate_count=0', 'wazuh_intrusion_readback_plan_action_button_count=0', - 'monitoring_alerting_observability_coverage_percent=72', + 'monitoring_alerting_observability_coverage_percent=74', 'wazuh_api_live_query_authorized=false', 'wazuh_active_response_authorized=false', 'wazuh_agent_install_authorized=false', @@ -2158,6 +2166,69 @@ const wazuhIntrusionReadbackBoundaries = [ 'not_authorization=true', ] as const +const externalHostIntrusionPreventionControlSummary = [ + { key: 'domains', value: '12', icon: Network, tone: 'steady' }, + { key: 'candidates', value: '14', icon: ListChecks, tone: 'warn' }, + { key: 'hosts', value: '4 + 1', icon: Server, tone: 'warn' }, + { key: 'runtimeGate', value: '0', icon: Lock, tone: 'locked' }, +] as const + +const externalHostIntrusionPreventionControlItems: ExternalHostIntrusionPreventionControlItem[] = [ + { key: 'gateway', check: 'P0-1', state: '待 diff / owner', icon: Route, tone: 'warn' }, + { key: 'sshFirewall', check: 'P0-2', state: '待 baseline', icon: Network, tone: 'warn' }, + { key: 'hostRuntime', check: 'P0-4', state: '待鑑識 ref', icon: Server, tone: 'warn' }, + { key: 'runnerSecret', check: 'P0-6', state: '待 freeze', icon: Workflow, tone: 'warn' }, + { key: 'wazuhResponse', check: 'P0-8', state: '待 dry-run', icon: Radar, tone: 'warn' }, + { key: 'backupRestore', check: 'P0-10', state: '待驗證', icon: Database, tone: 'warn' }, + { key: 'packagePatch', check: 'P0-11', state: '待窗口', icon: Boxes, tone: 'warn' }, + { key: 'sync', check: 'P0-14', state: '防衝突', icon: Bell, tone: 'locked' }, +] as const + +const externalHostIntrusionPreventionControlBoundaries = [ + 'external_host_intrusion_prevention_control_visible=true', + 'external_host_intrusion_prevention_control_domain_count=12', + 'external_host_intrusion_prevention_control_candidate_count=14', + 'external_host_intrusion_prevention_control_c0_candidate_count=10', + 'external_host_intrusion_prevention_control_c1_candidate_count=4', + 'external_host_intrusion_prevention_control_p0_candidate_count=14', + 'external_host_intrusion_prevention_control_host_alias_count=4', + 'external_host_intrusion_prevention_control_sensor_alias_count=1', + 'external_host_intrusion_prevention_control_required_owner_field_count=36', + 'external_host_intrusion_prevention_control_reviewer_check_count=34', + 'external_host_intrusion_prevention_control_outcome_lane_count=12', + 'external_host_intrusion_prevention_control_blocked_action_count=82', + 'external_host_intrusion_prevention_control_wazuh_event_required_candidate_count=7', + 'external_host_intrusion_prevention_control_host_forensics_required_candidate_count=6', + 'external_host_intrusion_prevention_control_config_diff_required_candidate_count=8', + 'external_host_intrusion_prevention_control_owner_response_received_count=0', + 'external_host_intrusion_prevention_control_owner_response_accepted_count=0', + 'external_host_intrusion_prevention_control_evidence_ref_received_count=0', + 'external_host_intrusion_prevention_control_evidence_ref_accepted_count=0', + 'external_host_intrusion_prevention_control_prevention_control_accepted_count=0', + 'external_host_intrusion_prevention_control_wazuh_active_response_enabled_count=0', + 'external_host_intrusion_prevention_control_host_write_authorized_count=0', + 'external_host_intrusion_prevention_control_firewall_change_authorized_count=0', + 'external_host_intrusion_prevention_control_nginx_reload_authorized_count=0', + 'external_host_intrusion_prevention_control_package_upgrade_authorized_count=0', + 'external_host_intrusion_prevention_control_active_scan_authorized_count=0', + 'external_host_intrusion_prevention_control_runtime_gate_count=0', + 'external_host_intrusion_prevention_control_action_button_count=0', + 'docker_compose_systemd_host_config_coverage_percent=68', + 'ssh_firewall_network_access_coverage_percent=70', + 'monitoring_alerting_observability_coverage_percent=74', + 'host_write_authorized=false', + 'ssh_write_authorized=false', + 'firewall_change_authorized=false', + 'nginx_reload_authorized=false', + 'wazuh_active_response_authorized=false', + 'package_upgrade_authorized=false', + 'active_scan_authorized=false', + 'runtime_execution_authorized=false', + 'active_runtime_gate_count=0', + 'action_buttons_allowed=false', + 'not_authorization=true', +] as const + const highValueConfigOwnerPacketSummary = [ { key: 'packetCount', value: '3', icon: ClipboardCheck, tone: 'warn' }, { key: 'c0Packets', value: '2', icon: AlertTriangle, tone: 'warn' }, @@ -2173,8 +2244,8 @@ const highValueConfigControlCoverageSummary = [ ] as const const highValueConfigControlCoverageItems: HighValueConfigControlCoverageItem[] = [ - { key: 'dockerSystemd', rank: 'P1-1', value: '64%', icon: Server, tone: 'warn' }, - { key: 'sshNetwork', rank: 'P1-2', value: '64%', icon: Network, tone: 'warn' }, + { key: 'dockerSystemd', rank: 'P1-1', value: '68%', icon: Server, tone: 'warn' }, + { key: 'sshNetwork', rank: 'P1-2', value: '70%', icon: Network, tone: 'warn' }, { key: 'aiProvider', rank: 'P1-3', value: '64%', icon: Cloud, tone: 'warn' }, { key: 'k8sGitops', rank: 'P1-4', value: '66%', icon: Workflow, tone: 'warn' }, { key: 'backupRestore', rank: 'P1-5', value: '66%', icon: Database, tone: 'warn' }, @@ -2187,7 +2258,7 @@ const highValueConfigControlCoverageBoundaries = [ 'high_value_config_control_coverage_c0_category_count=8', 'high_value_config_control_coverage_c1_category_count=4', 'high_value_config_control_coverage_average_percent=72', - 'high_value_config_control_coverage_needs_live_evidence_count=9', + 'high_value_config_control_coverage_needs_live_evidence_count=10', 'high_value_config_control_coverage_owner_response_required_count=14', 'high_value_config_control_coverage_owner_response_received_count=0', 'high_value_config_control_coverage_owner_response_accepted_count=0', @@ -2202,6 +2273,9 @@ const highValueConfigControlCoverageBoundaries = [ 'secret_metadata_coverage_percent=70', 'gitea_workflow_runner_source_control_coverage_percent=74', 'public_admin_api_runtime_config_coverage_percent=66', + 'docker_compose_systemd_host_config_coverage_percent=68', + 'ssh_firewall_network_access_coverage_percent=70', + 'monitoring_alerting_observability_coverage_percent=74', 'ai_provider_model_routing_coverage_percent=64', 'ai_provider_owner_response_acceptance_candidate_count=8', 'ai_provider_owner_response_acceptance_write_capable_candidate_count=5', @@ -2469,7 +2543,6 @@ const highValueConfigControlCoverageBoundaries = [ 'monitoring_alerting_observability_inventory_reload_owner_accepted_count=0', 'monitoring_alerting_observability_inventory_receiver_owner_accepted_count=0', 'monitoring_alerting_observability_inventory_route_smoke_accepted_count=0', - 'monitoring_alerting_observability_coverage_percent=72', 'monitoring_owner_response_acceptance_required_owner_field_count=14', 'monitoring_owner_response_acceptance_reviewer_check_count=23', 'monitoring_owner_response_acceptance_outcome_lane_count=12', @@ -7438,6 +7511,137 @@ function IwoooSWazuhIntrusionReadbackBoard() { ) } +function IwoooSExternalHostIntrusionPreventionControlBoard() { + const t = useTranslations('iwooos.externalHostIntrusionPreventionControl') + const textWrap = { overflowWrap: 'anywhere' as const, wordBreak: 'break-word' as const } + + return ( +
+
+
+
+
+ + {t('eyebrow')} +
+

{t('title')}

+

+ {t('subtitle')} +

+
+ +
+ {externalHostIntrusionPreventionControlSummary.map(item => { + const Icon = item.icon + return ( +
+
+ {t(`summary.${item.key}.label` as never)} + +
+
+ {item.value} +
+

+ {t(`summary.${item.key}.detail` as never)} +

+
+ ) + })} +
+
+ +
+ {externalHostIntrusionPreventionControlItems.map(item => { + const Icon = item.icon + return ( +
+
+ + {t('checkLabel')} {item.check} + + +
+
+
+ {t(`items.${item.key}.title` as never)} +
+
+ {t('stateLabel')}:{item.state} +
+
+

+ {t(`items.${item.key}.body` as never)} +

+
+ ) + })} +
+ +
+ + {t('boundaryTitle')} + +

+ {t('boundaryIntro')} +

+
+ {externalHostIntrusionPreventionControlBoundaries.map(item => ( + + {item} + + ))} +
+
+
+
+ ) +} + function IwoooSHighValueConfigOwnerPacketBoard() { const t = useTranslations('iwooos.highValueConfigOwnerPacket') const textWrap = { overflowWrap: 'anywhere' as const, wordBreak: 'break-word' as const } @@ -19968,6 +20172,7 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) { + diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 8e55bb888..11c215dff 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -18,6 +18,37 @@ **邊界**:本段不送 Telegram、不寫 Gateway queue、不呼叫 Bot API、不寫讀報回執、不啟動排程、不啟動 AI analysis runtime、不啟動中低風險自動處理、不讀 secret、不新增批准或發送按鈕。 +## 2026-06-18|IwoooS 外部入侵主機防堵控制本地收斂 + +**背景**:110 / 188 曾出現主機入侵與服務異常,表示既有 IwoooS 只讀治理、Wazuh 接入與高價值配置控管仍不足以把「外部入侵防堵」轉成可驗收、可同步、可回復的控制面。使用者已要求優先處理即時性資安危害,但仍不得把 runtime 操作、Nginx reload、firewall 變更、Wazuh active response、套件更新或 secret 輪替偽裝成已授權。 + +**完成內容**: +- 新增 `scripts/security/external-host-intrusion-prevention-control.py`、`docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md` 與 `docs/security/external-host-intrusion-prevention-control.snapshot.json`。 +- 外部入侵主機防堵控制固定為 `12` 個控制域、`14` 個 P0 防堵候選、`10` 個 C0 候選、`4` 個主機 alias、`1` 個 sensor alias、`36` 個 owner 必填欄位、`34` 個 reviewer checks、`12` 條 outcome lanes、`82` 類 blocked actions。 +- 高價值配置控管同步更新:Docker / systemd 主機服務成熟度 `68%`、SSH / firewall / network 成熟度 `70%`、monitoring / Wazuh / observability 成熟度 `74%`,平均成熟度 `72%`,needs-live-evidence 類別 `10`。 +- `/zh-TW/iwooos` 新增「外部入侵主機防堵控制」前台卡,使用 alias、候選數、必填欄位與 `0 / false` 邊界,不顯示內部 IP、個人 namespace、raw log、secret、工作視窗內容或外部對話逐字稿。 +- `iwooos-config-control-guard.py` 與 `security-mirror-progress-guard.py` 已把新 snapshot、前台 marker、i18n namespace、projection evidence、coverage 數值與禁止動作納入強制驗收。 + +**本地驗證,2026-06-18 10:19 CST**: +- `python3 -m py_compile`:新增外部入侵防堵腳本、高價值配置腳本、config guard、security mirror guard 通過。 +- `python3 scripts/security/external-host-intrusion-prevention-control.py --root .`:`domains=12 candidates=14 hosts=4 checks=34 blocked=82 runtime_gate=0`。 +- `python3 scripts/security/high-value-config-control-coverage.py --root .`:`categories=14 c0=8 avg=72 runtime_gate=0`。 +- JSON parse:`zh-TW.json`、`en.json`、external host 防堵 snapshot、高價值配置 snapshot、IwoooS posture projection snapshot 通過。 +- `python3 scripts/ops/doc-secrets-sanity-check.py docs .gitea apps/web/messages/zh-TW.json apps/web/messages/en.json 'apps/web/src/app/[locale]/iwooos/page.tsx'`:`DOC_SECRET_SANITY_OK scanned_files=900`。 +- `python3 scripts/security/iwooos-config-control-guard.py --root .`:`IWOOOS_CONFIG_CONTROL_GUARD_OK`。 +- `python3 scripts/security/security-mirror-progress-guard.py --root .`:`SECURITY_MIRROR_PROGRESS_GUARD_OK`。 +- `pnpm --filter @awoooi/web typecheck`:通過。 +- 本地 Chrome desktop `1440x1100` 與 mobile `390x844`:新卡可見,固定 marker missing `0`,水平溢位 `0`,敏感 / 內部協作片語命中 `0`。本地 desktop 因 `localhost` 對正式 API 的 CORS 限制出現既有 snapshot fetch 噪音;正式站需以同源 production route 再驗一次。 + +**完成度同步**: +- 外部入侵主機防堵控制 repo artifact / snapshot / guard:`100%`。 +- IwoooS 前台脫敏可視化與本地 desktop / mobile smoke:`100%`。 +- 高價值配置控管只讀成熟度:`72%`。 +- IwoooS headline:仍維持 `64%`,不得因 UI 可見假性拉高。 +- Wazuh active response、host write、firewall change、Nginx reload、package upgrade、active scan、runtime execution、action button:全部仍為 `0 / false`。 + +**邊界**:本輪未 SSH、未改 Nginx、未改 firewall、未 reload、未執行 Wazuh active response、未安裝 agent、未更新套件、未 active scan、未讀或保存 secret、未改 workflow、未同步 refs、未 force push、未做 production runtime 寫入;下一步必須先推 Gitea、等待 CD,再做 production `/zh-TW/iwooos` desktop / mobile verification 並補 deploy marker、Gitea runs 與正式 URL。 + ## 2026-06-18|P2-405F Telegram Canary Owner Review Gate 本地收斂 **背景**:P2-405E 已完成 dry-run delivery rehearsal 與正式站驗證,但 Telegram 真正要打通不能直接從「演練通過」跳到 Bot API 實發;必須先把 owner review、receipt readback、拒收條件、mute / rollback 與單一 canary 實發邊界固定成可審核契約,避免再次出現「批准後看似執行、實際沒有自動化流程」或「只發報表但沒有 receipt / actionability」的斷鏈。 diff --git a/docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md b/docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md new file mode 100644 index 000000000..8ccfbb5ae --- /dev/null +++ b/docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md @@ -0,0 +1,128 @@ +# IwoooS 外部入侵主機防堵控制矩陣 + +| 項目 | 內容 | +|------|------| +| 日期 | 2026-06-18 | +| 狀態 | `external_host_intrusion_prevention_control_ready_no_runtime_action` | +| 工具 | `scripts/security/external-host-intrusion-prevention-control.py` | +| Snapshot | `docs/security/external-host-intrusion-prevention-control.snapshot.json` | +| runtime gate | `0` | + +## 1. 目的 + +此矩陣把「全力防堵外部入侵主機」從口頭要求轉成 IwoooS 可驗收、可拒收、可排序的 P0 控制面。它把所有容易造成即時資安危害的面向放在同一張矩陣:公開入口、DNS / TLS、Nginx、SSH / sudo、端口 / 防火牆、WireGuard、NodePort、Docker / systemd、process、K8s / ArgoCD、RBAC、runner、workflow、deploy key、webhook、secret、Wazuh、套件更新、backup / restore、monitoring / alerting、跨專案 freeze 與 break-glass。 + +本階段不直接連主機、不 SSH、不讀 live config、不改 Nginx、不改 firewall、不啟用 Wazuh active response、不重啟服務、不更新套件、不輪替 secret、不跑 active scan。它的作用是先建立「誰能批准、要看什麼證據、什麼要拒收、什麼仍為 0」的防堵控制基線。 + +## 2. 為什麼舊機制沒有擋住 + +1. 先前 IwoooS 的主體是只讀治理、owner gate、前台可視化與低摩擦收件,`active_runtime_gate=0`,沒有主機 containment、firewall drop、Wazuh active response 或 secret rotation 權限。 +2. Wazuh 已建置只能代表偵測平台存在;若沒有 event refs、agent status refs、host forensic refs、config diff refs 與 containment decision,IwoooS 不能判斷 110 / 188 類主機事件已防堵。 +3. Nginx、端口、防火牆、runner、workflow、secret、Docker / systemd、K8s / ArgoCD 與 backup / restore 原本分散在不同清冊,沒有一個「外部入侵防堵」的統一優先序。 +4. route `200`、dashboard up、container up、CD success、UI 可見或外部 Agent 宣稱,過去容易被誤讀成服務恢復或風險降低,但它們都不能證明木馬清除、RCE 修補、持久化移除或 credential 未外洩。 +5. 未建立維護窗口、rollback owner、validation metrics、postcheck owner 與跨專案同步前,直接封 port、reload、restart、upgrade 或 sync 會造成服務中斷與二次事故。 + +## 3. 完整工作範圍 + +| 範圍 | 要控管的項目 | +|------|--------------| +| 主機 | host OS、SSH、sudo、authorized_keys、known_hosts、systemd、Docker、process、port binding、套件、kernel、Wazuh agent、backup agent、排程 | +| 公開入口 | DNS、TLS、certbot、Nginx、public gateway、upstream、WebSocket、ACME challenge、public / admin / API route | +| 網路 | firewall、WireGuard、NodePort、NetworkPolicy、VIP、內網 service dependency、監控接收端 | +| 容器與叢集 | Docker compose、Harbor / registry、K8s manifest、ArgoCD、RBAC、Secret metadata、image pull、Pod scheduling | +| 供應鏈 | Gitea workflow、runner、deploy key、webhook、repo secret name、branch protection、CODEOWNERS、artifact / image source | +| 憑證與秘密 | secret value、token、cookie、private key、env dump、credential escrow、rotation decision、redaction attestation | +| 偵測與回應 | Wazuh manager / indexer / dashboard / API、agent status、rule / decoder、event refs、active response dry-run、Prometheus / Alertmanager / Grafana / SigNoz / Sentry / Langfuse | +| 資料與復原 | backup freshness、restore drill、offsite sync、remote delete guard、retention、rollback、cold-start / DR scorecard | +| 產品面 | AWOOOI、AwoooP、IwoooS、VibeWork、agent-bounty-protocol、stock / public websites、API、admin、webhook、AI provider route | +| 協作治理 | 多 Session 同步、維護窗口、break-glass、operator notification、postcheck、no-false-green、LOGBOOK / deploy marker | + +## 4. 固定數字 + +| 指標 | 數值 | +|------|------| +| prevention domain | `12` | +| control candidate | `14` | +| C0 control candidate | `10` | +| C1 control candidate | `4` | +| P0 control candidate | `14` | +| host alias | `4` | +| sensor alias | `1` | +| required owner fields | `36` | +| reviewer checks | `34` | +| outcome lanes | `12` | +| blocked actions | `82` | +| owner response received / accepted | `0 / 0` | +| prevention control accepted | `0` | +| Wazuh active response enabled | `0` | +| host write / firewall change / Nginx reload | `0 / 0 / 0` | +| package upgrade / active scan / production write | `0 / 0 / 0` | +| runtime gate / action button | `0 / 0` | + +## 5. P0 防堵候選優先序 + +| 優先 | 候選 | 狀態 | +|------|------|------| +| P0-1 | 公開入口 / Nginx 變更 freeze 與 source-to-live diff | `waiting_owner_prevention_packet` | +| P0-2 | SSH / sudo / authorized_keys / known_hosts 存取收斂 | `waiting_owner_prevention_packet` | +| P0-3 | 端口 / 防火牆 / WireGuard / NodePort baseline | `waiting_owner_prevention_packet` | +| P0-4 | Docker / systemd / process / persistence baseline | `waiting_owner_prevention_packet` | +| P0-5 | K8s / ArgoCD drift、RBAC 與 Secret metadata containment | `waiting_owner_prevention_packet` | +| P0-6 | Runner / workflow / deploy key / secret freeze | `waiting_owner_prevention_packet` | +| P0-7 | 疑似 credential exposure 的輪替決策 gate | `waiting_owner_prevention_packet` | +| P0-8 | Wazuh event triage 與事件分流 gate | `waiting_owner_prevention_packet` | +| P0-9 | Wazuh active response dry-run / blast radius / rollback | `waiting_owner_prevention_packet` | +| P0-10 | Backup / restore / rollback 可用性防堵 gate | `waiting_owner_prevention_packet` | +| P0-11 | 套件更新 / CVE 修補維護窗口候選 | `waiting_owner_prevention_packet` | +| P0-12 | 公開 / 後台 / API runtime auth 與 route guard | `waiting_owner_prevention_packet` | +| P0-13 | 監控 / 告警 / route 200 no-false-green gate | `waiting_owner_prevention_packet` | +| P0-14 | 跨專案 freeze、break-glass 與 operator sync | `waiting_owner_prevention_packet` | + +## 6. 必填 owner 欄位 + +每個防堵候選至少需要 owner role、owner team、decision、decision reason、affected scope aliases、exposed surface aliases、current risk、immediate harm if delayed、redacted evidence refs、Wazuh event refs、host forensic refs、config diff refs、before / after state、maintenance window、break-glass reason、rollback owner、rollback plan、validation metrics、postcheck owner、cross-project sync ref、communication channel、secret absence、raw payload absence、no internal-name publication、no-false-green、service / AI / monitoring / backup impact、recurrence guard、followup owner、expiry / review date 與 reviewer attestation。 + +未補齊前只能停在 `waiting_owner_prevention_packet`,不能進 runtime 防堵。 + +## 7. 拒收與隔離條件 + +1. 收到 password、private key、runner token、webhook secret、cookie、session、env dump、secret hash 或 partial token。 +2. 收到 raw Wazuh payload、raw syslog、raw journal、完整命令輸出、未脫敏截圖或可還原內部 IP / 帳號 namespace 的內容。 +3. 只有外部 Agent 宣稱已清除、已封鎖、已修復、已 Zero-Trust,但沒有 Wazuh event refs 與 host forensic refs。 +4. 只有 route `200`、dashboard up、agent active、container up、CD success、UI 可見或 alert quiet。 +5. 缺 maintenance window、rollback owner、validation metrics、postcheck owner 或跨專案同步。 + +## 8. 禁止動作 + +本階段明確阻擋 SSH / sudo、host live config read、Nginx test / reload / conf write、certbot renew、DNS / route / upstream / WebSocket change、iptables / firewall / WireGuard / NodePort / NetworkPolicy change、Docker / systemd / process / reboot、apt update / upgrade、Wazuh active response / agent / rule / decoder change、ArgoCD sync、kubectl、Helm、RBAC、K8s secret、workflow、runner、deploy key、webhook、repo secret、secret rotation、secret store read、raw payload storage、active scan、exploit validation、backup / restore / offsite sync、remote delete、retention change、database migration、production write、action button、runtime gate 與 force push。 + +## 9. 指令 + +產生 committed snapshot: + +```bash +python3 scripts/security/external-host-intrusion-prevention-control.py \ + --root . \ + --output docs/security/external-host-intrusion-prevention-control.snapshot.json \ + --generated-at 2026-06-18T15:30:00+08:00 +``` + +驗證 guard: + +```bash +python3 scripts/security/iwooos-config-control-guard.py --root . +python3 scripts/security/security-mirror-progress-guard.py --root . +``` + +## 10. 完成度 + +- 外部入侵防堵控制矩陣 / repo artifact:`100%` +- 前台可視化與脫敏 marker:`100%` +- owner response received / accepted:`0%` +- Wazuh event refs / host forensic refs accepted:`0%` +- containment decision / prevention control accepted:`0%` +- Wazuh active response enabled:`0%` +- host write / firewall change / Nginx reload / package upgrade / active scan:`0%` +- runtime gate / action button:`0%` + +下一步是把 14 個 P0 防堵候選交給 owner 補脫敏證據、維護窗口、rollback owner 與 postcheck。驗收前,IwoooS 不宣告主機已乾淨、木馬已清除、RCE 已修補、外部入侵已防堵,也不自動執行任何主機或網路變更。 diff --git a/docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md b/docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md index 94c1660f1..51677cb40 100644 --- a/docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md +++ b/docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md @@ -126,6 +126,14 @@ 此 artifact 明確拒收硬編碼 Wazuh URL / 使用者 / 密碼、關閉 TLS 驗證、raw Wazuh payload、raw log、private key、runner token、外部 Agent 口頭宣稱、agent active 當結案、route `200` 當恢復,以及任何未經批准的 active response、host write、firewall drop、process kill、runner / workflow / secret 變更。Wazuh event refs、host forensic refs、containment decision、recovery proof、postcheck、recurrence guard、read-only API enabled、active response、host write、runtime gate 與 action button 仍全部為 `0`。 +## 1.10 2026-06-18 外部入侵主機防堵控制矩陣 + +已新增 `docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md`、`docs/security/external-host-intrusion-prevention-control.snapshot.json` 與 `scripts/security/external-host-intrusion-prevention-control.py`,把公開入口、SSH、端口、防火牆、Nginx、runner、secret、Docker / systemd、K8s、Wazuh、套件更新、backup / restore、監控與跨專案同步收斂成同一張 P0 防堵矩陣。 + +固定 `prevention_domain_count=12`、`control_candidate_count=14`、`c0_control_candidate_count=10`、`host_alias_count=4`、`sensor_alias_count=1`、`required_owner_field_count=36`、`reviewer_check_count=34`、`outcome_lane_count=12`、`blocked_action_count=82`。此更新讓 `docker_compose_systemd_host_config` 從 `64%` 推進到 `68%`、`ssh_firewall_network_access` 從 `64%` 推進到 `70%`、`monitoring_alerting_observability` 從 `72%` 推進到 `74%`;高價值配置平均仍為 `72%`,因為 headline 與 runtime gate 不因框架補強而假性提高。 + +此 artifact 只建立防堵控制、拒收條件與 owner packet 欄位;owner response、evidence refs、prevention control accepted、containment decision、maintenance window、rollback plan、postcheck、Wazuh active response、host write、firewall change、Nginx reload、package upgrade、active scan、production write、runtime gate 與 action button 仍全部為 `0 / false`。 + ## 2. 覆蓋摘要 | 指標 | 目前值 | 說明 | @@ -135,8 +143,8 @@ | C1 類別 | `4` | 監控、Docker / systemd、SSH / network、AI provider | | C2 類別 | `1` | 產品 runtime route 與跨產品邊界 | | C3 類別 | `1` | security evidence / snapshot / guard tooling | -| 平均只讀控管成熟度 | `71%` | 僅代表框架 / evidence / owner packet / acceptance ledger / source guard / post-incident readback 準備度,不代表 runtime 可執行 | -| 需要 live / owner evidence 的類別 | `9` | 只能等 owner-provided redacted evidence 或維護窗口,不主動修改 workflow、secret、runner、route、CORS、env、備份或主機 | +| 平均只讀控管成熟度 | `72%` | 僅代表框架 / evidence / owner packet / acceptance ledger / source guard / post-incident readback / 防堵控制矩陣準備度,不代表 runtime 可執行 | +| 需要 live / owner evidence 的類別 | `10` | 只能等 owner-provided redacted evidence 或維護窗口,不主動修改 workflow、secret、runner、route、CORS、env、備份或主機 | | owner response required | `14` | 每類都需要 owner response 才能往 accepted 前進 | | owner response received / accepted | `0 / 0` | 不得假性提高 | | runtime gate | `0` | 不得產生執行按鈕 | @@ -145,12 +153,12 @@ | 優先 | 類別 | 目前成熟度 | 下一步 | |------|------|------------|--------| -| P1-1 | Docker Compose / systemd / host service config | `64%` | repo-only 清冊、owner response acceptance、host service change evidence acceptance 與 post-incident readback plan 已納入 9 個 surface;重啟 actor、boot / recovery window、before / after、Docker daemon、compose / systemd、failed unit、port binding、dependency、public/admin route recovery、AI provider、monitoring、operator notification、cross-project sync、防再發與 no-false-green 已納入;仍缺 owner response、live hash、事故回讀包、maintenance / restart window、rollback owner、post-check plan、disable switch 與 no-secret-value evidence | -| P1-2 | SSH / sudoers / known_hosts / firewall / WireGuard / NodePort | `64%` | repo-only 清冊已納入 16 個 SSH / network access surface,owner response acceptance、事故型端口 / 防火牆變更證據驗收與 post-incident readback plan 已完成;仍缺 owner-provided change / incident ref、actor、before / after state、health impact、notification、cross-project sync、maintenance window、rollback owner 與 post-check evidence | +| P1-1 | Docker Compose / systemd / host service config | `68%` | repo-only 清冊、owner response acceptance、host service change evidence acceptance、post-incident readback plan 與外部入侵防堵矩陣已納入;主機 runtime、process、port binding、package、persistence、AI provider、monitoring、operator notification、cross-project sync、防再發與 no-false-green 已納入;仍缺 owner response、live hash、Wazuh / host forensic refs、maintenance / restart window、rollback owner、post-check plan、disable switch 與 no-secret-value evidence | +| P1-2 | SSH / sudoers / known_hosts / firewall / WireGuard / NodePort | `70%` | repo-only 清冊、owner response acceptance、端口 / 防火牆變更證據驗收、post-incident readback plan 與外部入侵防堵矩陣已固定;SSH / sudo、known_hosts、firewall、WireGuard、NodePort、NetworkPolicy、before / after state、break-glass 與維護窗口皆已納入;仍缺 owner-provided change / incident ref、actor、Wazuh / host forensic refs、service impact、notification、cross-project sync、maintenance window、rollback owner 與 post-check evidence | | P1-3 | AI provider / model routing / Ollama proxy / cost and privacy | `64%` | 已新增 owner response acceptance 帳本,固定 8 個候選、24 個 owner 必填欄位、24 個 reviewer checks、10 條 outcome lanes、38 類 blocked actions;仍缺 provider owner、fallback order、dry-run、benchmark、cost review、privacy review、data classification、prompt redaction、quality gate、rollback owner 與 post-check evidence,不切 production | -| P1-4 | K8s / ArgoCD / production manifests | `64%` | manifest inventory、owner response acceptance 與 GitOps change evidence acceptance 已完成;仍缺 proposed commit ref、rendered manifest diff、ArgoCD app / sync revision、health before / after、rollout、route smoke、metrics / alert、blast radius、rollback revision、maintenance window 與 post-check owner | +| P1-4 | K8s / ArgoCD / production manifests | `66%` | manifest inventory、owner response acceptance、GitOps change evidence acceptance 與 post-incident readback plan 已完成;仍缺 proposed commit ref、rendered manifest diff、ArgoCD app / sync revision、health before / after、rollout、route smoke、metrics / alert、blast radius、rollback revision、maintenance window 與 post-check owner | | P1-5 | Backup / restore / escrow / retention | `66%` | repo-only 清冊、owner response acceptance 與事故後回讀計畫已納入 38 個 surface;freshness before-after、backup status readback、restore drill、offsite sync、credential escrow non-secret proof、retention runway、cold-start scorecard、防再發與 no-false-green 已納入;仍缺 owner response、事故回讀包、restore drill approval package、offsite / escrow owner、rollback owner、validation plan 與 no-secret-value evidence | -| P1-6 | Wazuh / 主機入侵 / Prometheus / Alertmanager / Grafana / SigNoz / Sentry / Langfuse | `72%` | repo-only 清冊、owner response acceptance、事故後回讀計畫與 Wazuh / 主機入侵 readback plan 已納入;Wazuh 控制面、host-110 / host-188、外部 Agent 宣稱、Runner / secret / gateway 連動、containment / recovery proof 已進入 P0 回讀;仍缺 Wazuh event refs、host forensic refs、containment decision、recovery proof、postcheck、owner response、noise budget owner 與 maintenance window | +| P1-6 | Wazuh / 主機入侵 / Prometheus / Alertmanager / Grafana / SigNoz / Sentry / Langfuse | `74%` | repo-only 清冊、owner response acceptance、事故後回讀計畫、Wazuh / 主機入侵 readback plan 與外部入侵防堵矩陣已納入;Wazuh 控制面、host alias、外部 Agent 宣稱、Runner / secret / gateway 連動、active response dry-run、containment / recovery proof 已進入 P0 防堵候選;仍缺 Wazuh event refs、host forensic refs、containment decision、recovery proof、postcheck、owner response、noise budget owner 與 maintenance window | ## 4. 固定 0 / false 邊界 @@ -287,6 +295,7 @@ python3 scripts/security/iwooos-config-control-guard.py --root . | Monitoring / alerting / observability owner response acceptance backfill | `100%` | 已將 `monitoring_owner_response_acceptance_v1` 補強為 60 個 candidate、11 個 write-capable、38 個 acceptance fields、23 個 reviewer checks、12 條 outcome lanes、34 類 blocked action;monitoring / alerting / observability 成熟度 `66% -> 68%` | | Monitoring / alerting / observability post-incident readback plan | `100%` | 已新增 `monitoring_post_incident_readback_plan_v1`,60 個事故回讀 candidate、11 個 write-capable、30 個必填欄位、28 個 reviewer checks、11 條 outcome lanes、53 類 blocked action;成熟度 `68% -> 70%`,readback received / accepted、receiver receipt、stale / silence、alert chain health、reload、Telegram send、alert chain smoke 與 runtime gate 仍為 `0` | | Wazuh / 主機入侵 readback plan | `100%` | 已新增 `wazuh_iwooos_intrusion_readback_plan_v1`,6 個 P0 candidate、2 個 host alias、30 個必填欄位、24 個 reviewer checks、12 條 outcome lanes、49 類 blocked action;monitoring / alerting / observability 成熟度 `70% -> 72%`,Wazuh event、主機鑑識、containment、recovery proof、active response、host write 與 runtime gate 仍為 `0` | +| 外部入侵主機防堵控制矩陣 | `100%` | 已新增 `external_host_intrusion_prevention_control_v1`,12 個控制域、14 個 P0 防堵候選、4 個 host alias、1 個 sensor alias、36 個 owner 必填欄位、34 個 reviewer checks、12 條 outcome lanes、82 類 blocked action;Docker / systemd 成熟度 `64% -> 68%`、SSH / firewall 成熟度 `64% -> 70%`、monitoring / Wazuh 成熟度 `72% -> 74%`;Wazuh active response、host write、firewall change、Nginx reload、package upgrade、active scan、runtime gate 與 action button 仍為 `0` | | AI provider / model routing owner response acceptance | `100%` | 已新增 `ai_provider_owner_response_acceptance_v1`,8 個 candidate、5 個 write-capable、24 個 owner 必填欄位、24 個 reviewer checks、10 條 outcome lanes、38 類 blocked action;AI provider / model routing 成熟度 `60% -> 64%` | | Public Gateway / Nginx post-incident readback plan | `100%` | 已新增 `public_gateway_post_incident_readback_plan_v1`,3 個事故回讀 candidate、2 個 C0、30 個必填欄位、28 個 reviewer checks、10 條 outcome lanes、41 類 blocked action;成熟度 `90% -> 92%`,readback received / accepted、`nginx -t`、reload、route smoke、DNS / TLS、certbot 與 runtime gate 仍為 `0` | | SSH / firewall / network post-incident readback plan | `100%` | 已新增 `ssh_network_post_incident_readback_plan_v1`,14 個事故回讀 candidate、6 個 write-capable、24 個必填欄位、24 個 reviewer checks、10 條 outcome lanes、34 類 blocked action;成熟度 `62% -> 64%`,readback received / accepted、actor、before / after、impact、通知、同步、恢復、防再發與 runtime gate 仍為 `0` | diff --git a/docs/security/IWOOOS-POSTURE-PROJECTION.md b/docs/security/IWOOOS-POSTURE-PROJECTION.md index 15cab49bc..8afbacb4f 100644 --- a/docs/security/IWOOOS-POSTURE-PROJECTION.md +++ b/docs/security/IWOOOS-POSTURE-PROJECTION.md @@ -3,7 +3,7 @@ | 項目 | 內容 | |------|------| | 日期 | 2026-06-18 | -| 狀態 | 草案;P0 governance 總帳已建立;高價值配置 Owner Packet count sync、K8s / ArgoCD、Public Gateway / Nginx、Monitoring、CD / Runner / Secret 與 Backup / Restore / Escrow 事故後回讀投影已完成 | +| 狀態 | 草案;P0 governance 總帳已建立;高價值配置 Owner Packet count sync、K8s / ArgoCD、Public Gateway / Nginx、Monitoring、CD / Runner / Secret、Backup / Restore / Escrow、Wazuh / 主機入侵與外部入侵防堵控制投影已完成 | | Schema | `docs/schemas/iwooos_posture_projection_v1.schema.json` | | Snapshot | `docs/security/iwooos-posture-projection.snapshot.json` | | 模式 | `mirror_only` | @@ -53,6 +53,12 @@ 此同步只代表前端可以顯示 Backup / Restore / Escrow 事故後回讀計畫與邊界;`post_incident_readback_received_count`、`post_incident_readback_accepted_count`、`backup_status_readback_accepted_count`、`restore_drill_readback_accepted_count`、`offsite_sync_readback_accepted_count`、`credential_escrow_non_secret_readback_accepted_count`、`retention_runway_readback_accepted_count`、`backup_health_no_false_green_readback_accepted_count`、`runtime_gate_count` 與 `action_button_count` 仍全部維持 `0`。不得把備份排程存在、route `200`、冷啟動分數、UI 可見或文件齊備視為 backup / restore / DR 資安驗收。 +## 1.7 2026-06-18 外部入侵主機防堵控制投影 + +`external_host_intrusion_prevention_control_v1` 已投影到 `iwooos-posture-projection.snapshot.json` 與前台 marker。固定 `prevention_domain_count=12`、`control_candidate_count=14`、`c0_control_candidate_count=10`、`host_alias_count=4`、`sensor_alias_count=1`、`required_owner_field_count=36`、`reviewer_check_count=34`、`outcome_lane_count=12`、`blocked_action_count=82`,並讓 `docker_compose_systemd_host_config_coverage_percent=68`、`ssh_firewall_network_access_coverage_percent=70`、`monitoring_alerting_observability_coverage_percent=74`。 + +此同步只代表前端可以顯示外部入侵防堵候選、優先序、拒收條件與 0 / false 邊界;`owner_response_received_count`、`owner_response_accepted_count`、`evidence_ref_received_count`、`evidence_ref_accepted_count`、`prevention_control_accepted_count`、`wazuh_active_response_enabled_count`、`host_write_authorized_count`、`firewall_change_authorized_count`、`nginx_reload_authorized_count`、`package_upgrade_authorized_count`、`active_scan_authorized_count`、`runtime_gate_count` 與 `action_button_count` 仍全部維持 `0`。不得把這張矩陣解讀成已封鎖端口、已改防火牆、已重啟主機、已更新套件、已清除木馬或已啟用 Wazuh active response。 + ## 2. 來源 IwoooS 首版只讀取或對齊以下已提交 evidence: @@ -68,6 +74,7 @@ IwoooS 首版只讀取或對齊以下已提交 evidence: | `monitoring_post_incident_readback_plan_v1` | Monitoring / Alerting / Observability 事故後回讀計畫、70% 子項成熟度、30 個必填欄位、53 類 blocked action、runtime gate 0 | | `cd_runner_secret_injection_post_incident_readback_plan_v1` | CD / Runner / Secret injection 事故後回讀計畫、secret metadata 70%、workflow / runner 74%、33 個必填欄位、52 類 blocked action、runtime gate 0 | | `backup_restore_post_incident_readback_plan_v1` | Backup / Restore / Escrow 事故後回讀計畫、66% 子項成熟度、34 個必填欄位、51 類 blocked action、runtime gate 0 | +| `external_host_intrusion_prevention_control_v1` | 外部入侵主機防堵控制矩陣、12 個控制域、14 個 P0 防堵候選、36 個 owner 必填欄位、82 類 blocked action、runtime gate 0 | | `kali_integration_status_v1` | Kali 112 observe-only 整合態勢 | | `vibework_iwooos_onboarding_handoff_v1` | VibeWork repo / product / surface / owner / evidence refs / 獨立產品邊界只讀 handoff | | `docs/LOGBOOK.md` | 部署 marker、Gitea run 與 rollout risk 邊界紀錄 | diff --git a/docs/security/external-host-intrusion-prevention-control.snapshot.json b/docs/security/external-host-intrusion-prevention-control.snapshot.json new file mode 100644 index 000000000..226abf462 --- /dev/null +++ b/docs/security/external-host-intrusion-prevention-control.snapshot.json @@ -0,0 +1,3519 @@ +{ + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "control_candidates": [ + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:public_gateway_freeze_diff", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "公開入口 / Nginx 變更 freeze 與 source-to-live diff", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "public_ingress_gateway", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": true, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": false, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": false, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "public-gateway", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:ssh_sudo_access_lockdown", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "SSH / sudo / authorized_keys / known_hosts 存取收斂", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "ssh_sudo_access", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": true, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": true, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": true, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "ssh-sudo-access", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:firewall_port_baseline_guard", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "端口 / 防火牆 / WireGuard / NodePort baseline", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "firewall_network_policy", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": true, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": true, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": true, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "firewall-port-baseline", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:host_service_persistence_baseline", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "Docker / systemd / process / persistence baseline", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "host_runtime_services", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": true, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": true, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": true, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "host-service-persistence", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:k8s_argocd_drift_containment", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "K8s / ArgoCD drift、RBAC 與 Secret metadata containment", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "k8s_gitops_runtime", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": true, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": false, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": false, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "k8s-argocd-drift", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:runner_workflow_secret_freeze", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "Runner / workflow / deploy key / secret freeze", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "runner_workflow_supply_chain", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": true, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": true, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": true, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "runner-workflow-secret-freeze", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:credential_exposure_rotation_gate", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "疑似 credential exposure 的輪替決策 gate", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "secret_credential_exposure", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": true, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": true, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": true, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "credential-exposure", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:wazuh_event_triage_gate", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "Wazuh event triage 與事件分流 gate", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "wazuh_detection_response", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": false, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": false, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": true, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "wazuh-event-triage", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:wazuh_active_response_dry_run", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "Wazuh active response dry-run / blast radius / rollback", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "wazuh_detection_response", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": false, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": true, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": true, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "wazuh-active-response-dry-run", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:backup_restore_recovery_gate", + "control_tier": "C0", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "Backup / restore / rollback 可用性防堵 gate", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "backup_restore_resilience", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": true, + "requires_config_diff_refs": false, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": false, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": false, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "backup-restore-recovery", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:package_patch_window", + "control_tier": "C1", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "套件更新 / CVE 修補維護窗口候選", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "package_patch_vulnerability", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": false, + "requires_config_diff_refs": false, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": false, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": false, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "package-patch-window", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:public_runtime_auth_route_guard", + "control_tier": "C1", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "公開 / 後台 / API runtime auth 與 route guard", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "public_ingress_gateway", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": false, + "requires_config_diff_refs": true, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": false, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": false, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "public-runtime-auth-route", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:monitoring_no_false_green_gate", + "control_tier": "C1", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "監控 / 告警 / route 200 no-false-green gate", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "monitoring_alerting_false_green", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": false, + "requires_config_diff_refs": false, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": false, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": false, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "monitoring-no-false-green", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + }, + { + "action_buttons_allowed": false, + "blocked_actions": [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push" + ], + "config_diff_refs": [], + "control_id": "external_host_prevention:cross_project_break_glass_sync", + "control_tier": "C1", + "cross_project_sync_ref": null, + "followup_owner": "pending_owner_response", + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "host_forensic_refs": [], + "label": "跨專案 freeze、break-glass 與 operator sync", + "maintenance_window": "pending_owner_response", + "not_authorization": true, + "outcome_lanes": [ + "waiting_owner_prevention_packet", + "request_wazuh_event_supplement", + "request_host_forensics_supplement", + "request_config_diff_supplement", + "request_maintenance_window", + "request_break_glass_record", + "quarantine_secret_or_raw_payload", + "reject_claim_without_evidence", + "route_to_high_value_config_gate", + "ready_for_prevention_reviewer_review", + "waiting_runtime_authorization", + "blocked_no_rollback_or_postcheck" + ], + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "postcheck_ref": null, + "prevention_domain": "cross_project_freeze_sync", + "priority": "P0", + "redacted_evidence_refs": [], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "requires_break_glass_record": false, + "requires_config_diff_refs": false, + "requires_cross_project_sync": true, + "requires_host_forensics_refs": false, + "requires_maintenance_window": true, + "requires_owner_approval": true, + "requires_rollback_plan": true, + "requires_validation_plan": true, + "requires_wazuh_event_refs": false, + "reviewer_checks": [ + "scope_alias_only", + "owner_role_and_team_present", + "decision_and_reason_present", + "wazuh_event_refs_required_for_intrusion", + "host_forensic_refs_required", + "gateway_diff_required", + "firewall_before_after_required", + "ssh_sudo_scope_required", + "runner_workflow_diff_required", + "secret_values_absent", + "raw_payload_absent", + "maintenance_window_required", + "rollback_owner_required", + "validation_metrics_required", + "cross_project_sync_required", + "no_false_green", + "external_agent_claim_not_trusted", + "active_response_dry_run_first", + "firewall_change_break_glass_only", + "host_service_write_blocked", + "k8s_argocd_write_blocked", + "backup_restore_not_assumed", + "credential_rotation_requires_decision", + "package_upgrade_requires_window", + "public_frontend_no_internal_transcript", + "production_write_stays_zero", + "evidence_refs_redacted", + "parallel_session_conflict_checked", + "service_dependency_map_present", + "operator_notification_present", + "postcheck_independent", + "recurrence_guard_present", + "expiry_or_review_date_present", + "counts_transition_safe" + ], + "reviewer_outcome": "waiting_prevention_reviewer_review", + "rollback_owner": "pending_owner_response", + "runtime_gate": false, + "scope_alias": "cross-project-break-glass-sync", + "sensor_aliases": [ + "sensor-kali-112" + ], + "status": "waiting_owner_prevention_packet", + "validation_metric_refs": [], + "wazuh_event_refs": [] + } + ], + "execution_boundaries": { + "action_buttons_allowed": false, + "active_scan_authorized": false, + "argocd_sync_authorized": false, + "backup_run_authorized": false, + "certbot_renew_authorized": false, + "dns_tls_change_authorized": false, + "docker_restart_authorized": false, + "firewall_change_authorized": false, + "frontend_internal_transcript_display_allowed": false, + "host_isolation_authorized": false, + "host_live_config_read_authorized": false, + "host_read_authorized": false, + "host_write_authorized": false, + "kubectl_action_authorized": false, + "nginx_reload_authorized": false, + "nginx_test_authorized": false, + "not_authorization": true, + "package_upgrade_authorized": false, + "port_close_authorized": false, + "port_open_authorized": false, + "process_kill_authorized": false, + "production_write_authorized": false, + "raw_payload_storage_allowed": false, + "reboot_authorized": false, + "repo_secret_change_authorized": false, + "restore_run_authorized": false, + "runner_change_authorized": false, + "runtime_execution_authorized": false, + "secret_rotation_authorized": false, + "secret_value_collection_allowed": false, + "ssh_read_authorized": false, + "ssh_write_authorized": false, + "sudo_action_authorized": false, + "systemctl_restart_authorized": false, + "wazuh_active_response_authorized": false, + "wazuh_api_live_query_authorized": false, + "wazuh_rule_change_authorized": false, + "workflow_modification_authorized": false + }, + "generated_at": "2026-06-18T15:30:00+08:00", + "git_commit": "efde1097", + "mode": "control_matrix_only_no_host_write_no_firewall_change_no_active_response", + "operator_interpretation": [ + "這份矩陣把外部入侵防堵前移成 P0 控制候選,但不是 host write 或 firewall change 授權。", + "IwoooS 先拒收假綠燈:route 200、dashboard up、CD success、UI 可見、agent active 或外部 Agent 宣稱都不能單獨當成已防堵。", + "真正能進 runtime 的防堵需 owner role / team、decision reason、維護窗口、rollback owner、validation metrics、postcheck 與跨專案同步。", + "前台只能顯示 alias、候選數、缺口與 0/false 邊界,不顯示內網 IP、帳號 namespace、raw log、secret 或工作視窗內容。" + ], + "outcome_lanes": [ + { + "lane_id": "waiting_owner_prevention_packet", + "meaning": "防堵候選已建立,等待 owner 補齊欄位與脫敏證據。" + }, + { + "lane_id": "request_wazuh_event_supplement", + "meaning": "缺 Wazuh event / alert refs 時要求補件。" + }, + { + "lane_id": "request_host_forensics_supplement", + "meaning": "缺主機鑑識 refs 時要求補件。" + }, + { + "lane_id": "request_config_diff_supplement", + "meaning": "缺 Nginx、firewall、runner、workflow、K8s 或 secret metadata diff 時要求補件。" + }, + { + "lane_id": "request_maintenance_window", + "meaning": "涉及服務中斷、重啟、封鎖、更新或 active response 時要求維護窗口。" + }, + { + "lane_id": "request_break_glass_record", + "meaning": "即時封鎖或緊急變更需補 break-glass reason 與通知紀錄。" + }, + { + "lane_id": "quarantine_secret_or_raw_payload", + "meaning": "收到 secret、raw log、raw payload、env dump 或未脫敏截圖時隔離。" + }, + { + "lane_id": "reject_claim_without_evidence", + "meaning": "只有外部宣稱、route 200、dashboard up 或 agent active 時拒收。" + }, + { + "lane_id": "route_to_high_value_config_gate", + "meaning": "涉及高價值配置時串到既有配置控管 gate。" + }, + { + "lane_id": "ready_for_prevention_reviewer_review", + "meaning": "metadata 合格後進 reviewer review,不自動執行。" + }, + { + "lane_id": "waiting_runtime_authorization", + "meaning": "即使 accepted,也需獨立批准才可進 runtime 防堵。" + }, + { + "lane_id": "blocked_no_rollback_or_postcheck", + "meaning": "缺 rollback owner、validation 或 postcheck 時不得進下一關。" + } + ], + "prevention_domains": [ + { + "control_tier": "C0", + "domain_id": "public_ingress_gateway", + "immediate_risk": "未受控 reload、route drift、上游錯配或 TLS / ACME 變更會造成外部暴露或服務中斷。", + "label": "公開入口 / DNS / TLS / Nginx / public gateway" + }, + { + "control_tier": "C0", + "domain_id": "ssh_sudo_access", + "immediate_risk": "未受控登入、sudo 權限、host key 漂移或跳板憑證會擴大入侵面。", + "label": "SSH / sudo / authorized_keys / known_hosts" + }, + { + "control_tier": "C0", + "domain_id": "firewall_network_policy", + "immediate_risk": "端口開關、內網路由、NodePort 或 NetworkPolicy 漂移會直接改變可攻擊面。", + "label": "Firewall / WireGuard / NodePort / NetworkPolicy" + }, + { + "control_tier": "C0", + "domain_id": "host_runtime_services", + "immediate_risk": "容器重啟、failed unit、未知 process、port binding 或 persistence 會影響服務與入侵駐留判讀。", + "label": "Docker / systemd / process / port binding" + }, + { + "control_tier": "C0", + "domain_id": "k8s_gitops_runtime", + "immediate_risk": "GitOps drift、RBAC / Secret metadata、image pull 或 pending workload 可能隱藏惡意部署與供應鏈變更。", + "label": "K8s / ArgoCD / RBAC / Secret metadata" + }, + { + "control_tier": "C0", + "domain_id": "runner_workflow_supply_chain", + "immediate_risk": "runner、workflow、deploy key 或 webhook 被改動會直接打開 production 寫入路徑。", + "label": "Gitea runner / workflow / deploy key / webhook" + }, + { + "control_tier": "C0", + "domain_id": "secret_credential_exposure", + "immediate_risk": "secret、session、API token 或 env dump 外洩會讓修復失效並擴散到其他產品。", + "label": "Secret / session / API token / credential hygiene" + }, + { + "control_tier": "C0", + "domain_id": "wazuh_detection_response", + "immediate_risk": "偵測與 response 邊界不清會造成假綠燈、誤隔離、漏封鎖或錯信外部宣稱。", + "label": "Wazuh manager / agent / rule / active response" + }, + { + "control_tier": "C1", + "domain_id": "package_patch_vulnerability", + "immediate_risk": "未修補套件與服務版本過舊會保留可利用入口,但無維護窗口直接升級也會造成中斷。", + "label": "套件更新 / CVE / maintenance window" + }, + { + "control_tier": "C1", + "domain_id": "backup_restore_resilience", + "immediate_risk": "沒有可驗證 restore 與 rollback,入侵後清除、重建與服務恢復都沒有可信退路。", + "label": "Backup / restore / offsite / escrow / rollback" + }, + { + "control_tier": "C1", + "domain_id": "monitoring_alerting_false_green", + "immediate_risk": "route 200、dashboard up 或 alert quiet 若被當成資安通過,會掩蓋持久化與告警失效。", + "label": "Monitoring / alerting / no-false-green" + }, + { + "control_tier": "C1", + "domain_id": "cross_project_freeze_sync", + "immediate_risk": "多 session 或多專案並行修改會造成重複修復、rebase 衝突、錯誤 reload 或未同步封鎖。", + "label": "跨專案 freeze / operator sync / break-glass" + } + ], + "required_owner_fields": [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation" + ], + "reviewer_checks": [ + { + "check_id": "scope_alias_only", + "instruction": "只接受 host alias、service alias、product alias;不得公開內網 IP、帳號 namespace 或 repo owner 原名。" + }, + { + "check_id": "owner_role_and_team_present", + "instruction": "每個防堵候選都需要 owner role / team,不能匿名批准。" + }, + { + "check_id": "decision_and_reason_present", + "instruction": "需要明確 decision 與 decision reason;不得只寫批准或已處理。" + }, + { + "check_id": "wazuh_event_refs_required_for_intrusion", + "instruction": "主機入侵、惡意程式或 RCE 類候選必須有 Wazuh event refs。" + }, + { + "check_id": "host_forensic_refs_required", + "instruction": "需要 auth、process、network、FIM、package 或 persistence refs;服務恢復不能取代鑑識。" + }, + { + "check_id": "gateway_diff_required", + "instruction": "公開入口、Nginx、TLS、route 或 upstream 變更需有 source-to-live diff refs。" + }, + { + "check_id": "firewall_before_after_required", + "instruction": "端口、防火牆、WireGuard、NodePort 或 NetworkPolicy 需有 before / after state。" + }, + { + "check_id": "ssh_sudo_scope_required", + "instruction": "SSH、sudo、deploy key 或 known_hosts 需標示範圍與回滾 owner。" + }, + { + "check_id": "runner_workflow_diff_required", + "instruction": "runner、workflow、webhook 或 deploy key 需有 diff、run ref、permission scope 與 workspace cleanup。" + }, + { + "check_id": "secret_values_absent", + "instruction": "不得收 secret value、hash、partial token、cookie、env dump、private key 或 runner token。" + }, + { + "check_id": "raw_payload_absent", + "instruction": "不得保存 raw Wazuh payload、raw log、raw journal、完整命令輸出或未脫敏截圖。" + }, + { + "check_id": "maintenance_window_required", + "instruction": "任何可能中斷服務的防堵都需要 maintenance window。" + }, + { + "check_id": "rollback_owner_required", + "instruction": "任何 host、gateway、firewall、runner、K8s 或 secret 相關候選都需要 rollback owner。" + }, + { + "check_id": "validation_metrics_required", + "instruction": "防堵後驗證需列 route、API、agent、alert、backup 或 service health 指標。" + }, + { + "check_id": "cross_project_sync_required", + "instruction": "影響 AWOOOI、AwoooP、IwoooS、VibeWork、agent-bounty-protocol、stock 或監控需有同步 ref。" + }, + { + "check_id": "no_false_green", + "instruction": "route 200、dashboard up、agent active、CD success、UI 可見都不能單獨當資安驗收。" + }, + { + "check_id": "external_agent_claim_not_trusted", + "instruction": "外部 Agent 宣稱已封鎖、清除或 Zero-Trust 不能直接 accepted。" + }, + { + "check_id": "active_response_dry_run_first", + "instruction": "Wazuh active response 必須先 dry-run、驗證 blast radius 與 rollback,不得直接 production enable。" + }, + { + "check_id": "firewall_change_break_glass_only", + "instruction": "firewall drop、port close/open 需 break-glass 或 maintenance window,不得由候選自動執行。" + }, + { + "check_id": "host_service_write_blocked", + "instruction": "不得由本 artifact 觸發 Docker、systemd、kill process、package upgrade 或 reboot。" + }, + { + "check_id": "k8s_argocd_write_blocked", + "instruction": "不得由本 artifact 觸發 ArgoCD sync、kubectl、Helm、NetworkPolicy 或 RBAC apply。" + }, + { + "check_id": "backup_restore_not_assumed", + "instruction": "備份存在、冷啟動分數或 UI 可見不能代表 restore / rollback 可用。" + }, + { + "check_id": "credential_rotation_requires_decision", + "instruction": "credential rotation 需 owner decision、blast radius、dependent services 與 rollback plan。" + }, + { + "check_id": "package_upgrade_requires_window", + "instruction": "套件更新、kernel、Docker、Nginx、Wazuh agent 或 Kali 更新需維護窗口與 postcheck。" + }, + { + "check_id": "public_frontend_no_internal_transcript", + "instruction": "前台不得顯示工作視窗、內部對話、抱怨、raw namespace 或截圖原文。" + }, + { + "check_id": "production_write_stays_zero", + "instruction": "防堵矩陣不是 production write 授權;runtime gate 與 action button 必須維持 0。" + }, + { + "check_id": "evidence_refs_redacted", + "instruction": "只收脫敏 ref、ticket、artifact pointer;不得貼 raw secret 或 raw payload。" + }, + { + "check_id": "parallel_session_conflict_checked", + "instruction": "需確認其他 session 是否正在操作同一主機、Nginx、runner、workflow 或 secret。" + }, + { + "check_id": "service_dependency_map_present", + "instruction": "端口、gateway、host service 或 AI provider 變更需列服務依賴與受影響產品 alias。" + }, + { + "check_id": "operator_notification_present", + "instruction": "即時危害或可能中斷的防堵需有 operator notification / receipt plan。" + }, + { + "check_id": "postcheck_independent", + "instruction": "postcheck 必須由獨立於操作人的 reviewer 或 automation readback 驗證。" + }, + { + "check_id": "recurrence_guard_present", + "instruction": "需補防再發 guard,例如 config drift、runner freeze、secret hygiene、Wazuh rule coverage 或 firewall diff guard。" + }, + { + "check_id": "expiry_or_review_date_present", + "instruction": "臨時 freeze、break-glass 或例外需有到期或複審日期。" + }, + { + "check_id": "counts_transition_safe", + "instruction": "received / accepted / authorized / executed / allowed 類計數只能由正式驗收推進。" + } + ], + "schema_version": "external_host_intrusion_prevention_control_v1", + "source_context": { + "external_agent_claim_accepted_without_evidence": false, + "host_aliases": [ + "host-110", + "host-188", + "dev-host-111", + "dev-host-168" + ], + "raw_ip_or_account_namespace_published_to_frontend": false, + "runtime_prevention_enabled": false, + "sensor_aliases": [ + "sensor-kali-112" + ], + "work_session_transcript_published_to_frontend": false + }, + "status": "external_host_intrusion_prevention_control_ready_no_runtime_action", + "summary": { + "action_button_count": 0, + "active_scan_authorized_count": 0, + "argocd_sync_authorized_count": 0, + "backup_restore_required_candidate_count": 1, + "blocked_action_count": 82, + "break_glass_required_candidate_count": 10, + "c0_control_candidate_count": 10, + "c1_control_candidate_count": 4, + "config_diff_required_candidate_count": 8, + "containment_decision_accepted_count": 0, + "control_candidate_count": 14, + "coverage_percent_after_prevention_control": 74, + "cross_project_sync_required_candidate_count": 14, + "docker_compose_systemd_host_config_coverage_percent_after_prevention_control": 68, + "docker_restart_authorized_count": 0, + "evidence_ref_accepted_count": 0, + "evidence_ref_received_count": 0, + "firewall_change_authorized_count": 0, + "host_alias_count": 4, + "host_forensics_required_candidate_count": 6, + "host_write_authorized_count": 0, + "maintenance_window_accepted_count": 0, + "maintenance_window_required_candidate_count": 14, + "monitoring_alerting_observability_coverage_percent_after_prevention_control": 74, + "nginx_reload_authorized_count": 0, + "no_false_green_required_candidate_count": 14, + "outcome_lane_count": 12, + "owner_approval_required_candidate_count": 14, + "owner_response_accepted_count": 0, + "owner_response_received_count": 0, + "p0_control_candidate_count": 14, + "package_upgrade_authorized_count": 0, + "postcheck_accepted_count": 0, + "prevention_control_accepted_count": 0, + "prevention_domain_count": 12, + "production_write_authorized_count": 0, + "repo_secret_change_authorized_count": 0, + "required_owner_field_count": 36, + "reviewer_check_count": 34, + "rollback_plan_accepted_count": 0, + "rollback_required_candidate_count": 14, + "runner_change_authorized_count": 0, + "runtime_gate_count": 0, + "secret_value_collection_allowed_count": 0, + "sensor_alias_count": 1, + "ssh_firewall_network_access_coverage_percent_after_prevention_control": 70, + "ssh_write_authorized_count": 0, + "systemctl_restart_authorized_count": 0, + "urgent_prevention_candidate_count": 14, + "validation_required_candidate_count": 14, + "wazuh_active_response_enabled_count": 0, + "wazuh_event_required_candidate_count": 7, + "workflow_modification_authorized_count": 0 + } +} diff --git a/docs/security/high-value-config-control-coverage.snapshot.json b/docs/security/high-value-config-control-coverage.snapshot.json index 28fe1bf27..12d843e67 100644 --- a/docs/security/high-value-config-control-coverage.snapshot.json +++ b/docs/security/high-value-config-control-coverage.snapshot.json @@ -336,9 +336,9 @@ "action_buttons_allowed": false, "category_id": "monitoring_alerting_observability", "control_tier": "C1", - "coverage_percent": 72, - "coverage_status": "wazuh_intrusion_readback_plan_ready_needs_wazuh_owner_evidence", - "current_gap": "已固定 60 份 monitoring / alerting / observability owner response acceptance candidate、事故後回讀計畫,並新增 Wazuh / 主機入侵 readback plan;Wazuh 平台、host-110 / host-188 入侵訊號、外部 Agent live 變更宣稱、Runner / secret / gateway 連動、containment / recovery proof、hardcoded credential 拒收與 active response 邊界已納入;仍缺 Wazuh manager health ref、agent status ref、Wazuh event refs、host forensic refs、containment decision、recovery proof、postcheck、recurrence guard、owner response 與 maintenance window。", + "coverage_percent": 74, + "coverage_status": "external_host_intrusion_prevention_control_ready_needs_wazuh_owner_evidence", + "current_gap": "已固定 60 份 monitoring / alerting / observability owner response acceptance candidate、事故後回讀計畫、Wazuh / 主機入侵 readback plan,並新增外部入侵主機防堵控制矩陣;Wazuh 平台、host alias 入侵訊號、外部 Agent live 變更宣稱、Runner / secret / gateway 連動、active response dry-run、防再發與 no-false-green 已納入;仍缺 Wazuh manager health ref、agent status ref、Wazuh event refs、host forensic refs、containment decision、recovery proof、postcheck、recurrence guard、owner response 與 maintenance window。", "evidence_refs": [ "docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md", "docs/security/MONITORING-ALERTING-OBSERVABILITY-INVENTORY.md", @@ -352,11 +352,14 @@ "docs/security/WAZUH-IWOOOS-INTRUSION-READBACK-PLAN.md", "docs/security/wazuh-iwooos-intrusion-readback-plan.snapshot.json", "scripts/security/wazuh-iwooos-intrusion-readback-plan.py", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", "apps/web/src/app/api/iwooos/wazuh/route.ts", "docs/schemas/monitoring_alerting_observability_inventory_v1.schema.json" ], "label": "Prometheus / Alertmanager / Grafana / SigNoz / Sentry / Langfuse", - "next_owner_action": "補 Wazuh / 主機入侵事故回讀包:manager / indexer / dashboard / API health ref、host-110 / host-188 agent status ref、event / alert refs、auth log、process tree、network connection、FIM、package inventory、persistence refs、actor attribution、incident time window、affected scope、containment decision、recovery proof、independent postcheck、recurrence guard、cross-project sync、rollback owner、followup owner 與 no-secret / no-raw-payload / no-false-green attestation。", + "next_owner_action": "補 Wazuh / 主機入侵防堵包:manager / indexer / dashboard / API health ref、host alias agent status ref、event / alert refs、auth log、process tree、network connection、FIM、package inventory、persistence refs、actor attribution、incident time window、affected scope、containment decision、active response dry-run blast radius、recovery proof、independent postcheck、recurrence guard、cross-project sync、rollback owner、followup owner 與 no-secret / no-raw-payload / no-false-green attestation。", "owner_response_accepted": false, "owner_response_received": false, "owner_response_required": true, @@ -384,9 +387,9 @@ "action_buttons_allowed": false, "category_id": "docker_compose_systemd_host_config", "control_tier": "C1", - "coverage_percent": 64, - "coverage_status": "post_incident_readback_plan_ready_needs_host_service_owner_evidence", - "current_gap": "已固定 9 份 Docker / systemd / host service owner response acceptance candidate、change evidence acceptance 與 post-incident readback plan;重啟 actor、boot / recovery window、before / after state、Docker daemon、compose / systemd state、failed unit、port binding、dependency、public/admin route recovery、AI provider health、monitoring alert、operator notice、cross-project sync、restoration、recurrence guard 與 no-false-green 皆已納入只讀帳本;仍缺 owner response、live hash、事故回讀包、maintenance / restart window、rollback owner、post-check plan、disable switch 與 no-secret-value evidence。", + "coverage_percent": 68, + "coverage_status": "external_host_intrusion_prevention_control_ready_needs_host_service_owner_evidence", + "current_gap": "已固定 9 份 Docker / systemd / host service owner response acceptance candidate、change evidence acceptance、post-incident readback plan 與外部入侵防堵控制矩陣;重啟 actor、boot / recovery window、before / after state、Docker daemon、compose / systemd state、failed unit、port binding、dependency、process / persistence baseline、public/admin route recovery、AI provider health、monitoring alert、operator notice、cross-project sync、restoration、recurrence guard 與 no-false-green 皆已納入;仍缺 owner response、live hash、Wazuh / host forensic refs、maintenance / restart window、rollback owner、post-check plan、disable switch 與 no-secret-value evidence。", "evidence_refs": [ "docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md", "docs/security/HOST-SERVICE-CONFIG-INVENTORY.md", @@ -399,10 +402,13 @@ "docs/security/host-service-change-evidence-acceptance.snapshot.json", "docs/security/HOST-SERVICE-POST-INCIDENT-READBACK-PLAN.md", "docs/security/host-service-post-incident-readback-plan.snapshot.json", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", "docs/security/DEV-HOSTS-112-111-168-OBSERVE-ONLY-MAPPING.md" ], "label": "Docker Compose / systemd / host service config", - "next_owner_action": "補 host service 事故回讀包:owner-provided live hash / disposition、change / incident ref、actor role / team、boot time、restart / recovery window、before / after state、Docker daemon state、compose / systemd state、failed unit review、port binding、服務依賴圖、public/admin route recovery、AI provider health、monitoring alert、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner、post-check plan 與 no-secret-value evidence。", + "next_owner_action": "補 host service 防堵包:owner-provided live hash / disposition、change / incident ref、actor role / team、boot time、restart / recovery window、before / after state、Docker daemon state、compose / systemd state、failed unit review、port binding、process / persistence refs、服務依賴圖、public/admin route recovery、AI provider health、monitoring alert、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner、post-check plan 與 no-secret-value evidence。", "owner_response_accepted": false, "owner_response_received": false, "owner_response_required": true, @@ -430,9 +436,9 @@ "action_buttons_allowed": false, "category_id": "ssh_firewall_network_access", "control_tier": "C1", - "coverage_percent": 64, - "coverage_status": "post_incident_readback_plan_ready_needs_network_owner_evidence", - "current_gap": "owner response acceptance、端口 / 防火牆事故型變更證據驗收與 post-incident readback plan 都已固定;仍缺 owner-provided change / incident evidence、actor、before / after state、service / AI provider / monitoring impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check evidence。", + "coverage_percent": 70, + "coverage_status": "external_host_intrusion_prevention_control_ready_needs_network_owner_evidence", + "current_gap": "owner response acceptance、端口 / 防火牆事故型變更證據驗收、post-incident readback plan 與外部入侵防堵控制矩陣都已固定;SSH / sudo、authorized_keys、known_hosts、firewall、WireGuard、NodePort、NetworkPolicy、port close / open 與 break-glass 邊界已納入;仍缺 owner-provided change / incident evidence、actor、before / after state、Wazuh / host forensic refs、service / AI provider / monitoring impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check evidence。", "evidence_refs": [ "docs/HARD_RULES.md", "docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md", @@ -445,10 +451,13 @@ "docs/security/PORT-FIREWALL-CHANGE-EVIDENCE-ACCEPTANCE.md", "docs/security/port-firewall-change-evidence-acceptance.snapshot.json", "docs/security/SSH-NETWORK-POST-INCIDENT-READBACK-PLAN.md", - "docs/security/ssh-network-post-incident-readback-plan.snapshot.json" + "docs/security/ssh-network-post-incident-readback-plan.snapshot.json", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py" ], "label": "SSH / sudoers / known_hosts / firewall / WireGuard / NodePort", - "next_owner_action": "補端口 / 防火牆事故回讀包:change / incident ref、actor role / team、affected scope、before / after state、service dependency、public route impact、AI provider impact、monitoring alert impact、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner 與 post-check 指標。", + "next_owner_action": "補 SSH / 端口 / 防火牆防堵包:change / incident ref、actor role / team、affected scope、before / after state、service dependency、public route impact、AI provider impact、monitoring alert impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check 指標。", "owner_response_accepted": false, "owner_response_received": false, "owner_response_required": true, @@ -659,23 +668,9 @@ "websocket_route_change_authorized": false, "workflow_modification_authorized": false }, - "generated_at": "2026-06-18T10:30:00+08:00", - "git_commit": "1b9d44cf", + "generated_at": "2026-06-18T15:30:00+08:00", + "git_commit": "efde1097", "lowest_coverage_categories": [ - { - "category_id": "docker_compose_systemd_host_config", - "coverage_percent": 64, - "current_gap": "已固定 9 份 Docker / systemd / host service owner response acceptance candidate、change evidence acceptance 與 post-incident readback plan;重啟 actor、boot / recovery window、before / after state、Docker daemon、compose / systemd state、failed unit、port binding、dependency、public/admin route recovery、AI provider health、monitoring alert、operator notice、cross-project sync、restoration、recurrence guard 與 no-false-green 皆已納入只讀帳本;仍缺 owner response、live hash、事故回讀包、maintenance / restart window、rollback owner、post-check plan、disable switch 與 no-secret-value evidence。", - "label": "Docker Compose / systemd / host service config", - "next_owner_action": "補 host service 事故回讀包:owner-provided live hash / disposition、change / incident ref、actor role / team、boot time、restart / recovery window、before / after state、Docker daemon state、compose / systemd state、failed unit review、port binding、服務依賴圖、public/admin route recovery、AI provider health、monitoring alert、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner、post-check plan 與 no-secret-value evidence。" - }, - { - "category_id": "ssh_firewall_network_access", - "coverage_percent": 64, - "current_gap": "owner response acceptance、端口 / 防火牆事故型變更證據驗收與 post-incident readback plan 都已固定;仍缺 owner-provided change / incident evidence、actor、before / after state、service / AI provider / monitoring impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check evidence。", - "label": "SSH / sudoers / known_hosts / firewall / WireGuard / NodePort", - "next_owner_action": "補端口 / 防火牆事故回讀包:change / incident ref、actor role / team、affected scope、before / after state、service dependency、public route impact、AI provider impact、monitoring alert impact、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner 與 post-check 指標。" - }, { "category_id": "ai_provider_model_routing", "coverage_percent": 64, @@ -689,6 +684,20 @@ "current_gap": "已固定 owner response acceptance、GitOps 變更證據驗收與事故後回讀計畫只讀帳本;ArgoCD sync / health / degraded、Pending workload、image pull / scheduling、rollout before-after、event / metrics / alert、drift scanner、CronJob schedule、NetworkPolicy / RBAC、route / AI provider / monitoring 影響、防再發與 no-false-green 已納入;仍缺 owner response、事故回讀包、rendered manifest diff、ArgoCD revision、maintenance window、rollback revision、post-check owner 與 no-secret-value evidence。", "label": "K8s / ArgoCD / production manifests", "next_owner_action": "補 GitOps / K8s 事故回讀包:incident / change ref、actor role / team、ArgoCD sync / health / revision、degraded / Pending / image pull / scheduling 摘要、rollout before-after、event summary、metrics / alert、drift scanner、CronJob schedule、NetworkPolicy / Service / RBAC 影響、public/admin route、AI provider、monitoring、operator notification、cross-project sync、recovery 或 still-degraded ref、recurrence guard、maintenance window、rollback revision、rollback owner、post-check owner 與 no-secret-value evidence。" + }, + { + "category_id": "public_admin_api_runtime_config", + "coverage_percent": 66, + "current_gap": "已固定 Public / Admin / API runtime config 變更證據驗收只讀帳本,並新增前台 source / messages 敏感資訊防洩漏 guard;affected route、admin/auth boundary、API readback、CORS diff、frontend env diff、i18n redaction、webhook owner、desktop/mobile production smoke、bundle scan、rollback 與 post-check evidence 仍全部為 0。", + "label": "Public / admin / API / frontend runtime config", + "next_owner_action": "補 affected route refs、admin/auth boundary、API contract readback、CORS origin diff、frontend env diff、i18n redaction review、webhook/callback owner、desktop/mobile production smoke、bundle sensitive scan、rollback owner 與 post-check evidence。" + }, + { + "category_id": "backup_restore_credential", + "coverage_percent": 66, + "current_gap": "已固定 owner response acceptance、restore recovery backfill 與事故後回讀計畫;freshness before-after、backup status readback、restore drill、隔離 restore target、offsite sync、remote delete guard、credential escrow non-secret proof、retention runway、alert textfile、cold-start scorecard、rollback、post-change monitoring、防再發與 no-false-green 已納入只讀帳本;owner response、事故回讀包、live backup evidence、restore drill accepted、offsite / escrow / retention accepted 與 runtime gate 仍全部為 0。", + "label": "Backup / restore / escrow / retention", + "next_owner_action": "補 Backup / Restore / Escrow 事故回讀包:incident / change ref、actor role / team、時間窗、改前改後 freshness、backup status readback、restore drill、隔離 restore target、offsite sync、remote delete guard、credential escrow non-secret proof、credential recovery metadata、retention runway、retention / prune decision、依賴圖、資料分級、restore observer / stop condition、alert textfile、cold-start / DR scorecard、rollback validation、post-change monitoring、recurrence guard 與 no-secret-value evidence。" } ], "next_collection_order": [ @@ -698,11 +707,11 @@ "secret_metadata", "gitea_workflow_runner_source_control", "public_admin_api_runtime_config", - "agent_bounty_protocol_runtime", - "docker_compose_systemd_host_config", "ssh_firewall_network_access", - "ai_provider_model_routing", + "docker_compose_systemd_host_config", "monitoring_alerting_observability", + "agent_bounty_protocol_runtime", + "ai_provider_model_routing", "backup_restore_credential" ], "operator_interpretation": [ @@ -723,7 +732,7 @@ "c3_category_count": 1, "category_count": 14, "lowest_coverage_category_count": 4, - "needs_live_evidence_count": 9, + "needs_live_evidence_count": 10, "owner_response_accepted_count": 0, "owner_response_received_count": 0, "owner_response_required_count": 14, diff --git a/docs/security/iwooos-posture-projection.snapshot.json b/docs/security/iwooos-posture-projection.snapshot.json index 922695040..7c711fc2d 100644 --- a/docs/security/iwooos-posture-projection.snapshot.json +++ b/docs/security/iwooos-posture-projection.snapshot.json @@ -64,7 +64,8 @@ "display_owner_response_next_action_focus", "display_source_control_primary_readiness_board", "display_s4_9_owner_response_preflight_checks", - "display_s4_9_owner_response_request_templates" + "display_s4_9_owner_response_request_templates", + "display_external_host_intrusion_prevention_control" ], "awooop_cross_session_handoff_packets": [ { @@ -538,7 +539,10 @@ "docs/security/kali-integration-status.snapshot.json", "docs/security/agent-bounty-iwooos-onboarding-handoff.snapshot.json", "docs/security/high-value-config-owner-packet.snapshot.json", - "docs/LOGBOOK.md" + "docs/LOGBOOK.md", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py" ], "evidence_unlock_queue_items": [ { @@ -8443,7 +8447,10 @@ "docs/security/WAZUH-IWOOOS-INTRUSION-READBACK-PLAN.md", "docs/security/wazuh-iwooos-intrusion-readback-plan.snapshot.json", "scripts/security/wazuh-iwooos-intrusion-readback-plan.py", - "apps/web/src/app/api/iwooos/wazuh/route.ts" + "apps/web/src/app/api/iwooos/wazuh/route.ts", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py" ], "status": "draft", "summary": { @@ -8673,7 +8680,7 @@ "decision_runway_owner_response_received_count": 0, "decision_runway_runtime_gate_count": 0, "decision_runway_step_count": 5, - "docker_compose_systemd_host_config_coverage_percent": 64, + "docker_compose_systemd_host_config_coverage_percent": 68, "domain_tls_certbot_inventory_accepted_response_count": 0, "domain_tls_certbot_inventory_acme_challenge_domain_count": 7, "domain_tls_certbot_inventory_action_buttons_allowed": false, @@ -8711,6 +8718,57 @@ "executive_snapshot_owner_response_received_count": 0, "executive_snapshot_runtime_gate_count": 0, "existing_frontend_surface_count": 10, + "external_host_intrusion_prevention_control_action_button_count": 0, + "external_host_intrusion_prevention_control_active_scan_authorized_count": 0, + "external_host_intrusion_prevention_control_argocd_sync_authorized_count": 0, + "external_host_intrusion_prevention_control_backup_restore_required_candidate_count": 1, + "external_host_intrusion_prevention_control_blocked_action_count": 82, + "external_host_intrusion_prevention_control_break_glass_required_candidate_count": 10, + "external_host_intrusion_prevention_control_c0_candidate_count": 10, + "external_host_intrusion_prevention_control_c1_candidate_count": 4, + "external_host_intrusion_prevention_control_candidate_count": 14, + "external_host_intrusion_prevention_control_config_diff_required_candidate_count": 8, + "external_host_intrusion_prevention_control_containment_decision_accepted_count": 0, + "external_host_intrusion_prevention_control_coverage_percent_after_prevention_control": 74, + "external_host_intrusion_prevention_control_cross_project_sync_required_candidate_count": 14, + "external_host_intrusion_prevention_control_docker_restart_authorized_count": 0, + "external_host_intrusion_prevention_control_domain_count": 12, + "external_host_intrusion_prevention_control_evidence_ref_accepted_count": 0, + "external_host_intrusion_prevention_control_evidence_ref_received_count": 0, + "external_host_intrusion_prevention_control_firewall_change_authorized_count": 0, + "external_host_intrusion_prevention_control_first_layer": true, + "external_host_intrusion_prevention_control_host_alias_count": 4, + "external_host_intrusion_prevention_control_host_forensics_required_candidate_count": 6, + "external_host_intrusion_prevention_control_host_write_authorized_count": 0, + "external_host_intrusion_prevention_control_maintenance_window_accepted_count": 0, + "external_host_intrusion_prevention_control_maintenance_window_required_candidate_count": 14, + "external_host_intrusion_prevention_control_nginx_reload_authorized_count": 0, + "external_host_intrusion_prevention_control_no_false_green_required_candidate_count": 14, + "external_host_intrusion_prevention_control_outcome_lane_count": 12, + "external_host_intrusion_prevention_control_owner_approval_required_candidate_count": 14, + "external_host_intrusion_prevention_control_owner_response_accepted_count": 0, + "external_host_intrusion_prevention_control_owner_response_received_count": 0, + "external_host_intrusion_prevention_control_p0_candidate_count": 14, + "external_host_intrusion_prevention_control_package_upgrade_authorized_count": 0, + "external_host_intrusion_prevention_control_postcheck_accepted_count": 0, + "external_host_intrusion_prevention_control_prevention_control_accepted_count": 0, + "external_host_intrusion_prevention_control_production_write_authorized_count": 0, + "external_host_intrusion_prevention_control_repo_secret_change_authorized_count": 0, + "external_host_intrusion_prevention_control_required_owner_field_count": 36, + "external_host_intrusion_prevention_control_reviewer_check_count": 34, + "external_host_intrusion_prevention_control_rollback_plan_accepted_count": 0, + "external_host_intrusion_prevention_control_rollback_required_candidate_count": 14, + "external_host_intrusion_prevention_control_runner_change_authorized_count": 0, + "external_host_intrusion_prevention_control_runtime_gate_count": 0, + "external_host_intrusion_prevention_control_secret_value_collection_allowed_count": 0, + "external_host_intrusion_prevention_control_sensor_alias_count": 1, + "external_host_intrusion_prevention_control_ssh_write_authorized_count": 0, + "external_host_intrusion_prevention_control_systemctl_restart_authorized_count": 0, + "external_host_intrusion_prevention_control_urgent_prevention_candidate_count": 14, + "external_host_intrusion_prevention_control_validation_required_candidate_count": 14, + "external_host_intrusion_prevention_control_wazuh_active_response_enabled_count": 0, + "external_host_intrusion_prevention_control_wazuh_event_required_candidate_count": 7, + "external_host_intrusion_prevention_control_workflow_modification_authorized_count": 0, "first_progress_unlock_path_above_visual_dashboard": true, "first_progress_unlock_path_boundary_details_collapsed": true, "first_progress_unlock_path_default_visible": false, @@ -8758,7 +8816,7 @@ "high_value_config_control_coverage_first_layer": true, "high_value_config_control_coverage_item_count": 5, "high_value_config_control_coverage_lowest_category_count": 4, - "high_value_config_control_coverage_needs_live_evidence_count": 9, + "high_value_config_control_coverage_needs_live_evidence_count": 10, "high_value_config_control_coverage_owner_response_accepted_count": 0, "high_value_config_control_coverage_owner_response_received_count": 0, "high_value_config_control_coverage_owner_response_required_count": 14, @@ -8969,6 +9027,7 @@ "k8s_production_gitops_coverage_percent": 66, "kali_maintenance_readiness_item_count": 6, "long_form_sections_default_collapsed": true, + "monitoring_alerting_observability_coverage_percent": 74, "monitoring_alerting_observability_inventory_action_button_count": 0, "monitoring_alerting_observability_inventory_alert_rule_surface_count": 13, "monitoring_alerting_observability_inventory_alertmanager_receiver_surface_count": 1, @@ -9032,38 +9091,6 @@ "monitoring_post_incident_readback_plan_silence_mute_dedup_inhibit_review_accepted_count": 0, "monitoring_post_incident_readback_plan_stale_pending_resolved_review_accepted_count": 0, "monitoring_post_incident_readback_plan_write_capable_candidate_count": 11, - "wazuh_intrusion_readback_plan_action_button_count": 0, - "wazuh_intrusion_readback_plan_active_response_authorized_count": 0, - "wazuh_intrusion_readback_plan_affected_host_alias_count": 2, - "wazuh_intrusion_readback_plan_blocked_action_count": 49, - "wazuh_intrusion_readback_plan_c0_candidate_count": 6, - "wazuh_intrusion_readback_plan_candidate_count": 6, - "wazuh_intrusion_readback_plan_containment_decision_accepted_count": 0, - "wazuh_intrusion_readback_plan_containment_decision_received_count": 0, - "wazuh_intrusion_readback_plan_coverage_percent_after_readback_plan": 72, - "wazuh_intrusion_readback_plan_cross_project_sync_required_candidate_count": 6, - "wazuh_intrusion_readback_plan_first_layer": true, - "wazuh_intrusion_readback_plan_host_forensics_accepted_count": 0, - "wazuh_intrusion_readback_plan_host_forensics_ref_received_count": 0, - "wazuh_intrusion_readback_plan_host_forensics_required_candidate_count": 5, - "wazuh_intrusion_readback_plan_host_write_authorized_count": 0, - "wazuh_intrusion_readback_plan_outcome_lane_count": 12, - "wazuh_intrusion_readback_plan_owner_response_accepted_count": 0, - "wazuh_intrusion_readback_plan_owner_response_received_count": 0, - "wazuh_intrusion_readback_plan_readonly_api_code_path_present_count": 1, - "wazuh_intrusion_readback_plan_readonly_api_enabled_count": 0, - "wazuh_intrusion_readback_plan_recovery_proof_accepted_count": 0, - "wazuh_intrusion_readback_plan_recovery_proof_received_count": 0, - "wazuh_intrusion_readback_plan_required_readback_field_count": 30, - "wazuh_intrusion_readback_plan_reviewer_check_count": 24, - "wazuh_intrusion_readback_plan_runtime_gate_count": 0, - "wazuh_intrusion_readback_plan_secret_value_collection_allowed_count": 0, - "wazuh_intrusion_readback_plan_wazuh_agent_status_ref_received_count": 0, - "wazuh_intrusion_readback_plan_wazuh_event_accepted_count": 0, - "wazuh_intrusion_readback_plan_wazuh_event_ref_received_count": 0, - "wazuh_intrusion_readback_plan_wazuh_event_required_candidate_count": 5, - "wazuh_intrusion_readback_plan_wazuh_manager_health_ref_received_count": 0, - "wazuh_intrusion_readback_plan_wazuh_platform_reported_count": 1, "nav_entry_added": true, "nginx_public_gateway_coverage_percent": 92, "operator_journey_step_count": 6, @@ -9278,7 +9305,7 @@ "s4_9_request_draft_package_template_ready_count": 5, "secret_metadata_coverage_percent": 70, "source_control_primary_readiness_item_count": 6, - "ssh_firewall_network_access_coverage_percent": 64, + "ssh_firewall_network_access_coverage_percent": 70, "ssh_network_access_inventory_action_button_count": 0, "ssh_network_access_inventory_coverage_percent_after_inventory": 54, "ssh_network_access_inventory_coverage_percent_before_inventory": 48, @@ -9370,7 +9397,39 @@ "vibework_security_onboarding_runtime_gate_count": 0, "visual_command_dashboard_default_visible": false, "visual_command_dashboard_first_layer": true, - "visual_command_dashboard_widget_count": 14 + "visual_command_dashboard_widget_count": 14, + "wazuh_intrusion_readback_plan_action_button_count": 0, + "wazuh_intrusion_readback_plan_active_response_authorized_count": 0, + "wazuh_intrusion_readback_plan_affected_host_alias_count": 2, + "wazuh_intrusion_readback_plan_blocked_action_count": 49, + "wazuh_intrusion_readback_plan_c0_candidate_count": 6, + "wazuh_intrusion_readback_plan_candidate_count": 6, + "wazuh_intrusion_readback_plan_containment_decision_accepted_count": 0, + "wazuh_intrusion_readback_plan_containment_decision_received_count": 0, + "wazuh_intrusion_readback_plan_coverage_percent_after_readback_plan": 72, + "wazuh_intrusion_readback_plan_cross_project_sync_required_candidate_count": 6, + "wazuh_intrusion_readback_plan_first_layer": true, + "wazuh_intrusion_readback_plan_host_forensics_accepted_count": 0, + "wazuh_intrusion_readback_plan_host_forensics_ref_received_count": 0, + "wazuh_intrusion_readback_plan_host_forensics_required_candidate_count": 5, + "wazuh_intrusion_readback_plan_host_write_authorized_count": 0, + "wazuh_intrusion_readback_plan_outcome_lane_count": 12, + "wazuh_intrusion_readback_plan_owner_response_accepted_count": 0, + "wazuh_intrusion_readback_plan_owner_response_received_count": 0, + "wazuh_intrusion_readback_plan_readonly_api_code_path_present_count": 1, + "wazuh_intrusion_readback_plan_readonly_api_enabled_count": 0, + "wazuh_intrusion_readback_plan_recovery_proof_accepted_count": 0, + "wazuh_intrusion_readback_plan_recovery_proof_received_count": 0, + "wazuh_intrusion_readback_plan_required_readback_field_count": 30, + "wazuh_intrusion_readback_plan_reviewer_check_count": 24, + "wazuh_intrusion_readback_plan_runtime_gate_count": 0, + "wazuh_intrusion_readback_plan_secret_value_collection_allowed_count": 0, + "wazuh_intrusion_readback_plan_wazuh_agent_status_ref_received_count": 0, + "wazuh_intrusion_readback_plan_wazuh_event_accepted_count": 0, + "wazuh_intrusion_readback_plan_wazuh_event_ref_received_count": 0, + "wazuh_intrusion_readback_plan_wazuh_event_required_candidate_count": 5, + "wazuh_intrusion_readback_plan_wazuh_manager_health_ref_received_count": 0, + "wazuh_intrusion_readback_plan_wazuh_platform_reported_count": 1 }, "topology_atlas_lenses": [ { diff --git a/scripts/security/external-host-intrusion-prevention-control.py b/scripts/security/external-host-intrusion-prevention-control.py new file mode 100644 index 000000000..8473b084c --- /dev/null +++ b/scripts/security/external-host-intrusion-prevention-control.py @@ -0,0 +1,657 @@ +#!/usr/bin/env python3 +""" +IwoooS 外部入侵主機防堵控制矩陣產生器。 + +本工具只產生 repo 內 snapshot,將外部入口、SSH / sudo、端口 / +防火牆、Nginx、runner、secret、Docker / systemd、K8s / ArgoCD、 +Wazuh、套件更新、backup / restore 與跨專案同步收斂成同一份可審核 +控制矩陣。 + +它不連線主機、不 SSH、不讀 live config、不改 Nginx / firewall / K8s、 +不啟用 Wazuh active response、不重啟服務、不更新套件、不輪替 secret、 +不做 active scan,也不把 UI 可見、服務 200 或外部 Agent 宣稱當成已防堵。 +""" + +from __future__ import annotations + +import argparse +import json +import subprocess +import sys +from datetime import datetime, timedelta, timezone +from pathlib import Path +from typing import Any + + +TAIPEI = timezone(timedelta(hours=8)) + +HOST_ALIASES = ["host-110", "host-188", "dev-host-111", "dev-host-168"] +SENSOR_ALIASES = ["sensor-kali-112"] + +PREVENTION_DOMAINS = [ + { + "domain_id": "public_ingress_gateway", + "label": "公開入口 / DNS / TLS / Nginx / public gateway", + "control_tier": "C0", + "immediate_risk": "未受控 reload、route drift、上游錯配或 TLS / ACME 變更會造成外部暴露或服務中斷。", + }, + { + "domain_id": "ssh_sudo_access", + "label": "SSH / sudo / authorized_keys / known_hosts", + "control_tier": "C0", + "immediate_risk": "未受控登入、sudo 權限、host key 漂移或跳板憑證會擴大入侵面。", + }, + { + "domain_id": "firewall_network_policy", + "label": "Firewall / WireGuard / NodePort / NetworkPolicy", + "control_tier": "C0", + "immediate_risk": "端口開關、內網路由、NodePort 或 NetworkPolicy 漂移會直接改變可攻擊面。", + }, + { + "domain_id": "host_runtime_services", + "label": "Docker / systemd / process / port binding", + "control_tier": "C0", + "immediate_risk": "容器重啟、failed unit、未知 process、port binding 或 persistence 會影響服務與入侵駐留判讀。", + }, + { + "domain_id": "k8s_gitops_runtime", + "label": "K8s / ArgoCD / RBAC / Secret metadata", + "control_tier": "C0", + "immediate_risk": "GitOps drift、RBAC / Secret metadata、image pull 或 pending workload 可能隱藏惡意部署與供應鏈變更。", + }, + { + "domain_id": "runner_workflow_supply_chain", + "label": "Gitea runner / workflow / deploy key / webhook", + "control_tier": "C0", + "immediate_risk": "runner、workflow、deploy key 或 webhook 被改動會直接打開 production 寫入路徑。", + }, + { + "domain_id": "secret_credential_exposure", + "label": "Secret / session / API token / credential hygiene", + "control_tier": "C0", + "immediate_risk": "secret、session、API token 或 env dump 外洩會讓修復失效並擴散到其他產品。", + }, + { + "domain_id": "wazuh_detection_response", + "label": "Wazuh manager / agent / rule / active response", + "control_tier": "C0", + "immediate_risk": "偵測與 response 邊界不清會造成假綠燈、誤隔離、漏封鎖或錯信外部宣稱。", + }, + { + "domain_id": "package_patch_vulnerability", + "label": "套件更新 / CVE / maintenance window", + "control_tier": "C1", + "immediate_risk": "未修補套件與服務版本過舊會保留可利用入口,但無維護窗口直接升級也會造成中斷。", + }, + { + "domain_id": "backup_restore_resilience", + "label": "Backup / restore / offsite / escrow / rollback", + "control_tier": "C1", + "immediate_risk": "沒有可驗證 restore 與 rollback,入侵後清除、重建與服務恢復都沒有可信退路。", + }, + { + "domain_id": "monitoring_alerting_false_green", + "label": "Monitoring / alerting / no-false-green", + "control_tier": "C1", + "immediate_risk": "route 200、dashboard up 或 alert quiet 若被當成資安通過,會掩蓋持久化與告警失效。", + }, + { + "domain_id": "cross_project_freeze_sync", + "label": "跨專案 freeze / operator sync / break-glass", + "control_tier": "C1", + "immediate_risk": "多 session 或多專案並行修改會造成重複修復、rebase 衝突、錯誤 reload 或未同步封鎖。", + }, +] + +REQUIRED_OWNER_FIELDS = [ + "control_id", + "owner_role", + "owner_team", + "decision", + "decision_reason", + "affected_scope_aliases", + "exposed_surface_aliases", + "current_risk", + "immediate_harm_if_delayed", + "redacted_evidence_refs", + "wazuh_event_refs", + "host_forensic_refs", + "config_diff_refs", + "before_state_ref", + "after_state_ref", + "maintenance_window", + "break_glass_reason", + "rollback_owner", + "rollback_plan_ref", + "validation_metrics", + "postcheck_owner", + "postcheck_ref", + "cross_project_sync_ref", + "communication_channel", + "secret_value_absence_attestation", + "raw_payload_absence_attestation", + "no_internal_name_publication_attestation", + "no_false_green_attestation", + "service_impact_assessment", + "ai_provider_impact_assessment", + "monitoring_alert_impact_assessment", + "backup_restore_impact_assessment", + "recurrence_guard_ref", + "followup_owner", + "expiry_or_review_date", + "reviewer_attestation", +] + +REVIEWER_CHECKS = [ + {"check_id": "scope_alias_only", "instruction": "只接受 host alias、service alias、product alias;不得公開內網 IP、帳號 namespace 或 repo owner 原名。"}, + {"check_id": "owner_role_and_team_present", "instruction": "每個防堵候選都需要 owner role / team,不能匿名批准。"}, + {"check_id": "decision_and_reason_present", "instruction": "需要明確 decision 與 decision reason;不得只寫批准或已處理。"}, + {"check_id": "wazuh_event_refs_required_for_intrusion", "instruction": "主機入侵、惡意程式或 RCE 類候選必須有 Wazuh event refs。"}, + {"check_id": "host_forensic_refs_required", "instruction": "需要 auth、process、network、FIM、package 或 persistence refs;服務恢復不能取代鑑識。"}, + {"check_id": "gateway_diff_required", "instruction": "公開入口、Nginx、TLS、route 或 upstream 變更需有 source-to-live diff refs。"}, + {"check_id": "firewall_before_after_required", "instruction": "端口、防火牆、WireGuard、NodePort 或 NetworkPolicy 需有 before / after state。"}, + {"check_id": "ssh_sudo_scope_required", "instruction": "SSH、sudo、deploy key 或 known_hosts 需標示範圍與回滾 owner。"}, + {"check_id": "runner_workflow_diff_required", "instruction": "runner、workflow、webhook 或 deploy key 需有 diff、run ref、permission scope 與 workspace cleanup。"}, + {"check_id": "secret_values_absent", "instruction": "不得收 secret value、hash、partial token、cookie、env dump、private key 或 runner token。"}, + {"check_id": "raw_payload_absent", "instruction": "不得保存 raw Wazuh payload、raw log、raw journal、完整命令輸出或未脫敏截圖。"}, + {"check_id": "maintenance_window_required", "instruction": "任何可能中斷服務的防堵都需要 maintenance window。"}, + {"check_id": "rollback_owner_required", "instruction": "任何 host、gateway、firewall、runner、K8s 或 secret 相關候選都需要 rollback owner。"}, + {"check_id": "validation_metrics_required", "instruction": "防堵後驗證需列 route、API、agent、alert、backup 或 service health 指標。"}, + {"check_id": "cross_project_sync_required", "instruction": "影響 AWOOOI、AwoooP、IwoooS、VibeWork、agent-bounty-protocol、stock 或監控需有同步 ref。"}, + {"check_id": "no_false_green", "instruction": "route 200、dashboard up、agent active、CD success、UI 可見都不能單獨當資安驗收。"}, + {"check_id": "external_agent_claim_not_trusted", "instruction": "外部 Agent 宣稱已封鎖、清除或 Zero-Trust 不能直接 accepted。"}, + {"check_id": "active_response_dry_run_first", "instruction": "Wazuh active response 必須先 dry-run、驗證 blast radius 與 rollback,不得直接 production enable。"}, + {"check_id": "firewall_change_break_glass_only", "instruction": "firewall drop、port close/open 需 break-glass 或 maintenance window,不得由候選自動執行。"}, + {"check_id": "host_service_write_blocked", "instruction": "不得由本 artifact 觸發 Docker、systemd、kill process、package upgrade 或 reboot。"}, + {"check_id": "k8s_argocd_write_blocked", "instruction": "不得由本 artifact 觸發 ArgoCD sync、kubectl、Helm、NetworkPolicy 或 RBAC apply。"}, + {"check_id": "backup_restore_not_assumed", "instruction": "備份存在、冷啟動分數或 UI 可見不能代表 restore / rollback 可用。"}, + {"check_id": "credential_rotation_requires_decision", "instruction": "credential rotation 需 owner decision、blast radius、dependent services 與 rollback plan。"}, + {"check_id": "package_upgrade_requires_window", "instruction": "套件更新、kernel、Docker、Nginx、Wazuh agent 或 Kali 更新需維護窗口與 postcheck。"}, + {"check_id": "public_frontend_no_internal_transcript", "instruction": "前台不得顯示工作視窗、內部對話、抱怨、raw namespace 或截圖原文。"}, + {"check_id": "production_write_stays_zero", "instruction": "防堵矩陣不是 production write 授權;runtime gate 與 action button 必須維持 0。"}, + {"check_id": "evidence_refs_redacted", "instruction": "只收脫敏 ref、ticket、artifact pointer;不得貼 raw secret 或 raw payload。"}, + {"check_id": "parallel_session_conflict_checked", "instruction": "需確認其他 session 是否正在操作同一主機、Nginx、runner、workflow 或 secret。"}, + {"check_id": "service_dependency_map_present", "instruction": "端口、gateway、host service 或 AI provider 變更需列服務依賴與受影響產品 alias。"}, + {"check_id": "operator_notification_present", "instruction": "即時危害或可能中斷的防堵需有 operator notification / receipt plan。"}, + {"check_id": "postcheck_independent", "instruction": "postcheck 必須由獨立於操作人的 reviewer 或 automation readback 驗證。"}, + {"check_id": "recurrence_guard_present", "instruction": "需補防再發 guard,例如 config drift、runner freeze、secret hygiene、Wazuh rule coverage 或 firewall diff guard。"}, + {"check_id": "expiry_or_review_date_present", "instruction": "臨時 freeze、break-glass 或例外需有到期或複審日期。"}, + {"check_id": "counts_transition_safe", "instruction": "received / accepted / authorized / executed / allowed 類計數只能由正式驗收推進。"}, +] + +OUTCOME_LANES = [ + {"lane_id": "waiting_owner_prevention_packet", "meaning": "防堵候選已建立,等待 owner 補齊欄位與脫敏證據。"}, + {"lane_id": "request_wazuh_event_supplement", "meaning": "缺 Wazuh event / alert refs 時要求補件。"}, + {"lane_id": "request_host_forensics_supplement", "meaning": "缺主機鑑識 refs 時要求補件。"}, + {"lane_id": "request_config_diff_supplement", "meaning": "缺 Nginx、firewall、runner、workflow、K8s 或 secret metadata diff 時要求補件。"}, + {"lane_id": "request_maintenance_window", "meaning": "涉及服務中斷、重啟、封鎖、更新或 active response 時要求維護窗口。"}, + {"lane_id": "request_break_glass_record", "meaning": "即時封鎖或緊急變更需補 break-glass reason 與通知紀錄。"}, + {"lane_id": "quarantine_secret_or_raw_payload", "meaning": "收到 secret、raw log、raw payload、env dump 或未脫敏截圖時隔離。"}, + {"lane_id": "reject_claim_without_evidence", "meaning": "只有外部宣稱、route 200、dashboard up 或 agent active 時拒收。"}, + {"lane_id": "route_to_high_value_config_gate", "meaning": "涉及高價值配置時串到既有配置控管 gate。"}, + {"lane_id": "ready_for_prevention_reviewer_review", "meaning": "metadata 合格後進 reviewer review,不自動執行。"}, + {"lane_id": "waiting_runtime_authorization", "meaning": "即使 accepted,也需獨立批准才可進 runtime 防堵。"}, + {"lane_id": "blocked_no_rollback_or_postcheck", "meaning": "缺 rollback owner、validation 或 postcheck 時不得進下一關。"}, +] + +BLOCKED_ACTIONS = [ + "ssh_read", + "ssh_write", + "sudo_action", + "host_file_read", + "host_file_write", + "host_live_config_read", + "iptables_change", + "ufw_change", + "firewall_drop", + "firewall_allow", + "port_close", + "port_open", + "wireguard_change", + "nodeport_change", + "network_policy_apply", + "nginx_test", + "nginx_reload", + "nginx_conf_write", + "certbot_renew", + "dns_record_change", + "route_change", + "upstream_change", + "websocket_route_change", + "docker_restart", + "docker_kill", + "docker_compose_up", + "docker_compose_down", + "systemctl_restart", + "systemctl_stop", + "systemctl_start", + "kill_process", + "quarantine_host", + "reboot_host", + "apt_update", + "apt_upgrade", + "package_install", + "kernel_upgrade", + "wazuh_active_response_enable", + "wazuh_agent_install", + "wazuh_agent_restart", + "wazuh_rule_change", + "wazuh_decoder_change", + "wazuh_api_live_query_without_owner_gate", + "argocd_sync", + "kubectl_apply", + "kubectl_delete", + "helm_upgrade", + "rbac_change", + "k8s_secret_change", + "workflow_modification", + "gitea_action_dispatch", + "runner_label_change", + "runner_config_change", + "deploy_key_change", + "webhook_change", + "repo_secret_change", + "secret_rotation", + "secret_store_read", + "collect_password", + "collect_private_key", + "collect_runner_token", + "collect_webhook_secret", + "collect_cookie_or_session", + "collect_env_dump", + "store_raw_wazuh_payload", + "store_raw_syslog", + "store_raw_journal", + "store_raw_command_output", + "store_unredacted_screenshot", + "active_scan", + "credentialed_scan", + "exploit_validation", + "backup_run", + "restore_run", + "offsite_sync", + "remote_delete", + "retention_change", + "database_migration", + "production_write", + "add_action_button", + "open_runtime_gate", + "force_push", +] + + +CONTROL_CANDIDATES = [ + { + "control_id": "external_host_prevention:public_gateway_freeze_diff", + "scope_alias": "public-gateway", + "label": "公開入口 / Nginx 變更 freeze 與 source-to-live diff", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "public_ingress_gateway", + "requires_wazuh_event_refs": False, + "requires_host_forensics_refs": False, + "requires_config_diff_refs": True, + }, + { + "control_id": "external_host_prevention:ssh_sudo_access_lockdown", + "scope_alias": "ssh-sudo-access", + "label": "SSH / sudo / authorized_keys / known_hosts 存取收斂", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "ssh_sudo_access", + "requires_wazuh_event_refs": True, + "requires_host_forensics_refs": True, + "requires_config_diff_refs": True, + }, + { + "control_id": "external_host_prevention:firewall_port_baseline_guard", + "scope_alias": "firewall-port-baseline", + "label": "端口 / 防火牆 / WireGuard / NodePort baseline", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "firewall_network_policy", + "requires_wazuh_event_refs": True, + "requires_host_forensics_refs": True, + "requires_config_diff_refs": True, + }, + { + "control_id": "external_host_prevention:host_service_persistence_baseline", + "scope_alias": "host-service-persistence", + "label": "Docker / systemd / process / persistence baseline", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "host_runtime_services", + "requires_wazuh_event_refs": True, + "requires_host_forensics_refs": True, + "requires_config_diff_refs": True, + }, + { + "control_id": "external_host_prevention:k8s_argocd_drift_containment", + "scope_alias": "k8s-argocd-drift", + "label": "K8s / ArgoCD drift、RBAC 與 Secret metadata containment", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "k8s_gitops_runtime", + "requires_wazuh_event_refs": False, + "requires_host_forensics_refs": False, + "requires_config_diff_refs": True, + }, + { + "control_id": "external_host_prevention:runner_workflow_secret_freeze", + "scope_alias": "runner-workflow-secret-freeze", + "label": "Runner / workflow / deploy key / secret freeze", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "runner_workflow_supply_chain", + "requires_wazuh_event_refs": True, + "requires_host_forensics_refs": True, + "requires_config_diff_refs": True, + }, + { + "control_id": "external_host_prevention:credential_exposure_rotation_gate", + "scope_alias": "credential-exposure", + "label": "疑似 credential exposure 的輪替決策 gate", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "secret_credential_exposure", + "requires_wazuh_event_refs": True, + "requires_host_forensics_refs": True, + "requires_config_diff_refs": True, + }, + { + "control_id": "external_host_prevention:wazuh_event_triage_gate", + "scope_alias": "wazuh-event-triage", + "label": "Wazuh event triage 與事件分流 gate", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "wazuh_detection_response", + "requires_wazuh_event_refs": True, + "requires_host_forensics_refs": False, + "requires_config_diff_refs": False, + }, + { + "control_id": "external_host_prevention:wazuh_active_response_dry_run", + "scope_alias": "wazuh-active-response-dry-run", + "label": "Wazuh active response dry-run / blast radius / rollback", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "wazuh_detection_response", + "requires_wazuh_event_refs": True, + "requires_host_forensics_refs": True, + "requires_config_diff_refs": False, + }, + { + "control_id": "external_host_prevention:backup_restore_recovery_gate", + "scope_alias": "backup-restore-recovery", + "label": "Backup / restore / rollback 可用性防堵 gate", + "control_tier": "C0", + "priority": "P0", + "prevention_domain": "backup_restore_resilience", + "requires_wazuh_event_refs": False, + "requires_host_forensics_refs": False, + "requires_config_diff_refs": False, + }, + { + "control_id": "external_host_prevention:package_patch_window", + "scope_alias": "package-patch-window", + "label": "套件更新 / CVE 修補維護窗口候選", + "control_tier": "C1", + "priority": "P0", + "prevention_domain": "package_patch_vulnerability", + "requires_wazuh_event_refs": False, + "requires_host_forensics_refs": False, + "requires_config_diff_refs": False, + }, + { + "control_id": "external_host_prevention:public_runtime_auth_route_guard", + "scope_alias": "public-runtime-auth-route", + "label": "公開 / 後台 / API runtime auth 與 route guard", + "control_tier": "C1", + "priority": "P0", + "prevention_domain": "public_ingress_gateway", + "requires_wazuh_event_refs": False, + "requires_host_forensics_refs": False, + "requires_config_diff_refs": True, + }, + { + "control_id": "external_host_prevention:monitoring_no_false_green_gate", + "scope_alias": "monitoring-no-false-green", + "label": "監控 / 告警 / route 200 no-false-green gate", + "control_tier": "C1", + "priority": "P0", + "prevention_domain": "monitoring_alerting_false_green", + "requires_wazuh_event_refs": False, + "requires_host_forensics_refs": False, + "requires_config_diff_refs": False, + }, + { + "control_id": "external_host_prevention:cross_project_break_glass_sync", + "scope_alias": "cross-project-break-glass-sync", + "label": "跨專案 freeze、break-glass 與 operator sync", + "control_tier": "C1", + "priority": "P0", + "prevention_domain": "cross_project_freeze_sync", + "requires_wazuh_event_refs": False, + "requires_host_forensics_refs": False, + "requires_config_diff_refs": False, + }, +] + + +EXECUTION_BOUNDARIES = { + "runtime_execution_authorized": False, + "host_read_authorized": False, + "host_write_authorized": False, + "ssh_read_authorized": False, + "ssh_write_authorized": False, + "sudo_action_authorized": False, + "host_live_config_read_authorized": False, + "firewall_change_authorized": False, + "port_close_authorized": False, + "port_open_authorized": False, + "nginx_test_authorized": False, + "nginx_reload_authorized": False, + "dns_tls_change_authorized": False, + "certbot_renew_authorized": False, + "docker_restart_authorized": False, + "systemctl_restart_authorized": False, + "process_kill_authorized": False, + "host_isolation_authorized": False, + "package_upgrade_authorized": False, + "reboot_authorized": False, + "wazuh_api_live_query_authorized": False, + "wazuh_active_response_authorized": False, + "wazuh_rule_change_authorized": False, + "argocd_sync_authorized": False, + "kubectl_action_authorized": False, + "workflow_modification_authorized": False, + "runner_change_authorized": False, + "repo_secret_change_authorized": False, + "secret_rotation_authorized": False, + "secret_value_collection_allowed": False, + "raw_payload_storage_allowed": False, + "active_scan_authorized": False, + "backup_run_authorized": False, + "restore_run_authorized": False, + "production_write_authorized": False, + "action_buttons_allowed": False, + "frontend_internal_transcript_display_allowed": False, + "not_authorization": True, +} + + +def git_short_sha(root: Path) -> str: + try: + result = subprocess.run( + ["git", "rev-parse", "--short", "HEAD"], + cwd=root, + check=True, + capture_output=True, + text=True, + ) + return result.stdout.strip() + except Exception: + return "unknown" + + +def build_candidate(source: dict[str, Any]) -> dict[str, Any]: + return { + **source, + "status": "waiting_owner_prevention_packet", + "host_aliases": HOST_ALIASES, + "sensor_aliases": SENSOR_ALIASES, + "requires_owner_approval": True, + "requires_maintenance_window": True, + "requires_break_glass_record": source["control_tier"] == "C0", + "requires_cross_project_sync": True, + "requires_rollback_plan": True, + "requires_validation_plan": True, + "owner_role": "pending_owner_response", + "owner_team": "pending_owner_response", + "maintenance_window": "pending_owner_response", + "rollback_owner": "pending_owner_response", + "followup_owner": "pending_owner_response", + "redacted_evidence_refs": [], + "wazuh_event_refs": [], + "host_forensic_refs": [], + "config_diff_refs": [], + "validation_metric_refs": [], + "postcheck_ref": None, + "cross_project_sync_ref": None, + "reviewer_outcome": "waiting_prevention_reviewer_review", + "runtime_gate": False, + "action_buttons_allowed": False, + "not_authorization": True, + "blocked_actions": BLOCKED_ACTIONS, + "required_owner_fields": REQUIRED_OWNER_FIELDS, + "reviewer_checks": [item["check_id"] for item in REVIEWER_CHECKS], + "outcome_lanes": [item["lane_id"] for item in OUTCOME_LANES], + } + + +def count_if(candidates: list[dict[str, Any]], key: str) -> int: + return sum(1 for item in candidates if item[key]) + + +def build_report(root: Path, generated_at: str | None) -> dict[str, Any]: + report_time = generated_at or datetime.now(TAIPEI).isoformat(timespec="seconds") + candidates = [build_candidate(item) for item in CONTROL_CANDIDATES] + return { + "schema_version": "external_host_intrusion_prevention_control_v1", + "generated_at": report_time, + "git_commit": git_short_sha(root), + "status": "external_host_intrusion_prevention_control_ready_no_runtime_action", + "mode": "control_matrix_only_no_host_write_no_firewall_change_no_active_response", + "source_context": { + "host_aliases": HOST_ALIASES, + "sensor_aliases": SENSOR_ALIASES, + "raw_ip_or_account_namespace_published_to_frontend": False, + "work_session_transcript_published_to_frontend": False, + "external_agent_claim_accepted_without_evidence": False, + "runtime_prevention_enabled": False, + }, + "summary": { + "prevention_domain_count": len(PREVENTION_DOMAINS), + "host_alias_count": len(HOST_ALIASES), + "sensor_alias_count": len(SENSOR_ALIASES), + "control_candidate_count": len(candidates), + "c0_control_candidate_count": sum(1 for item in candidates if item["control_tier"] == "C0"), + "c1_control_candidate_count": sum(1 for item in candidates if item["control_tier"] == "C1"), + "p0_control_candidate_count": sum(1 for item in candidates if item["priority"] == "P0"), + "urgent_prevention_candidate_count": len(candidates), + "maintenance_window_required_candidate_count": count_if(candidates, "requires_maintenance_window"), + "break_glass_required_candidate_count": count_if(candidates, "requires_break_glass_record"), + "owner_approval_required_candidate_count": count_if(candidates, "requires_owner_approval"), + "cross_project_sync_required_candidate_count": count_if(candidates, "requires_cross_project_sync"), + "rollback_required_candidate_count": count_if(candidates, "requires_rollback_plan"), + "validation_required_candidate_count": count_if(candidates, "requires_validation_plan"), + "wazuh_event_required_candidate_count": count_if(candidates, "requires_wazuh_event_refs"), + "host_forensics_required_candidate_count": count_if(candidates, "requires_host_forensics_refs"), + "config_diff_required_candidate_count": count_if(candidates, "requires_config_diff_refs"), + "backup_restore_required_candidate_count": sum(1 for item in candidates if item["prevention_domain"] == "backup_restore_resilience"), + "no_false_green_required_candidate_count": len(candidates), + "required_owner_field_count": len(REQUIRED_OWNER_FIELDS), + "reviewer_check_count": len(REVIEWER_CHECKS), + "outcome_lane_count": len(OUTCOME_LANES), + "blocked_action_count": len(BLOCKED_ACTIONS), + "coverage_percent_after_prevention_control": 74, + "docker_compose_systemd_host_config_coverage_percent_after_prevention_control": 68, + "ssh_firewall_network_access_coverage_percent_after_prevention_control": 70, + "monitoring_alerting_observability_coverage_percent_after_prevention_control": 74, + "owner_response_received_count": 0, + "owner_response_accepted_count": 0, + "evidence_ref_received_count": 0, + "evidence_ref_accepted_count": 0, + "prevention_control_accepted_count": 0, + "containment_decision_accepted_count": 0, + "maintenance_window_accepted_count": 0, + "rollback_plan_accepted_count": 0, + "postcheck_accepted_count": 0, + "wazuh_active_response_enabled_count": 0, + "host_write_authorized_count": 0, + "ssh_write_authorized_count": 0, + "firewall_change_authorized_count": 0, + "nginx_reload_authorized_count": 0, + "docker_restart_authorized_count": 0, + "systemctl_restart_authorized_count": 0, + "argocd_sync_authorized_count": 0, + "workflow_modification_authorized_count": 0, + "runner_change_authorized_count": 0, + "repo_secret_change_authorized_count": 0, + "secret_value_collection_allowed_count": 0, + "active_scan_authorized_count": 0, + "package_upgrade_authorized_count": 0, + "production_write_authorized_count": 0, + "runtime_gate_count": 0, + "action_button_count": 0, + }, + "execution_boundaries": EXECUTION_BOUNDARIES, + "prevention_domains": PREVENTION_DOMAINS, + "control_candidates": candidates, + "required_owner_fields": REQUIRED_OWNER_FIELDS, + "reviewer_checks": REVIEWER_CHECKS, + "outcome_lanes": OUTCOME_LANES, + "blocked_actions": BLOCKED_ACTIONS, + "operator_interpretation": [ + "這份矩陣把外部入侵防堵前移成 P0 控制候選,但不是 host write 或 firewall change 授權。", + "IwoooS 先拒收假綠燈:route 200、dashboard up、CD success、UI 可見、agent active 或外部 Agent 宣稱都不能單獨當成已防堵。", + "真正能進 runtime 的防堵需 owner role / team、decision reason、維護窗口、rollback owner、validation metrics、postcheck 與跨專案同步。", + "前台只能顯示 alias、候選數、缺口與 0/false 邊界,不顯示內網 IP、帳號 namespace、raw log、secret 或工作視窗內容。", + ], + } + + +def main() -> int: + parser = argparse.ArgumentParser(description="IwoooS 外部入侵主機防堵控制矩陣") + parser.add_argument("--root", default=".", help="repo root") + parser.add_argument("--output", help="寫出 JSON 報告") + parser.add_argument("--generated-at", help="固定報告時間,供 committed snapshot 使用") + args = parser.parse_args() + + root = Path(args.root).resolve() + report = build_report(root, args.generated_at) + payload = json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + + if args.output: + output = Path(args.output) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(payload + "\n", encoding="utf-8") + else: + print(payload) + + summary = report["summary"] + print( + "EXTERNAL_HOST_INTRUSION_PREVENTION_CONTROL_OK " + f"domains={summary['prevention_domain_count']} " + f"candidates={summary['control_candidate_count']} " + f"hosts={summary['host_alias_count']} " + f"checks={summary['reviewer_check_count']} " + f"blocked={summary['blocked_action_count']} " + f"runtime_gate={summary['runtime_gate_count']}", + file=sys.stderr, + ) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/security/high-value-config-control-coverage.py b/scripts/security/high-value-config-control-coverage.py index 18815e1ea..af333b007 100644 --- a/scripts/security/high-value-config-control-coverage.py +++ b/scripts/security/high-value-config-control-coverage.py @@ -151,8 +151,8 @@ CONTROL_STATUS_BY_CATEGORY = { "next_owner_action": "補 repo owner、external agent owner、treasury owner、runtime gate owner、maintenance window、rollback owner 與 validation plan。", }, "monitoring_alerting_observability": { - "coverage_status": "wazuh_intrusion_readback_plan_ready_needs_wazuh_owner_evidence", - "coverage_percent": 72, + "coverage_status": "external_host_intrusion_prevention_control_ready_needs_wazuh_owner_evidence", + "coverage_percent": 74, "evidence_refs": [ "docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md", "docs/security/MONITORING-ALERTING-OBSERVABILITY-INVENTORY.md", @@ -166,15 +166,18 @@ CONTROL_STATUS_BY_CATEGORY = { "docs/security/WAZUH-IWOOOS-INTRUSION-READBACK-PLAN.md", "docs/security/wazuh-iwooos-intrusion-readback-plan.snapshot.json", "scripts/security/wazuh-iwooos-intrusion-readback-plan.py", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", "apps/web/src/app/api/iwooos/wazuh/route.ts", "docs/schemas/monitoring_alerting_observability_inventory_v1.schema.json", ], - "current_gap": "已固定 60 份 monitoring / alerting / observability owner response acceptance candidate、事故後回讀計畫,並新增 Wazuh / 主機入侵 readback plan;Wazuh 平台、host-110 / host-188 入侵訊號、外部 Agent live 變更宣稱、Runner / secret / gateway 連動、containment / recovery proof、hardcoded credential 拒收與 active response 邊界已納入;仍缺 Wazuh manager health ref、agent status ref、Wazuh event refs、host forensic refs、containment decision、recovery proof、postcheck、recurrence guard、owner response 與 maintenance window。", - "next_owner_action": "補 Wazuh / 主機入侵事故回讀包:manager / indexer / dashboard / API health ref、host-110 / host-188 agent status ref、event / alert refs、auth log、process tree、network connection、FIM、package inventory、persistence refs、actor attribution、incident time window、affected scope、containment decision、recovery proof、independent postcheck、recurrence guard、cross-project sync、rollback owner、followup owner 與 no-secret / no-raw-payload / no-false-green attestation。", + "current_gap": "已固定 60 份 monitoring / alerting / observability owner response acceptance candidate、事故後回讀計畫、Wazuh / 主機入侵 readback plan,並新增外部入侵主機防堵控制矩陣;Wazuh 平台、host alias 入侵訊號、外部 Agent live 變更宣稱、Runner / secret / gateway 連動、active response dry-run、防再發與 no-false-green 已納入;仍缺 Wazuh manager health ref、agent status ref、Wazuh event refs、host forensic refs、containment decision、recovery proof、postcheck、recurrence guard、owner response 與 maintenance window。", + "next_owner_action": "補 Wazuh / 主機入侵防堵包:manager / indexer / dashboard / API health ref、host alias agent status ref、event / alert refs、auth log、process tree、network connection、FIM、package inventory、persistence refs、actor attribution、incident time window、affected scope、containment decision、active response dry-run blast radius、recovery proof、independent postcheck、recurrence guard、cross-project sync、rollback owner、followup owner 與 no-secret / no-raw-payload / no-false-green attestation。", }, "docker_compose_systemd_host_config": { - "coverage_status": "post_incident_readback_plan_ready_needs_host_service_owner_evidence", - "coverage_percent": 64, + "coverage_status": "external_host_intrusion_prevention_control_ready_needs_host_service_owner_evidence", + "coverage_percent": 68, "evidence_refs": [ "docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md", "docs/security/HOST-SERVICE-CONFIG-INVENTORY.md", @@ -187,14 +190,17 @@ CONTROL_STATUS_BY_CATEGORY = { "docs/security/host-service-change-evidence-acceptance.snapshot.json", "docs/security/HOST-SERVICE-POST-INCIDENT-READBACK-PLAN.md", "docs/security/host-service-post-incident-readback-plan.snapshot.json", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", "docs/security/DEV-HOSTS-112-111-168-OBSERVE-ONLY-MAPPING.md", ], - "current_gap": "已固定 9 份 Docker / systemd / host service owner response acceptance candidate、change evidence acceptance 與 post-incident readback plan;重啟 actor、boot / recovery window、before / after state、Docker daemon、compose / systemd state、failed unit、port binding、dependency、public/admin route recovery、AI provider health、monitoring alert、operator notice、cross-project sync、restoration、recurrence guard 與 no-false-green 皆已納入只讀帳本;仍缺 owner response、live hash、事故回讀包、maintenance / restart window、rollback owner、post-check plan、disable switch 與 no-secret-value evidence。", - "next_owner_action": "補 host service 事故回讀包:owner-provided live hash / disposition、change / incident ref、actor role / team、boot time、restart / recovery window、before / after state、Docker daemon state、compose / systemd state、failed unit review、port binding、服務依賴圖、public/admin route recovery、AI provider health、monitoring alert、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner、post-check plan 與 no-secret-value evidence。", + "current_gap": "已固定 9 份 Docker / systemd / host service owner response acceptance candidate、change evidence acceptance、post-incident readback plan 與外部入侵防堵控制矩陣;重啟 actor、boot / recovery window、before / after state、Docker daemon、compose / systemd state、failed unit、port binding、dependency、process / persistence baseline、public/admin route recovery、AI provider health、monitoring alert、operator notice、cross-project sync、restoration、recurrence guard 與 no-false-green 皆已納入;仍缺 owner response、live hash、Wazuh / host forensic refs、maintenance / restart window、rollback owner、post-check plan、disable switch 與 no-secret-value evidence。", + "next_owner_action": "補 host service 防堵包:owner-provided live hash / disposition、change / incident ref、actor role / team、boot time、restart / recovery window、before / after state、Docker daemon state、compose / systemd state、failed unit review、port binding、process / persistence refs、服務依賴圖、public/admin route recovery、AI provider health、monitoring alert、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner、post-check plan 與 no-secret-value evidence。", }, "ssh_firewall_network_access": { - "coverage_status": "post_incident_readback_plan_ready_needs_network_owner_evidence", - "coverage_percent": 64, + "coverage_status": "external_host_intrusion_prevention_control_ready_needs_network_owner_evidence", + "coverage_percent": 70, "evidence_refs": [ "docs/HARD_RULES.md", "docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md", @@ -208,9 +214,12 @@ CONTROL_STATUS_BY_CATEGORY = { "docs/security/port-firewall-change-evidence-acceptance.snapshot.json", "docs/security/SSH-NETWORK-POST-INCIDENT-READBACK-PLAN.md", "docs/security/ssh-network-post-incident-readback-plan.snapshot.json", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", ], - "current_gap": "owner response acceptance、端口 / 防火牆事故型變更證據驗收與 post-incident readback plan 都已固定;仍缺 owner-provided change / incident evidence、actor、before / after state、service / AI provider / monitoring impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check evidence。", - "next_owner_action": "補端口 / 防火牆事故回讀包:change / incident ref、actor role / team、affected scope、before / after state、service dependency、public route impact、AI provider impact、monitoring alert impact、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner 與 post-check 指標。", + "current_gap": "owner response acceptance、端口 / 防火牆事故型變更證據驗收、post-incident readback plan 與外部入侵防堵控制矩陣都已固定;SSH / sudo、authorized_keys、known_hosts、firewall、WireGuard、NodePort、NetworkPolicy、port close / open 與 break-glass 邊界已納入;仍缺 owner-provided change / incident evidence、actor、before / after state、Wazuh / host forensic refs、service / AI provider / monitoring impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check evidence。", + "next_owner_action": "補 SSH / 端口 / 防火牆防堵包:change / incident ref、actor role / team、affected scope、before / after state、service dependency、public route impact、AI provider impact、monitoring alert impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check 指標。", }, "ai_provider_model_routing": { "coverage_status": "owner_response_acceptance_ready_needs_provider_owner_evidence", @@ -414,14 +423,17 @@ def build_report(root: Path, generated_at: str | None) -> dict[str, Any]: "alert_chain_no_false_green_backfill_ready_needs_live_evidence_receipt", "post_incident_readback_plan_ready_needs_monitoring_owner_evidence", "wazuh_intrusion_readback_plan_ready_needs_wazuh_owner_evidence", + "external_host_intrusion_prevention_control_ready_needs_wazuh_owner_evidence", "change_evidence_acceptance_ready_needs_network_owner_evidence", "incident_change_evidence_acceptance_ready_needs_network_owner_evidence", "post_incident_readback_plan_ready_needs_network_owner_evidence", + "external_host_intrusion_prevention_control_ready_needs_network_owner_evidence", "policy_ready_needs_drift_evidence", "inventory_needed", "repo_only_inventory_ready_needs_live_owner_evidence", "incident_recovery_backfill_ready_needs_live_owner_evidence", "change_evidence_acceptance_ready_needs_host_service_owner_evidence", + "external_host_intrusion_prevention_control_ready_needs_host_service_owner_evidence", "policy_ready_needs_network_matrix", "policy_ready_needs_dry_run_pack", "owner_response_acceptance_ready_needs_provider_owner_evidence", @@ -471,11 +483,11 @@ def build_report(root: Path, generated_at: str | None) -> dict[str, Any]: "secret_metadata", "gitea_workflow_runner_source_control", "public_admin_api_runtime_config", - "agent_bounty_protocol_runtime", - "docker_compose_systemd_host_config", "ssh_firewall_network_access", - "ai_provider_model_routing", + "docker_compose_systemd_host_config", "monitoring_alerting_observability", + "agent_bounty_protocol_runtime", + "ai_provider_model_routing", "backup_restore_credential", ], "operator_interpretation": [ diff --git a/scripts/security/iwooos-config-control-guard.py b/scripts/security/iwooos-config-control-guard.py index 840e6b722..33899335a 100644 --- a/scripts/security/iwooos-config-control-guard.py +++ b/scripts/security/iwooos-config-control-guard.py @@ -25,9 +25,9 @@ EXPECTED_CATEGORIES = { "public_admin_api_runtime_config": 66, "backup_restore_credential": 66, "agent_bounty_protocol_runtime": 68, - "monitoring_alerting_observability": 70, - "docker_compose_systemd_host_config": 64, - "ssh_firewall_network_access": 64, + "monitoring_alerting_observability": 74, + "docker_compose_systemd_host_config": 68, + "ssh_firewall_network_access": 70, "ai_provider_model_routing": 64, "product_surface_runtime_routes": 72, "security_evidence_tooling": 86, @@ -69,6 +69,7 @@ REQUIRED_CONTROL_DOCS = [ "docs/security/MONITORING-OWNER-REQUEST-DRAFT.md", "docs/security/MONITORING-POST-INCIDENT-READBACK-PLAN.md", "docs/security/WAZUH-IWOOOS-INTRUSION-READBACK-PLAN.md", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", "docs/security/AI-PROVIDER-OWNER-RESPONSE-ACCEPTANCE.md", "docs/security/AGENT-BOUNTY-OWNER-REQUEST-DRAFT.md", "docs/security/SECURITY-SUPPLY-CHAIN-CONTRACT-MANIFEST.md", @@ -858,6 +859,75 @@ ARTIFACT_SPECS = [ "coverage_percent_after_readback_plan": 72, }, }, + { + "label": "external host intrusion prevention control", + "path": "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "schema": "external_host_intrusion_prevention_control_v1", + "status": "external_host_intrusion_prevention_control_ready_no_runtime_action", + "list_counts": { + "prevention_domains": 12, + "control_candidates": 14, + "blocked_actions": 82, + "reviewer_checks": 34, + "outcome_lanes": 12, + "required_owner_fields": 36, + }, + "summary_counts": { + "prevention_domain_count": 12, + "host_alias_count": 4, + "sensor_alias_count": 1, + "control_candidate_count": 14, + "c0_control_candidate_count": 10, + "c1_control_candidate_count": 4, + "p0_control_candidate_count": 14, + "urgent_prevention_candidate_count": 14, + "maintenance_window_required_candidate_count": 14, + "break_glass_required_candidate_count": 10, + "owner_approval_required_candidate_count": 14, + "cross_project_sync_required_candidate_count": 14, + "rollback_required_candidate_count": 14, + "validation_required_candidate_count": 14, + "wazuh_event_required_candidate_count": 7, + "host_forensics_required_candidate_count": 6, + "config_diff_required_candidate_count": 8, + "backup_restore_required_candidate_count": 1, + "no_false_green_required_candidate_count": 14, + "required_owner_field_count": 36, + "reviewer_check_count": 34, + "outcome_lane_count": 12, + "blocked_action_count": 82, + "coverage_percent_after_prevention_control": 74, + "docker_compose_systemd_host_config_coverage_percent_after_prevention_control": 68, + "ssh_firewall_network_access_coverage_percent_after_prevention_control": 70, + "monitoring_alerting_observability_coverage_percent_after_prevention_control": 74, + "owner_response_received_count": 0, + "owner_response_accepted_count": 0, + "evidence_ref_received_count": 0, + "evidence_ref_accepted_count": 0, + "prevention_control_accepted_count": 0, + "containment_decision_accepted_count": 0, + "maintenance_window_accepted_count": 0, + "rollback_plan_accepted_count": 0, + "postcheck_accepted_count": 0, + "wazuh_active_response_enabled_count": 0, + "host_write_authorized_count": 0, + "ssh_write_authorized_count": 0, + "firewall_change_authorized_count": 0, + "nginx_reload_authorized_count": 0, + "docker_restart_authorized_count": 0, + "systemctl_restart_authorized_count": 0, + "argocd_sync_authorized_count": 0, + "workflow_modification_authorized_count": 0, + "runner_change_authorized_count": 0, + "repo_secret_change_authorized_count": 0, + "secret_value_collection_allowed_count": 0, + "active_scan_authorized_count": 0, + "package_upgrade_authorized_count": 0, + "production_write_authorized_count": 0, + "runtime_gate_count": 0, + "action_button_count": 0, + }, + }, { "label": "ai provider owner response acceptance", "path": "docs/security/ai-provider-owner-response-acceptance.snapshot.json", diff --git a/scripts/security/security-mirror-progress-guard.py b/scripts/security/security-mirror-progress-guard.py index 664dfc945..30e995102 100755 --- a/scripts/security/security-mirror-progress-guard.py +++ b/scripts/security/security-mirror-progress-guard.py @@ -191,6 +191,9 @@ def validate(root: Path) -> None: monitoring_post_incident_readback_plan = load_json( security_dir / "monitoring-post-incident-readback-plan.snapshot.json" ) + external_host_intrusion_prevention_control = load_json( + security_dir / "external-host-intrusion-prevention-control.snapshot.json" + ) ai_provider_owner_response_acceptance = load_json( security_dir / "ai-provider-owner-response-acceptance.snapshot.json" ) @@ -2779,7 +2782,7 @@ def validate(root: Path) -> None: assert_equal( "high_value_config_coverage.summary.needs_live_evidence_count", high_value_config_coverage["summary"]["needs_live_evidence_count"], - 9, + 10, ) for key in [ "owner_response_received_count", @@ -3191,11 +3194,6 @@ def validate(root: Path) -> None: public_runtime_config_category["evidence_refs"], evidence_ref, ) - assert_contains( - "high_value_config_coverage.lowest_coverage_categories.docker", - [item["category_id"] for item in high_value_config_coverage["lowest_coverage_categories"]], - "docker_compose_systemd_host_config", - ) docker_systemd_category = next( item for item in high_value_config_coverage["coverage_categories"] @@ -3204,12 +3202,12 @@ def validate(root: Path) -> None: assert_equal( "high_value_config_coverage.coverage_categories.docker.coverage_percent", docker_systemd_category["coverage_percent"], - 64, + 68, ) assert_equal( "high_value_config_coverage.coverage_categories.docker.coverage_status", docker_systemd_category["coverage_status"], - "post_incident_readback_plan_ready_needs_host_service_owner_evidence", + "external_host_intrusion_prevention_control_ready_needs_host_service_owner_evidence", ) for evidence_ref in [ "docs/security/HOST-SERVICE-CONFIG-INVENTORY.md", @@ -3222,6 +3220,9 @@ def validate(root: Path) -> None: "docs/security/host-service-change-evidence-acceptance.snapshot.json", "docs/security/HOST-SERVICE-POST-INCIDENT-READBACK-PLAN.md", "docs/security/host-service-post-incident-readback-plan.snapshot.json", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", ]: assert_contains( "high_value_config_coverage.coverage_categories.docker.evidence_refs", @@ -3236,12 +3237,12 @@ def validate(root: Path) -> None: assert_equal( "high_value_config_coverage.coverage_categories.ssh_network.coverage_percent", ssh_network_category["coverage_percent"], - 64, + 70, ) assert_equal( "high_value_config_coverage.coverage_categories.ssh_network.coverage_status", ssh_network_category["coverage_status"], - "post_incident_readback_plan_ready_needs_network_owner_evidence", + "external_host_intrusion_prevention_control_ready_needs_network_owner_evidence", ) for evidence_ref in [ "docs/security/SSH-NETWORK-ACCESS-INVENTORY.md", @@ -3252,6 +3253,9 @@ def validate(root: Path) -> None: "docs/security/port-firewall-change-evidence-acceptance.snapshot.json", "docs/security/SSH-NETWORK-POST-INCIDENT-READBACK-PLAN.md", "docs/security/ssh-network-post-incident-readback-plan.snapshot.json", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", ]: assert_contains( "high_value_config_coverage.coverage_categories.ssh_network.evidence_refs", @@ -3321,12 +3325,12 @@ def validate(root: Path) -> None: assert_equal( "high_value_config_coverage.coverage_categories.monitoring.coverage_percent", monitoring_category["coverage_percent"], - 72, + 74, ) assert_equal( "high_value_config_coverage.coverage_categories.monitoring.coverage_status", monitoring_category["coverage_status"], - "wazuh_intrusion_readback_plan_ready_needs_wazuh_owner_evidence", + "external_host_intrusion_prevention_control_ready_needs_wazuh_owner_evidence", ) for evidence_ref in [ "docs/security/MONITORING-ALERTING-OBSERVABILITY-INVENTORY.md", @@ -3340,6 +3344,9 @@ def validate(root: Path) -> None: "docs/security/WAZUH-IWOOOS-INTRUSION-READBACK-PLAN.md", "docs/security/wazuh-iwooos-intrusion-readback-plan.snapshot.json", "scripts/security/wazuh-iwooos-intrusion-readback-plan.py", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", "apps/web/src/app/api/iwooos/wazuh/route.ts", "docs/schemas/monitoring_alerting_observability_inventory_v1.schema.json", ]: @@ -3348,6 +3355,107 @@ def validate(root: Path) -> None: monitoring_category["evidence_refs"], evidence_ref, ) + assert_equal( + "external_host_intrusion_prevention_control.schema", + external_host_intrusion_prevention_control["schema_version"], + "external_host_intrusion_prevention_control_v1", + ) + assert_equal( + "external_host_intrusion_prevention_control.status", + external_host_intrusion_prevention_control["status"], + "external_host_intrusion_prevention_control_ready_no_runtime_action", + ) + assert_equal( + "external_host_intrusion_prevention_control.prevention_domains.count", + len(external_host_intrusion_prevention_control["prevention_domains"]), + 12, + ) + assert_equal( + "external_host_intrusion_prevention_control.control_candidates.count", + len(external_host_intrusion_prevention_control["control_candidates"]), + 14, + ) + assert_equal( + "external_host_intrusion_prevention_control.reviewer_checks.count", + len(external_host_intrusion_prevention_control["reviewer_checks"]), + 34, + ) + assert_equal( + "external_host_intrusion_prevention_control.outcome_lanes.count", + len(external_host_intrusion_prevention_control["outcome_lanes"]), + 12, + ) + assert_equal( + "external_host_intrusion_prevention_control.blocked_actions.count", + len(external_host_intrusion_prevention_control["blocked_actions"]), + 82, + ) + expected_external_host_intrusion_prevention_summary = { + "prevention_domain_count": 12, + "host_alias_count": 4, + "sensor_alias_count": 1, + "control_candidate_count": 14, + "c0_control_candidate_count": 10, + "c1_control_candidate_count": 4, + "p0_control_candidate_count": 14, + "urgent_prevention_candidate_count": 14, + "maintenance_window_required_candidate_count": 14, + "break_glass_required_candidate_count": 10, + "owner_approval_required_candidate_count": 14, + "cross_project_sync_required_candidate_count": 14, + "rollback_required_candidate_count": 14, + "validation_required_candidate_count": 14, + "wazuh_event_required_candidate_count": 7, + "host_forensics_required_candidate_count": 6, + "config_diff_required_candidate_count": 8, + "backup_restore_required_candidate_count": 1, + "no_false_green_required_candidate_count": 14, + "required_owner_field_count": 36, + "reviewer_check_count": 34, + "outcome_lane_count": 12, + "blocked_action_count": 82, + "coverage_percent_after_prevention_control": 74, + "docker_compose_systemd_host_config_coverage_percent_after_prevention_control": 68, + "ssh_firewall_network_access_coverage_percent_after_prevention_control": 70, + "monitoring_alerting_observability_coverage_percent_after_prevention_control": 74, + "owner_response_received_count": 0, + "owner_response_accepted_count": 0, + "evidence_ref_received_count": 0, + "evidence_ref_accepted_count": 0, + "prevention_control_accepted_count": 0, + "containment_decision_accepted_count": 0, + "maintenance_window_accepted_count": 0, + "rollback_plan_accepted_count": 0, + "postcheck_accepted_count": 0, + "wazuh_active_response_enabled_count": 0, + "host_write_authorized_count": 0, + "ssh_write_authorized_count": 0, + "firewall_change_authorized_count": 0, + "nginx_reload_authorized_count": 0, + "docker_restart_authorized_count": 0, + "systemctl_restart_authorized_count": 0, + "argocd_sync_authorized_count": 0, + "workflow_modification_authorized_count": 0, + "runner_change_authorized_count": 0, + "repo_secret_change_authorized_count": 0, + "secret_value_collection_allowed_count": 0, + "active_scan_authorized_count": 0, + "package_upgrade_authorized_count": 0, + "production_write_authorized_count": 0, + "runtime_gate_count": 0, + "action_button_count": 0, + } + for key, expected in expected_external_host_intrusion_prevention_summary.items(): + assert_equal( + f"external_host_intrusion_prevention_control.summary.{key}", + external_host_intrusion_prevention_control["summary"][key], + expected, + ) + for key, value in external_host_intrusion_prevention_control["execution_boundaries"].items(): + if key == "not_authorization": + assert_true(f"external_host_intrusion_prevention_control.execution_boundaries.{key}", value) + else: + assert_false(f"external_host_intrusion_prevention_control.execution_boundaries.{key}", value) assert_equal( "host_service_config_inventory.schema", host_service_config_inventory["schema_version"], @@ -7940,6 +8048,9 @@ def validate(root: Path) -> None: "docs/security/WAZUH-IWOOOS-INTRUSION-READBACK-PLAN.md", "docs/security/wazuh-iwooos-intrusion-readback-plan.snapshot.json", "scripts/security/wazuh-iwooos-intrusion-readback-plan.py", + "docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md", + "docs/security/external-host-intrusion-prevention-control.snapshot.json", + "scripts/security/external-host-intrusion-prevention-control.py", "apps/web/src/app/api/iwooos/wazuh/route.ts", "docs/schemas/monitoring_alerting_observability_inventory_v1.schema.json", "docs/security/public-runtime-config-change-evidence-acceptance.snapshot.json", @@ -7970,7 +8081,7 @@ def validate(root: Path) -> None: "high_value_config_control_coverage_c0_category_count": 8, "high_value_config_control_coverage_c1_category_count": 4, "high_value_config_control_coverage_average_percent": 72, - "high_value_config_control_coverage_needs_live_evidence_count": 9, + "high_value_config_control_coverage_needs_live_evidence_count": 10, "high_value_config_control_coverage_owner_response_required_count": 14, "high_value_config_control_coverage_owner_response_received_count": 0, "high_value_config_control_coverage_owner_response_accepted_count": 0, @@ -7985,6 +8096,15 @@ def validate(root: Path) -> None: "public_frontend_sensitive_surface_guard_runtime_gate_count": 0, "k8s_production_gitops_coverage_percent": 66, "ai_provider_model_routing_coverage_percent": 64, + "docker_compose_systemd_host_config_coverage_percent": 68, + "ssh_firewall_network_access_coverage_percent": 70, + "monitoring_alerting_observability_coverage_percent": 74, + "external_host_intrusion_prevention_control_candidate_count": 14, + "external_host_intrusion_prevention_control_c0_candidate_count": 10, + "external_host_intrusion_prevention_control_required_owner_field_count": 36, + "external_host_intrusion_prevention_control_reviewer_check_count": 34, + "external_host_intrusion_prevention_control_blocked_action_count": 82, + "external_host_intrusion_prevention_control_runtime_gate_count": 0, } for key, expected in expected_high_value_config_coverage_summary.items(): assert_equal( @@ -8100,7 +8220,7 @@ def validate(root: Path) -> None: "host_service_post_incident_readback_plan_runtime_gate_count": 0, "host_service_post_incident_readback_plan_action_button_count": 0, "host_service_post_incident_readback_plan_coverage_percent_after_readback_plan": 64, - "docker_compose_systemd_host_config_coverage_percent": 64, + "docker_compose_systemd_host_config_coverage_percent": 68, } for key, expected in expected_host_service_projection_summary.items(): assert_equal( @@ -13648,6 +13768,8 @@ def validate(root: Path) -> None: "display_vibework_security_onboarding", "display_agent_bounty_security_onboarding", "display_rollout_risk_read_only", + "display_wazuh_intrusion_readback", + "display_external_host_intrusion_prevention_control", "display_high_value_config_owner_packet", "display_awooop_high_value_config_owner_packet_read_only", ]: @@ -18275,6 +18397,119 @@ def validate(root: Path) -> None: iwooos_projection_page, text, ) + for key in ["eyebrow", "title", "subtitle", "boundaryTitle", "boundaryIntro"]: + assert_contains( + "web_messages.zh-TW.iwooos.externalHostIntrusionPreventionControl.keys", + list(web_messages_zh["iwooos"]["externalHostIntrusionPreventionControl"].keys()), + key, + ) + assert_contains( + "web_messages.en.iwooos.externalHostIntrusionPreventionControl.keys", + list(web_messages_en["iwooos"]["externalHostIntrusionPreventionControl"].keys()), + key, + ) + for key in ["domains", "candidates", "hosts", "runtimeGate"]: + assert_contains( + "web_messages.zh-TW.iwooos.externalHostIntrusionPreventionControl.summary", + list(web_messages_zh["iwooos"]["externalHostIntrusionPreventionControl"]["summary"].keys()), + key, + ) + assert_contains( + "web_messages.en.iwooos.externalHostIntrusionPreventionControl.summary", + list(web_messages_en["iwooos"]["externalHostIntrusionPreventionControl"]["summary"].keys()), + key, + ) + for key in [ + "gateway", + "sshFirewall", + "hostRuntime", + "runnerSecret", + "wazuhResponse", + "backupRestore", + "packagePatch", + "sync", + ]: + assert_contains( + "web_messages.zh-TW.iwooos.externalHostIntrusionPreventionControl.items", + list(web_messages_zh["iwooos"]["externalHostIntrusionPreventionControl"]["items"].keys()), + key, + ) + assert_contains( + "web_messages.en.iwooos.externalHostIntrusionPreventionControl.items", + list(web_messages_en["iwooos"]["externalHostIntrusionPreventionControl"]["items"].keys()), + key, + ) + assert_text_contains( + "iwooos_page.external_host_intrusion_prevention_control_testid", + iwooos_projection_page, + 'data-testid="iwooos-external-host-intrusion-prevention-control-board"', + ) + assert_text_contains( + "iwooos_page.external_host_intrusion_prevention_control_boundary_testid", + iwooos_projection_page, + 'data-testid="iwooos-external-host-intrusion-prevention-control-boundaries"', + ) + assert_text_before( + "iwooos_page.external_host_intrusion_after_wazuh", + iwooos_projection_page, + "", + "", + ) + assert_text_before( + "iwooos_page.external_host_intrusion_before_config_priority", + iwooos_projection_page, + "", + "", + ) + for text in [ + "external_host_intrusion_prevention_control_visible=true", + "external_host_intrusion_prevention_control_domain_count=12", + "external_host_intrusion_prevention_control_candidate_count=14", + "external_host_intrusion_prevention_control_c0_candidate_count=10", + "external_host_intrusion_prevention_control_c1_candidate_count=4", + "external_host_intrusion_prevention_control_p0_candidate_count=14", + "external_host_intrusion_prevention_control_host_alias_count=4", + "external_host_intrusion_prevention_control_sensor_alias_count=1", + "external_host_intrusion_prevention_control_required_owner_field_count=36", + "external_host_intrusion_prevention_control_reviewer_check_count=34", + "external_host_intrusion_prevention_control_outcome_lane_count=12", + "external_host_intrusion_prevention_control_blocked_action_count=82", + "external_host_intrusion_prevention_control_wazuh_event_required_candidate_count=7", + "external_host_intrusion_prevention_control_host_forensics_required_candidate_count=6", + "external_host_intrusion_prevention_control_config_diff_required_candidate_count=8", + "external_host_intrusion_prevention_control_owner_response_received_count=0", + "external_host_intrusion_prevention_control_owner_response_accepted_count=0", + "external_host_intrusion_prevention_control_evidence_ref_received_count=0", + "external_host_intrusion_prevention_control_evidence_ref_accepted_count=0", + "external_host_intrusion_prevention_control_prevention_control_accepted_count=0", + "external_host_intrusion_prevention_control_wazuh_active_response_enabled_count=0", + "external_host_intrusion_prevention_control_host_write_authorized_count=0", + "external_host_intrusion_prevention_control_firewall_change_authorized_count=0", + "external_host_intrusion_prevention_control_nginx_reload_authorized_count=0", + "external_host_intrusion_prevention_control_package_upgrade_authorized_count=0", + "external_host_intrusion_prevention_control_active_scan_authorized_count=0", + "external_host_intrusion_prevention_control_runtime_gate_count=0", + "external_host_intrusion_prevention_control_action_button_count=0", + "docker_compose_systemd_host_config_coverage_percent=68", + "ssh_firewall_network_access_coverage_percent=70", + "monitoring_alerting_observability_coverage_percent=74", + "host_write_authorized=false", + "ssh_write_authorized=false", + "firewall_change_authorized=false", + "nginx_reload_authorized=false", + "wazuh_active_response_authorized=false", + "package_upgrade_authorized=false", + "active_scan_authorized=false", + "runtime_execution_authorized=false", + "active_runtime_gate_count=0", + "action_buttons_allowed=false", + "not_authorization=true", + ]: + assert_text_contains( + "iwooos_page.external_host_intrusion_prevention_control_boundary", + iwooos_projection_page, + text, + ) assert_text_contains( "iwooos_page.high_value_config_control_coverage_testid", iwooos_projection_page, @@ -18293,12 +18528,12 @@ def validate(root: Path) -> None: assert_text_contains( "iwooos_page.high_value_config_control_coverage_docker_systemd_percent", iwooos_projection_page, - "{ key: 'dockerSystemd', rank: 'P1-1', value: '64%'", + "{ key: 'dockerSystemd', rank: 'P1-1', value: '68%'", ) assert_text_contains( "iwooos_page.high_value_config_control_coverage_ssh_network_percent", iwooos_projection_page, - "{ key: 'sshNetwork', rank: 'P1-2', value: '64%'", + "{ key: 'sshNetwork', rank: 'P1-2', value: '70%'", ) assert_text_contains( "iwooos_page.high_value_config_control_coverage_ai_provider_percent", @@ -18323,7 +18558,7 @@ def validate(root: Path) -> None: "high_value_config_control_coverage_c0_category_count=8", "high_value_config_control_coverage_c1_category_count=4", "high_value_config_control_coverage_average_percent=72", - "high_value_config_control_coverage_needs_live_evidence_count=9", + "high_value_config_control_coverage_needs_live_evidence_count=10", "high_value_config_control_coverage_owner_response_required_count=14", "high_value_config_control_coverage_owner_response_received_count=0", "high_value_config_control_coverage_owner_response_accepted_count=0", @@ -18338,6 +18573,9 @@ def validate(root: Path) -> None: "secret_metadata_coverage_percent=70", "gitea_workflow_runner_source_control_coverage_percent=74", "public_admin_api_runtime_config_coverage_percent=66", + "docker_compose_systemd_host_config_coverage_percent=68", + "ssh_firewall_network_access_coverage_percent=70", + "monitoring_alerting_observability_coverage_percent=74", "ai_provider_model_routing_coverage_percent=64", "ai_provider_owner_response_acceptance_candidate_count=8", "ai_provider_owner_response_acceptance_write_capable_candidate_count=5", @@ -18603,7 +18841,7 @@ def validate(root: Path) -> None: "monitoring_alerting_observability_inventory_reload_owner_accepted_count=0", "monitoring_alerting_observability_inventory_receiver_owner_accepted_count=0", "monitoring_alerting_observability_inventory_route_smoke_accepted_count=0", - "monitoring_alerting_observability_coverage_percent=72", + "monitoring_alerting_observability_coverage_percent=74", "monitoring_owner_response_acceptance_reviewer_check_count=23", "monitoring_owner_response_acceptance_outcome_lane_count=12", "monitoring_owner_response_acceptance_blocked_action_count=34", @@ -19106,12 +19344,12 @@ def validate(root: Path) -> None: assert_text_contains( "web_messages.zh-TW.iwooos.highValueConfigControlCoverage.items.sshNetwork.body", web_messages_zh["iwooos"]["highValueConfigControlCoverage"]["items"]["sshNetwork"]["body"], - "14 個事故回讀候選、24 個 reviewer checks、10 條 outcome lanes、34 類 blocked action", + "目前成熟度 70%", ) assert_text_contains( "web_messages.en.iwooos.highValueConfigControlCoverage.items.sshNetwork.body", web_messages_en["iwooos"]["highValueConfigControlCoverage"]["items"]["sshNetwork"]["body"], - "14 個事故回讀候選、24 個 reviewer checks、10 條 outcome lanes、34 類 blocked action", + "目前成熟度 70%", ) assert_text_contains( "web_messages.zh-TW.iwooos.highValueConfigControlCoverage.items.backupRestore.body",