diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index bf062af7..eabac9b1 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -21021,7 +21021,7 @@ }, "evidencePercent": { "label": "完成度", - "detail": "56% 是 evidence-weighted 作戰體制完成度,不代表入侵已清除或 runtime 已授權。" + "detail": "62% 是 evidence-weighted 作戰體制完成度;Wazuh manager registry 已驗收 6 個公開別名,但不代表入侵已清除或 runtime 已授權。" }, "runtimeGate": { "label": "執行期", @@ -21035,7 +21035,7 @@ }, "wazuhRegistry": { "title": "Wazuh registry 還是第一個硬 Gate", - "body": "需要 manager registry 的 agent total、active、disconnected、last seen 與 expected minimum;Dashboard 可見不能代替。" + "body": "manager registry owner export 與 acceptance evidence 已通過 no-persist 驗收,6 個公開別名已接受;Dashboard 可見仍不能替代 runtime gate 或維護 postcheck。" }, "incidentCase": { "title": "入侵與漂移必須形成 case", @@ -21167,7 +21167,7 @@ }, "accepted": { "label": "已接受", - "detail": "owner response、事件證據與 registry acceptance 仍為 0%。" + "detail": "registry acceptance 已為 6 個公開別名;owner incident evidence、case acceptance 與 runtime 仍為 0。" }, "runtimeGate": { "label": "執行期", @@ -21177,7 +21177,7 @@ "items": { "wazuhApi": { "title": "Wazuh API / registry 是第一硬 Gate", - "body": "API connection 與 API version 仍未通過;index pattern 綠燈不能替代 manager registry 與逐主機納管證據。" + "body": "manager registry evidence 已覆蓋 6 個公開別名;index pattern 或 Dashboard 綠燈仍不能替代 runtime gate、active response 或逐主機維護 postcheck。" }, "hostForensics": { "title": "主機入侵不能只靠宣稱", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index bf062af7..eabac9b1 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -21021,7 +21021,7 @@ }, "evidencePercent": { "label": "完成度", - "detail": "56% 是 evidence-weighted 作戰體制完成度,不代表入侵已清除或 runtime 已授權。" + "detail": "62% 是 evidence-weighted 作戰體制完成度;Wazuh manager registry 已驗收 6 個公開別名,但不代表入侵已清除或 runtime 已授權。" }, "runtimeGate": { "label": "執行期", @@ -21035,7 +21035,7 @@ }, "wazuhRegistry": { "title": "Wazuh registry 還是第一個硬 Gate", - "body": "需要 manager registry 的 agent total、active、disconnected、last seen 與 expected minimum;Dashboard 可見不能代替。" + "body": "manager registry owner export 與 acceptance evidence 已通過 no-persist 驗收,6 個公開別名已接受;Dashboard 可見仍不能替代 runtime gate 或維護 postcheck。" }, "incidentCase": { "title": "入侵與漂移必須形成 case", @@ -21167,7 +21167,7 @@ }, "accepted": { "label": "已接受", - "detail": "owner response、事件證據與 registry acceptance 仍為 0%。" + "detail": "registry acceptance 已為 6 個公開別名;owner incident evidence、case acceptance 與 runtime 仍為 0。" }, "runtimeGate": { "label": "執行期", @@ -21177,7 +21177,7 @@ "items": { "wazuhApi": { "title": "Wazuh API / registry 是第一硬 Gate", - "body": "API connection 與 API version 仍未通過;index pattern 綠燈不能替代 manager registry 與逐主機納管證據。" + "body": "manager registry evidence 已覆蓋 6 個公開別名;index pattern 或 Dashboard 綠燈仍不能替代 runtime gate、active response 或逐主機維護 postcheck。" }, "hostForensics": { "title": "主機入侵不能只靠宣稱", diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx index f90ca79c..1aba5bf6 100644 --- a/apps/web/src/app/[locale]/iwooos/page.tsx +++ b/apps/web/src/app/[locale]/iwooos/page.tsx @@ -2514,13 +2514,13 @@ const securityOperatingSystemSummary = [ { key: 'workstreams', value: '24', icon: ListChecks, tone: 'steady' }, { key: 'p0', value: '12', icon: AlertTriangle, tone: 'warn' }, { key: 'alertContract', value: '9', icon: Bell, tone: 'steady' }, - { key: 'evidencePercent', value: '56%', icon: Activity, tone: 'warn' }, + { key: 'evidencePercent', value: '62%', icon: Activity, tone: 'warn' }, { key: 'runtimeGate', value: '0', icon: Lock, tone: 'locked' }, ] as const const securityOperatingSystemItems: SecurityOperatingSystemItem[] = [ { key: 'assetGraph', check: 'SYS-1', state: 'P0', icon: Network, tone: 'warn' }, - { key: 'wazuhRegistry', check: 'SYS-2', state: '0%', icon: Radar, tone: 'locked' }, + { key: 'wazuhRegistry', check: 'SYS-2', state: '100% / 6', icon: Radar, tone: 'steady' }, { key: 'incidentCase', check: 'SYS-3', state: '待 case', icon: FileWarning, tone: 'warn' }, { key: 'alertContract', check: 'SYS-4', state: '已固定', icon: Bell, tone: 'steady' }, { key: 'configControl', check: 'SYS-5', state: 'P0', icon: Route, tone: 'warn' }, @@ -2545,8 +2545,9 @@ const securityOperatingSystemBoundaries = [ 'iwooos_security_operating_system_cross_session_sync_checkpoint_count=7', 'iwooos_security_operating_system_blocked_action_count=18', 'iwooos_security_operating_system_source_control_artifact_percent=100', - 'iwooos_security_operating_system_evidence_weighted_percent=56', - 'iwooos_security_operating_system_wazuh_registry_acceptance_percent=0', + 'iwooos_security_operating_system_evidence_weighted_percent=62', + 'iwooos_security_operating_system_wazuh_registry_acceptance_percent=100', + 'iwooos_security_operating_system_wazuh_registry_accepted_count=6', 'iwooos_security_operating_system_runtime_response_percent=0', 'iwooos_security_operating_system_owner_response_received_count=0', 'iwooos_security_operating_system_owner_response_accepted_count=0', diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index c8c1a91f..9c9d2598 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,17 @@ +## 2026-06-28 — 14:20 IwoooS Wazuh manager registry 驗收口徑收斂 + +**完成內容**: +- Production `GET /api/v1/iwooos/wazuh-manager-registry-reviewer-validation` 已讀回 `owner_registry_export_received_count=1`、`owner_registry_export_accepted_count=1`、`reviewer_validation_passed_count=1`、`manager_registry_accepted_count=6`,且 `runtime_gate_count=0`、`host_write_authorized_count=0`、`active_response_authorized_count=0`、`secret_value_collection_allowed_count=0`。 +- Production valid POST `validate-owner-export` 與 `validate-manager-registry-acceptance` 皆回 accepted;POST 前後 GET counters 完全一致,`NO_PERSIST=True`。 +- Source / snapshot / guard / 前台同步:`wazuh-managed-host-coverage-gate`、`wazuh-manager-registry-reviewer-validation`、`iwooos-security-operating-system` 與 `security-mirror-progress-guard.py` 全部改讀 manager registry accepted `6`、gap `0`、registry acceptance `100%`;IwoooS security operating system 完成度保守上修為 `62%`,runtime response 仍 `0%`。 + +**驗證結果**: +- `DATABASE_URL=sqlite:///test.db PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_iwooos_wazuh_managed_host_coverage.py apps/api/tests/test_iwooos_wazuh_manager_registry_reviewer_validation.py apps/api/tests/test_iwooos_security_control_coverage.py apps/api/tests/test_iwooos_runtime_security_readback.py -q`:`33 passed`。 +- `python3 scripts/security/security-mirror-progress-guard.py --root .`:通過。 +- `pnpm --filter @awoooi/web exec tsc --noEmit --incremental false`:通過。 + +**邊界**:沒有查 live Wazuh、沒有 Wazuh active response、沒有 host write、沒有 secret 讀取、沒有 Nginx / firewall / DB / K8s runtime 變更、沒有 force push。下一步是 P0 告警可讀性與 receipt、Nginx / Gateway config-control、主機入侵與鑑識的下一個 owner packet / controlled verifier。 + ## 2026-06-28 — 10:34 110 cd-lane 外部 opener 止血與 188 source-aware gate 收斂 **背景**:09:44 後 `awoooi-cd-lane.service` 仍在 10:03、10:22 後多次被還原為 `enabled / active`,binary 又回到 ELF,並可接 Gitea Actions task;後續確認不是 Docker / Nginx / Harbor 事故,而是 110 runner / direct CD lane 壓力事故與外部 opener 反覆恢復。 diff --git a/docs/security/IWOOOS-SECURITY-OPERATING-SYSTEM.md b/docs/security/IWOOOS-SECURITY-OPERATING-SYSTEM.md index ceabf080..1df1a1eb 100644 --- a/docs/security/IWOOOS-SECURITY-OPERATING-SYSTEM.md +++ b/docs/security/IWOOOS-SECURITY-OPERATING-SYSTEM.md @@ -55,14 +55,14 @@ | 跨 session 同步檢查點 | `7` | | blocked action | `18` | | source artifact 完成度 | `100%` | -| evidence-weighted 資安作戰系統完成度 | `56%` | +| evidence-weighted 資安作戰系統完成度 | `62%` | | SOC / SIEM 框架可視化成熟度 | `92%` | -| Wazuh manager registry 驗收 | `0%` | +| Wazuh manager registry 驗收 | `100% / 6` | | runtime response | `0%` | | owner response received / accepted | `0 / 0` | | runtime gate / action button | `0 / 0` | -`56%` 是保守 evidence-weighted 完成度:代表作戰制度、優先序、資料結構、前台邊界與 guard 已形成;不代表主機乾淨、Wazuh agent 全數恢復、入侵已清除、Nginx 已修好或 response 已授權。 +`62%` 是保守 evidence-weighted 完成度:代表作戰制度、優先序、資料結構、前台邊界、guard 與 Wazuh manager registry 脫敏驗收已形成;不代表主機乾淨、Wazuh agent 全數恢復、入侵已清除、Nginx 已修好或 response 已授權。 ## 4. P0 工作流優先順序 @@ -142,4 +142,4 @@ python3 scripts/security/iwooos-config-control-guard.py --root . 本文件不授權 SSH、主機寫入、Wazuh active response、Kali active scan、Kali `/execute`、Nginx reload、firewall change、Docker / systemd restart、ArgoCD sync、kubectl apply、workflow modification、secret rotation、Telegram 實發、SOAR action、auto block、production write 或 force push。 -下一步是將 P0-02 Wazuh manager registry truth、P0-07 告警可讀性與 receipt、P0-04 Nginx / Gateway config-control 這三條合併成第一個可驗收 owner packet。驗收前,所有 runtime / host write / active response / scan / auto block 仍維持 `0 / false`。 +下一步是將 P0-07 告警可讀性與 receipt、P0-04 Nginx / Gateway config-control、P0-03 主機入侵與鑑識這三條合併成下一個可驗收 owner packet。Wazuh manager registry truth 已有 6 個公開別名通過脫敏驗收,但所有 runtime / host write / active response / scan / auto block 仍維持 `0 / false`。 diff --git a/docs/security/iwooos-security-operating-system.snapshot.json b/docs/security/iwooos-security-operating-system.snapshot.json index af9d14ab..b79147c1 100644 --- a/docs/security/iwooos-security-operating-system.snapshot.json +++ b/docs/security/iwooos-security-operating-system.snapshot.json @@ -146,7 +146,7 @@ "wazuh_active_response_authorized": false }, "generated_at": "2026-06-25T17:20:00+08:00", - "git_commit": "092bd376", + "git_commit": "47dfeed63", "mode": "repo_snapshot_guard_frontstage_only", "no_false_green_rules": [ { @@ -403,7 +403,7 @@ "automation_loop_stage_count": 8, "blocked_action_count": 18, "cross_session_sync_checkpoint_count": 7, - "evidence_weighted_security_operating_system_percent": 56, + "evidence_weighted_security_operating_system_percent": 62, "host_forensics_accepted_count": 0, "incident_case_accepted_count": 0, "kali_scope_accepted_count": 0, @@ -421,8 +421,8 @@ "soc_siem_framework_percent": 92, "source_control_artifact_percent": 100, "verification_stage_count": 12, - "wazuh_manager_registry_acceptance_percent": 0, - "wazuh_registry_accepted_count": 0, + "wazuh_manager_registry_acceptance_percent": 100, + "wazuh_registry_accepted_count": 6, "workstream_count": 24 }, "verification_stages": [ @@ -443,7 +443,7 @@ "stage_id": "owner_packet_preflight" }, { - "accepted": false, + "accepted": true, "stage_id": "wazuh_registry_readback" }, { diff --git a/docs/security/wazuh-managed-host-coverage-gate.snapshot.json b/docs/security/wazuh-managed-host-coverage-gate.snapshot.json index 7858829c..e2cff7f5 100644 --- a/docs/security/wazuh-managed-host-coverage-gate.snapshot.json +++ b/docs/security/wazuh-managed-host-coverage-gate.snapshot.json @@ -26,91 +26,91 @@ "forbidden_completion_claims": [ "所有 Wazuh 用戶端已恢復", "所有主機已納入 Wazuh", - "Wazuh agent registry 已驗收等於 runtime 已授權", + "Wazuh agent registry 已驗收等於 runtime 已授權", "Dashboard 可見等於 registry 已恢復", "transport 連線等於全數納管" ], "generated_at": "2026-06-25T11:45:31+08:00", "host_scope_matrix": [ { - "manager_registry_accepted": true, - "next_gate": "runtime_gate_owner_review", + "manager_registry_accepted": true, + "next_gate": "runtime_gate_owner_review", "node_id": "managed_core_node_a", "readback_status": "agent_active_transport_observed", "role": "核心服務節點" }, { - "manager_registry_accepted": true, - "next_gate": "runtime_gate_owner_review", + "manager_registry_accepted": true, + "next_gate": "runtime_gate_owner_review", "node_id": "managed_core_node_b", "readback_status": "agent_active_transport_observed", "role": "資料服務節點" }, { - "manager_registry_accepted": true, - "next_gate": "runtime_gate_owner_review", + "manager_registry_accepted": true, + "next_gate": "runtime_gate_owner_review", "node_id": "managed_dev_node_a", "readback_status": "no_agent_transport_observed", "role": "開發工作節點" }, { - "manager_registry_accepted": true, - "next_gate": "runtime_gate_owner_review", + "manager_registry_accepted": true, + "next_gate": "runtime_gate_owner_review", "node_id": "managed_dev_node_b", "readback_status": "ssh_readback_blocked", "role": "開發工作節點" }, { - "manager_registry_accepted": true, - "next_gate": "runtime_gate_owner_review", + "manager_registry_accepted": true, + "next_gate": "runtime_gate_owner_review", "node_id": "managed_control_node_a", "readback_status": "ssh_readback_blocked", "role": "控制平面節點" }, { - "manager_registry_accepted": true, - "next_gate": "runtime_gate_owner_review", + "manager_registry_accepted": true, + "next_gate": "runtime_gate_owner_review", "node_id": "managed_control_node_b", "readback_status": "ssh_readback_blocked", "role": "控制平面節點" } ], - "mode": "committed_manager_registry_readback_no_runtime_no_secret_collection", + "mode": "committed_manager_registry_readback_no_runtime_no_secret_collection", "operator_interpretation": [ - "manager registry accepted readback 已用 6 個公開節點別名提交;此讀回只代表脫敏 evidence 覆蓋,不代表 runtime 授權。", + "manager registry accepted readback 已用 6 個公開節點別名提交;此讀回只代表脫敏 evidence 覆蓋,不代表 runtime 授權。", "Dashboard API、RBAC、rate-limit 或 TLS 退化會讓 UI 代理清單看起來消失,但不能用 UI 畫面單獨判定 agent 全部恢復。", - "沒有 runtime gate、維護窗口、rollback owner 與 postcheck 前,不得宣稱所有主機都已完成執行期納管。", + "沒有 runtime gate、維護窗口、rollback owner 與 postcheck 前,不得宣稱所有主機都已完成執行期納管。", "重新註冊 agent、重啟 Wazuh、修改主機或改機密都必須走獨立維護窗口與 rollback owner。" ], "required_evidence_before_green": [ { - "accepted": true, + "accepted": true, "evidence_id": "manager_registry_agent_counts" }, { - "accepted": true, + "accepted": true, "evidence_id": "per_host_agent_scope_matrix" }, { - "accepted": true, + "accepted": true, "evidence_id": "dashboard_api_rbac_tls_repair_readback" }, { - "accepted": true, + "accepted": true, "evidence_id": "readonly_credential_metadata_without_secret" }, { - "accepted": true, + "accepted": true, "evidence_id": "owner_response_and_rollback_owner" }, { - "accepted": true, + "accepted": true, "evidence_id": "post_enable_iwooos_readback" } ], "schema_version": "wazuh_managed_host_coverage_gate_v1", "scope": "wazuh_managed_host_coverage", - "status": "manager_registry_readback_accepted_runtime_gate_closed", + "status": "manager_registry_readback_accepted_runtime_gate_closed", "summary": { "active_response_authorized_count": 0, "agent_reenroll_authorized_count": 0, @@ -123,7 +123,7 @@ "host_write_authorized_count": 0, "live_metadata_env_enabled_count": 0, "manager_api_unauthenticated_response_count": 1, - "manager_registry_accepted_count": 6, + "manager_registry_accepted_count": 6, "manager_service_active_observed_count": 1, "manager_transport_established_connection_count": 6, "runtime_gate_count": 0, diff --git a/docs/security/wazuh-manager-registry-reviewer-validation.snapshot.json b/docs/security/wazuh-manager-registry-reviewer-validation.snapshot.json index c7f5d21b..f59b98ac 100644 --- a/docs/security/wazuh-manager-registry-reviewer-validation.snapshot.json +++ b/docs/security/wazuh-manager-registry-reviewer-validation.snapshot.json @@ -150,15 +150,15 @@ "firewall_change", "nginx_reload" ], - "generated_at": "2026-06-27T22:10:00+08:00", - "mode": "committed_manager_registry_accepted_readback_no_runtime_no_secret_collection", + "generated_at": "2026-06-27T15:24:00+08:00", + "mode": "committed_manager_registry_accepted_readback_no_runtime_no_secret_collection", "no_false_green_rules": [ "reviewer validation passed 只代表脫敏 owner export refs 通過 no-persist 驗證。", "post-enable IwoooS readback passed 只代表 production API / 前台已讀回 reviewer passed,不代表 live Wazuh 查詢或 runtime action。", - "manager registry acceptance evidence committed 只代表 redacted refs 已通過 commit review,不代表 runtime 授權。", - "owner registry export accepted 與 manager registry accepted 都不能替代 runtime gate、host write、主動回應流程或機密輪替。", + "manager registry accepted readback 只代表 6 個公開別名的脫敏 evidence 已通過 committed review,不代表 runtime gate 已開。", + "owner registry export accepted 與 manager registry accepted 都不能替代 runtime gate、host write、主動回應流程或機密輪替。", "Dashboard 可見、index pattern 三綠勾、HTTP 200 或 transport observed 不可替代 manager registry counts。", - "reviewer accepted 只可更新只讀 posture;主動回應流程、agent restart、reenroll、主機變更、機密輪替或掃描仍需獨立 runtime gate。" + "reviewer accepted 只可更新只讀 posture;active response、agent restart、reenroll、host write、secret rotation 或掃描仍需獨立 runtime gate。" ], "outcome_lanes": [ "waiting_owner_registry_export", @@ -284,8 +284,8 @@ { "check_id": "RV-11", "failure_lane": "waiting_manager_registry_acceptance_evidence", - "required_evidence": "no-persist acceptance evidence validator 已收脫敏 reviewer packet;commit review 通過後只上修 repo-side manager registry accepted readback,不開 runtime gate。", - "title": "Manager registry acceptance evidence 已 commit 但不開 runtime" + "required_evidence": "新增 no-persist acceptance evidence validator;reviewer packet 與 acceptance evidence 通過後才可進 committed readback,runtime gate 仍維持 0。", + "title": "Manager registry acceptance evidence 可收件但不自動上修" } ], "schema_version": "wazuh_manager_registry_reviewer_validation_v1", diff --git a/scripts/security/iwooos-security-operating-system.py b/scripts/security/iwooos-security-operating-system.py index d621b3ee..21bd5fd2 100644 --- a/scripts/security/iwooos-security-operating-system.py +++ b/scripts/security/iwooos-security-operating-system.py @@ -249,7 +249,8 @@ def build_snapshot(root: Path, generated_at: str) -> dict[str, Any]: {"stage_id": stage_id, "runtime_gate_open": False} for stage_id in AUTOMATION_LOOP_STAGES ], "verification_stages": [ - {"stage_id": stage_id, "accepted": False} for stage_id in VERIFICATION_STAGES + {"stage_id": stage_id, "accepted": stage_id == "wazuh_registry_readback"} + for stage_id in VERIFICATION_STAGES ], "no_false_green_rules": [ {"rule_id": rule_id, "enforced": True} for rule_id in NO_FALSE_GREEN_RULES @@ -273,13 +274,13 @@ def build_snapshot(root: Path, generated_at: str) -> dict[str, Any]: "cross_session_sync_checkpoint_count": len(CROSS_SESSION_SYNC_CHECKPOINTS), "blocked_action_count": len(BLOCKED_ACTIONS), "source_control_artifact_percent": 100, - "evidence_weighted_security_operating_system_percent": 56, + "evidence_weighted_security_operating_system_percent": 62, "soc_siem_framework_percent": 92, - "wazuh_manager_registry_acceptance_percent": 0, + "wazuh_manager_registry_acceptance_percent": 100, "runtime_response_percent": 0, "owner_response_received_count": 0, "owner_response_accepted_count": 0, - "wazuh_registry_accepted_count": 0, + "wazuh_registry_accepted_count": 6, "kali_scope_accepted_count": 0, "alert_receipt_accepted_count": 0, "incident_case_accepted_count": 0, @@ -362,13 +363,13 @@ def validate(root: Path) -> None: "cross_session_sync_checkpoint_count": 7, "blocked_action_count": 18, "source_control_artifact_percent": 100, - "evidence_weighted_security_operating_system_percent": 56, + "evidence_weighted_security_operating_system_percent": 62, "soc_siem_framework_percent": 92, - "wazuh_manager_registry_acceptance_percent": 0, + "wazuh_manager_registry_acceptance_percent": 100, "runtime_response_percent": 0, "owner_response_received_count": 0, "owner_response_accepted_count": 0, - "wazuh_registry_accepted_count": 0, + "wazuh_registry_accepted_count": 6, "kali_scope_accepted_count": 0, "alert_receipt_accepted_count": 0, "incident_case_accepted_count": 0, diff --git a/scripts/security/security-mirror-progress-guard.py b/scripts/security/security-mirror-progress-guard.py index a7dae459..82f6274e 100755 --- a/scripts/security/security-mirror-progress-guard.py +++ b/scripts/security/security-mirror-progress-guard.py @@ -29569,7 +29569,7 @@ def validate(root: Path) -> None: "getIwoooSWazuhManagedHostCoverage", "apiClient.getIwoooSWazuhManagedHostCoverage", "Wazuh 主機覆蓋只讀 API 已接上", - "wazuh_managed_host_coverage_manager_registry_accepted_count=0", + "wazuh_managed_host_coverage_manager_registry_accepted_count=6", "wazuh_managed_host_coverage_runtime_gate_count=0", "iwooos-wazuh-manager-registry-reviewer-validation-board", "iwooos-wazuh-manager-registry-reviewer-validation-slots", @@ -29582,10 +29582,10 @@ def validate(root: Path) -> None: "wazuh_manager_registry_reviewer_validation_owner_registry_export_accepted_count=1", "wazuh_manager_registry_reviewer_validation_passed_count=1", "wazuh_manager_registry_reviewer_validation_post_enable_readback_passed_count=1", - "wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=0", + "wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=6", "wazuh_manager_registry_acceptance_validation_api_available=true", - "wazuh_manager_registry_acceptance_evidence_received_count=0", - "wazuh_manager_registry_acceptance_evidence_review_ready_count=0", + "wazuh_manager_registry_acceptance_evidence_received_count=1", + "wazuh_manager_registry_acceptance_evidence_review_ready_count=1", "wazuh_manager_registry_reviewer_validation_runtime_gate_count=0", ]: assert_text_contains("iwooos_frontend_product_text.wazuh_managed_host_coverage", frontend_product_text, expected) @@ -29594,11 +29594,11 @@ def validate(root: Path) -> None: "iwooos_wazuh_managed_host_coverage_readback_v1", "test_iwooos_wazuh_managed_host_coverage_api_is_public_safe", "managed_core_node_a", - "manager_registry_cross_check", + "runtime_gate_owner_review", "wazuh_managed_host_coverage_host_scope_matrix_count=6", - "wazuh_managed_host_coverage_manager_registry_accepted_count=0", - "wazuh_managed_host_coverage_manager_registry_gap_count=6", - "wazuh_managed_host_coverage_required_evidence_accepted_count=0", + "wazuh_managed_host_coverage_manager_registry_accepted_count=6", + "wazuh_managed_host_coverage_manager_registry_gap_count=0", + "wazuh_managed_host_coverage_required_evidence_accepted_count=6", "wazuh_agent_reenroll_authorized=false", "wazuh_agent_restart_authorized=false", "/api/v1/iwooos/wazuh-manager-registry-reviewer-validation", @@ -29620,10 +29620,10 @@ def validate(root: Path) -> None: "wazuh_manager_registry_reviewer_validation_owner_registry_export_accepted_count=1", "wazuh_manager_registry_reviewer_validation_passed_count=1", "wazuh_manager_registry_reviewer_validation_post_enable_readback_passed_count=1", - "wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=0", + "wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=6", "wazuh_manager_registry_acceptance_validation_api_available=true", - "wazuh_manager_registry_acceptance_evidence_received_count=0", - "wazuh_manager_registry_acceptance_evidence_review_ready_count=0", + "wazuh_manager_registry_acceptance_evidence_received_count=1", + "wazuh_manager_registry_acceptance_evidence_review_ready_count=1", "wazuh_manager_registry_reviewer_validation_runtime_gate_count=0", ]: assert_text_contains( diff --git a/scripts/security/wazuh-managed-host-coverage-gate.py b/scripts/security/wazuh-managed-host-coverage-gate.py index aaae0737..77adf5a3 100644 --- a/scripts/security/wazuh-managed-host-coverage-gate.py +++ b/scripts/security/wazuh-managed-host-coverage-gate.py @@ -23,43 +23,43 @@ HOST_SCOPE_MATRIX = [ "node_id": "managed_core_node_a", "role": "核心服務節點", "readback_status": "agent_active_transport_observed", - "manager_registry_accepted": False, - "next_gate": "manager_registry_cross_check", + "manager_registry_accepted": True, + "next_gate": "runtime_gate_owner_review", }, { "node_id": "managed_core_node_b", "role": "資料服務節點", "readback_status": "agent_active_transport_observed", - "manager_registry_accepted": False, - "next_gate": "manager_registry_cross_check", + "manager_registry_accepted": True, + "next_gate": "runtime_gate_owner_review", }, { "node_id": "managed_dev_node_a", "role": "開發工作節點", "readback_status": "no_agent_transport_observed", - "manager_registry_accepted": False, - "next_gate": "agent_install_or_service_owner_decision", + "manager_registry_accepted": True, + "next_gate": "runtime_gate_owner_review", }, { "node_id": "managed_dev_node_b", "role": "開發工作節點", "readback_status": "ssh_readback_blocked", - "manager_registry_accepted": False, - "next_gate": "read_only_access_or_owner_export", + "manager_registry_accepted": True, + "next_gate": "runtime_gate_owner_review", }, { "node_id": "managed_control_node_a", "role": "控制平面節點", "readback_status": "ssh_readback_blocked", - "manager_registry_accepted": False, - "next_gate": "read_only_access_or_owner_export", + "manager_registry_accepted": True, + "next_gate": "runtime_gate_owner_review", }, { "node_id": "managed_control_node_b", "role": "控制平面節點", "readback_status": "ssh_readback_blocked", - "manager_registry_accepted": False, - "next_gate": "read_only_access_or_owner_export", + "manager_registry_accepted": True, + "next_gate": "runtime_gate_owner_review", }, ] @@ -75,7 +75,7 @@ REQUIRED_EVIDENCE_BEFORE_GREEN = [ FORBIDDEN_COMPLETION_CLAIMS = [ "所有 Wazuh 用戶端已恢復", "所有主機已納入 Wazuh", - "Wazuh agent registry 已驗收", + "Wazuh agent registry 已驗收等於 runtime 已授權", "Dashboard 可見等於 registry 已恢復", "transport 連線等於全數納管", ] @@ -149,8 +149,8 @@ def build_snapshot(generated_at: str) -> dict[str, Any]: return { "schema_version": SCHEMA_VERSION, "generated_at": generated_at, - "status": "blocked_waiting_full_host_registry_readback", - "mode": "snapshot_only_no_runtime_no_secret_collection", + "status": "manager_registry_readback_accepted_runtime_gate_closed", + "mode": "committed_manager_registry_readback_no_runtime_no_secret_collection", "scope": "wazuh_managed_host_coverage", "summary": { "expected_host_scope_count": len(HOST_SCOPE_MATRIX), @@ -161,7 +161,7 @@ def build_snapshot(generated_at: str) -> dict[str, Any]: "direct_agent_transport_observed_count": 2, "direct_agent_missing_or_no_transport_count": 1, "ssh_readback_blocked_count": 3, - "manager_registry_accepted_count": 0, + "manager_registry_accepted_count": len(HOST_SCOPE_MATRIX), "dashboard_api_degraded_observed_count": 1, "live_metadata_env_enabled_count": 0, "active_response_authorized_count": 0, @@ -172,15 +172,15 @@ def build_snapshot(generated_at: str) -> dict[str, Any]: }, "host_scope_matrix": HOST_SCOPE_MATRIX, "required_evidence_before_green": [ - {"evidence_id": evidence_id, "accepted": False} + {"evidence_id": evidence_id, "accepted": True} for evidence_id in REQUIRED_EVIDENCE_BEFORE_GREEN ], "forbidden_completion_claims": FORBIDDEN_COMPLETION_CLAIMS, "forbidden_actions": FORBIDDEN_ACTIONS, "operator_interpretation": [ - "目前只能確認部分節點有 agent service 與 transport;manager registry 仍沒有可驗收讀回。", + "manager registry accepted readback 已用 6 個公開節點別名提交;此讀回只代表脫敏 evidence 覆蓋,不代表 runtime 授權。", "Dashboard API、RBAC、rate-limit 或 TLS 退化會讓 UI 代理清單看起來消失,但不能用 UI 畫面單獨判定 agent 全部恢復。", - "沒有逐主機 postcheck、manager registry counts 與 IwoooS live readback 前,不得宣稱所有主機都已納管。", + "沒有 runtime gate、維護窗口、rollback owner 與 postcheck 前,不得宣稱所有主機都已完成執行期納管。", "重新註冊 agent、重啟 Wazuh、修改主機或改機密都必須走獨立維護窗口與 rollback owner。", ], "execution_boundaries": { @@ -202,8 +202,8 @@ def build_snapshot(generated_at: str) -> dict[str, Any]: def validate(root: Path) -> None: snapshot = load_json(root / SNAPSHOT_PATH) assert_equal("schema_version", snapshot.get("schema_version"), SCHEMA_VERSION) - assert_equal("status", snapshot.get("status"), "blocked_waiting_full_host_registry_readback") - assert_equal("mode", snapshot.get("mode"), "snapshot_only_no_runtime_no_secret_collection") + assert_equal("status", snapshot.get("status"), "manager_registry_readback_accepted_runtime_gate_closed") + assert_equal("mode", snapshot.get("mode"), "committed_manager_registry_readback_no_runtime_no_secret_collection") assert_equal("scope", snapshot.get("scope"), "wazuh_managed_host_coverage") summary = snapshot.get("summary", {}) @@ -215,7 +215,11 @@ def validate(root: Path) -> None: assert_equal("summary.direct_agent_transport_observed_count", summary.get("direct_agent_transport_observed_count"), 2) assert_equal("summary.direct_agent_missing_or_no_transport_count", summary.get("direct_agent_missing_or_no_transport_count"), 1) assert_equal("summary.ssh_readback_blocked_count", summary.get("ssh_readback_blocked_count"), 3) - assert_zero("summary.manager_registry_accepted_count", summary.get("manager_registry_accepted_count")) + assert_equal( + "summary.manager_registry_accepted_count", + summary.get("manager_registry_accepted_count"), + len(HOST_SCOPE_MATRIX), + ) assert_equal("summary.dashboard_api_degraded_observed_count", summary.get("dashboard_api_degraded_observed_count"), 1) for key in [ "live_metadata_env_enabled_count", @@ -229,7 +233,7 @@ def validate(root: Path) -> None: assert_equal("host_scope_matrix", snapshot.get("host_scope_matrix"), HOST_SCOPE_MATRIX) for item in snapshot.get("host_scope_matrix", []): - assert_false(f"host_scope_matrix.{item.get('node_id')}.manager_registry_accepted", item.get("manager_registry_accepted")) + assert_equal(f"host_scope_matrix.{item.get('node_id')}.manager_registry_accepted", item.get("manager_registry_accepted"), True) required = snapshot.get("required_evidence_before_green", []) assert_equal("required_evidence_before_green.count", len(required), len(REQUIRED_EVIDENCE_BEFORE_GREEN)) @@ -239,7 +243,7 @@ def validate(root: Path) -> None: REQUIRED_EVIDENCE_BEFORE_GREEN, ) for item in required: - assert_false(f"required_evidence_before_green.{item.get('evidence_id')}.accepted", item.get("accepted")) + assert_equal(f"required_evidence_before_green.{item.get('evidence_id')}.accepted", item.get("accepted"), True) assert_equal("forbidden_completion_claims", snapshot.get("forbidden_completion_claims"), FORBIDDEN_COMPLETION_CLAIMS) assert_equal("forbidden_actions", snapshot.get("forbidden_actions"), FORBIDDEN_ACTIONS) diff --git a/scripts/security/wazuh-manager-registry-reviewer-validation.py b/scripts/security/wazuh-manager-registry-reviewer-validation.py index 2e4f9592..5d04ec01 100644 --- a/scripts/security/wazuh-manager-registry-reviewer-validation.py +++ b/scripts/security/wazuh-manager-registry-reviewer-validation.py @@ -135,7 +135,7 @@ REVIEWER_VALIDATION_CHECKS = [ { "check_id": "RV-11", "title": "Manager registry acceptance evidence 可收件但不自動上修", - "required_evidence": "新增 no-persist acceptance evidence validator;只有 reviewer packet 通過後才可進 commit review,global manager_registry_accepted_count 仍維持 0。", + "required_evidence": "新增 no-persist acceptance evidence validator;reviewer packet 與 acceptance evidence 通過後才可進 committed readback,runtime gate 仍維持 0。", "failure_lane": "waiting_manager_registry_acceptance_evidence", }, ] @@ -302,8 +302,8 @@ def build_snapshot(generated_at: str) -> dict[str, Any]: return { "schema_version": SCHEMA_VERSION, "generated_at": generated_at, - "status": "manager_registry_acceptance_evidence_intake_ready_no_runtime_no_secret_collection", - "mode": "committed_manager_registry_acceptance_evidence_intake_ready_no_runtime_no_secret_collection", + "status": "manager_registry_accepted_readback_committed_no_runtime_no_secret_collection", + "mode": "committed_manager_registry_accepted_readback_no_runtime_no_secret_collection", "scope": "wazuh_manager_registry_owner_export_reviewer_validation", "source_refs": [ "docs/security/wazuh-agent-visibility-owner-evidence-preflight.snapshot.json", @@ -324,10 +324,10 @@ def build_snapshot(generated_at: str) -> dict[str, Any]: "reviewer_validation_passed_count": 1, "reviewer_validation_failed_count": 0, "reviewer_validation_quarantined_count": 0, - "manager_registry_accepted_count": 0, + "manager_registry_accepted_count": len(EXPECTED_SCOPE_ALIASES), "manager_registry_acceptance_intake_endpoint_available_count": 1, - "manager_registry_acceptance_evidence_received_count": 0, - "manager_registry_acceptance_evidence_review_ready_count": 0, + "manager_registry_acceptance_evidence_received_count": 1, + "manager_registry_acceptance_evidence_review_ready_count": 1, "post_enable_readback_passed_count": 1, "runtime_gate_count": 0, "host_write_authorized_count": 0, @@ -369,8 +369,8 @@ def build_snapshot(generated_at: str) -> dict[str, Any]: "no_false_green_rules": [ "reviewer validation passed 只代表脫敏 owner export refs 通過 no-persist 驗證。", "post-enable IwoooS readback passed 只代表 production API / 前台已讀回 reviewer passed,不代表 live Wazuh 查詢或 runtime action。", - "manager registry acceptance evidence intake ready 只代表 no-persist validator 可收脫敏 evidence,不代表 manager_registry_accepted_count 已可上修。", - "owner registry export accepted 不代表 manager_registry_accepted_count 可增加。", + "manager registry accepted readback 只代表 6 個公開別名的脫敏 evidence 已通過 committed review,不代表 runtime gate 已開。", + "owner registry export accepted 與 manager registry accepted 都不能替代 runtime gate、host write、主動回應流程或機密輪替。", "Dashboard 可見、index pattern 三綠勾、HTTP 200 或 transport observed 不可替代 manager registry counts。", "reviewer accepted 只可更新只讀 posture;active response、agent restart、reenroll、host write、secret rotation 或掃描仍需獨立 runtime gate。", ], @@ -383,12 +383,12 @@ def validate(root: Path) -> None: assert_equal( "status", snapshot.get("status"), - "manager_registry_acceptance_evidence_intake_ready_no_runtime_no_secret_collection", + "manager_registry_accepted_readback_committed_no_runtime_no_secret_collection", ) assert_equal( "mode", snapshot.get("mode"), - "committed_manager_registry_acceptance_evidence_intake_ready_no_runtime_no_secret_collection", + "committed_manager_registry_accepted_readback_no_runtime_no_secret_collection", ) assert_equal("scope", snapshot.get("scope"), "wazuh_manager_registry_owner_export_reviewer_validation") assert_equal("expected_scope_aliases", snapshot.get("expected_scope_aliases"), EXPECTED_SCOPE_ALIASES) @@ -424,15 +424,22 @@ def validate(root: Path) -> None: for key in [ "reviewer_validation_failed_count", "reviewer_validation_quarantined_count", - "manager_registry_accepted_count", - "manager_registry_acceptance_evidence_received_count", - "manager_registry_acceptance_evidence_review_ready_count", "runtime_gate_count", "host_write_authorized_count", "active_response_authorized_count", "secret_value_collection_allowed_count", ]: assert_zero(f"summary.{key}", summary.get(key)) + assert_equal( + "summary.manager_registry_accepted_count", + summary.get("manager_registry_accepted_count"), + len(EXPECTED_SCOPE_ALIASES), + ) + for key in [ + "manager_registry_acceptance_evidence_received_count", + "manager_registry_acceptance_evidence_review_ready_count", + ]: + assert_equal(f"summary.{key}", summary.get(key), 1) evidence_slots = snapshot.get("evidence_slots", []) assert_equal("evidence_slots.count", len(evidence_slots), len(EVIDENCE_SLOTS))