feat(iwooos): expose Wazuh live metadata gate readback
All checks were successful
Code Review / ai-code-review (push) Successful in 16s
CD Pipeline / tests (push) Successful in 1m45s
CD Pipeline / build-and-deploy (push) Successful in 5m8s
CD Pipeline / post-deploy-checks (push) Successful in 1m35s

This commit is contained in:
Your Name
2026-06-27 00:11:54 +08:00
parent bfecd87c04
commit 10a925bab6
9 changed files with 715 additions and 35 deletions

View File

@@ -20,6 +20,7 @@ _SNAPSHOT_FILES = {
"owner_gap": "s4-9-owner-response-gap-audit.snapshot.json",
"wazuh_coverage": "wazuh-managed-host-coverage-gate.snapshot.json",
"wazuh_runtime": "wazuh-agent-visibility-runtime-gate.snapshot.json",
"wazuh_live_metadata_gate": "wazuh-readonly-live-metadata-env-gate.snapshot.json",
"kali_status": "kali-integration-status.snapshot.json",
"soc_control": "soc-siem-kali-wazuh-integration-control.snapshot.json",
"alert_readability": "telegram-alert-readability-guard.snapshot.json",
@@ -31,6 +32,7 @@ _EXPECTED_SCHEMAS = {
"owner_gap": "s4_9_owner_response_gap_audit_v1",
"wazuh_coverage": "wazuh_managed_host_coverage_gate_v1",
"wazuh_runtime": "wazuh_agent_visibility_runtime_gate_v1",
"wazuh_live_metadata_gate": "iwooos_wazuh_readonly_live_metadata_env_gate_v1",
"kali_status": "kali_integration_status_v1",
"soc_control": "soc_siem_kali_wazuh_integration_control_v1",
"alert_readability": "telegram_alert_readability_guard_v1",
@@ -70,6 +72,7 @@ def load_latest_iwooos_runtime_security_readback(
owner_gap_summary = _summary(snapshots["owner_gap"])
wazuh_summary = _summary(snapshots["wazuh_coverage"])
live_metadata_gate_summary = _summary(snapshots["wazuh_live_metadata_gate"])
soc_summary = _summary(snapshots["soc_control"])
alert_summary = _summary(snapshots["alert_readability"])
dispatch_summary = _summary(snapshots["owner_dispatch"])
@@ -92,7 +95,7 @@ def load_latest_iwooos_runtime_security_readback(
"source_refs": source_refs,
"summary": {
"source_snapshot_count": len(source_refs),
"p0_lane_count": 7,
"p0_lane_count": 8,
"control_plane_visibility_percent": _average_percent(
soc_summary.get("coverage_percent_after_soc_integration_control"),
intrusion_summary.get("coverage_percent_after_prevention_control"),
@@ -118,6 +121,24 @@ def load_latest_iwooos_runtime_security_readback(
"wazuh_live_below_expected_count": live_wazuh["agent_below_expected_minimum_count"],
"wazuh_live_metadata_available_count": live_wazuh["metadata_available_count"],
"wazuh_live_status": live_wazuh["status"],
"wazuh_live_metadata_gate_owner_accepted_count": _int(
live_metadata_gate_summary.get("live_metadata_owner_response_accepted_count")
),
"wazuh_live_metadata_gate_secret_source_accepted_count": _int(
live_metadata_gate_summary.get("secret_source_metadata_accepted_count")
),
"wazuh_live_metadata_gate_manager_health_accepted_count": _int(
live_metadata_gate_summary.get("wazuh_manager_health_ref_accepted_count")
),
"wazuh_live_metadata_gate_readonly_scope_accepted_count": _int(
live_metadata_gate_summary.get("readonly_account_scope_accepted_count")
),
"wazuh_live_metadata_gate_post_enable_readback_count": _int(
live_metadata_gate_summary.get("post_enable_readback_passed_count")
),
"wazuh_live_metadata_gate_live_query_authorized_count": _int(
live_metadata_gate_summary.get("wazuh_api_live_query_authorized_count")
),
"kali_active_scan_authorized_count": _int(soc_summary.get("kali_active_scan_authorized_count")),
"kali_execute_authorized_count": _int(soc_summary.get("kali_execute_authorized_count")),
"kali_finding_envelope_accepted_count": _int(soc_summary.get("kali_finding_envelope_accepted_count")),
@@ -132,7 +153,7 @@ def load_latest_iwooos_runtime_security_readback(
"blocked_waiting_manager_registry",
0,
"locked",
"manager_registry_cross_check",
"管理器清單交叉驗收",
{
"expected_hosts": wazuh_summary.get("expected_host_scope_count", 0),
"transport_observed": wazuh_summary.get("manager_transport_established_connection_count", 0),
@@ -145,7 +166,7 @@ def load_latest_iwooos_runtime_security_readback(
live_wazuh["status"],
0 if live_wazuh["degraded_count"] else 30,
"steady" if live_wazuh["metadata_available_count"] else "warn",
"enable_readonly_metadata_owner_gate_and_manager_registry_cross_check",
"先通過唯讀中繼資料負責人閘門與管理器清單交叉驗收",
{
"http_status": live_wazuh["http_status"],
"readonly_enabled": live_wazuh["readonly_api_enabled_count"],
@@ -155,12 +176,42 @@ def load_latest_iwooos_runtime_security_readback(
},
["GET /api/iwooos/wazuh"],
),
_lane(
"wazuh_live_metadata_gate",
snapshots["wazuh_live_metadata_gate"].get("status", "blocked_waiting_live_metadata_owner_response"),
0,
"locked",
"補齊負責人回覆、機密中繼資料、管理節點健康、唯讀範圍與啟用後讀回",
{
"route_readback": live_metadata_gate_summary.get("production_route_readback_passed_count", 0),
"owner_accepted": live_metadata_gate_summary.get("live_metadata_owner_response_accepted_count", 0),
"secret_metadata_accepted": live_metadata_gate_summary.get(
"secret_source_metadata_accepted_count",
0,
),
"manager_health_accepted": live_metadata_gate_summary.get(
"wazuh_manager_health_ref_accepted_count",
0,
),
"readonly_scope_accepted": live_metadata_gate_summary.get(
"readonly_account_scope_accepted_count",
0,
),
"post_enable_readback": live_metadata_gate_summary.get("post_enable_readback_passed_count", 0),
"live_query_authorized": live_metadata_gate_summary.get(
"wazuh_api_live_query_authorized_count",
0,
),
"runtime_gate": live_metadata_gate_summary.get("runtime_gate_count", 0),
},
["docs/security/wazuh-readonly-live-metadata-env-gate.snapshot.json"],
),
_lane(
"wazuh_dashboard_api",
"degraded_api_connection_not_green",
0,
"warn",
"dashboard_api_rbac_tls_repair_readback",
"儀表板 API、RBAC 與 TLS 修復後重新讀回",
{
"dashboard_api_degraded": wazuh_summary.get("dashboard_api_degraded_observed_count", 0),
"runtime_gate": wazuh_summary.get("runtime_gate_count", 0),
@@ -176,7 +227,7 @@ def load_latest_iwooos_runtime_security_readback(
snapshots["kali_status"].get("status", "blocked_waiting_kali_scope"),
0,
"locked",
"kali_scope_and_finding_envelope_accepted",
"資安觀測範圍與 finding envelope 先被接受",
{
"active_scan_authorized": soc_summary.get("kali_active_scan_authorized_count", 0),
"execute_authorized": soc_summary.get("kali_execute_authorized_count", 0),
@@ -192,7 +243,7 @@ def load_latest_iwooos_runtime_security_readback(
"contract_ready_no_send_receipt",
_alert_contract_percent(alert_summary),
"warn",
"alert_route_receipt_available",
"補齊告警路由 receipt 與實發驗證",
{
"formatter_markers": alert_summary.get("source_formatter_marker_count", 0),
"required_markers": alert_summary.get("required_output_marker_count", 0),
@@ -205,7 +256,7 @@ def load_latest_iwooos_runtime_security_readback(
snapshots["owner_dispatch"].get("status", "owner_request_draft_ready_not_dispatched"),
0,
"locked",
"owner_response_packet_delivery",
"正式負責人回覆封包送達與接受",
{
"request_drafts": dispatch_summary.get("request_draft_count", 0),
"request_sent": dispatch_summary.get("request_sent_count", 0),
@@ -218,7 +269,7 @@ def load_latest_iwooos_runtime_security_readback(
"candidate_only_no_runtime_containment",
_int(intrusion_summary.get("coverage_percent_after_prevention_control")),
"warn",
"redacted_evidence_refs_and_maintenance_window",
"補脫敏證據參照與維護窗口",
{
"urgent_candidates": intrusion_summary.get("urgent_prevention_candidate_count", 0),
"evidence_received": intrusion_summary.get("evidence_ref_received_count", 0),
@@ -244,13 +295,14 @@ def load_latest_iwooos_runtime_security_readback(
"not_authorization": True,
},
"no_false_green_rules": [
"dashboard_route_200_is_not_wazuh_registry_recovery",
"transport_count_is_not_full_host_management",
"ui_visible_is_not_runtime_authorization",
"owner_request_draft_is_not_owner_acceptance",
"kali_health_is_not_active_scan_authorization",
"alert_format_contract_is_not_telegram_send_receipt",
"wazuh_live_route_disabled_or_degraded_is_p0_not_green",
"儀表板路由 200 不代表 Wazuh 清單已恢復",
"傳輸連線數不代表所有主機都已納管",
"前台可見不代表執行期已授權",
"負責人送件草案不代表負責人已接受",
"資安觀測節點健康不代表主動掃描已授權",
"告警格式合約不代表通知已實發或已取得 receipt",
"Wazuh 正式只讀路由 disabled 或退化時仍是 P0 紅燈",
"Wazuh 即時中繼資料必須先通過負責人、機密中繼資料、唯讀範圍與啟用後讀回",
],
}
@@ -367,6 +419,9 @@ def _require_runtime_boundaries(snapshots: dict[str, dict[str, Any]]) -> None:
"telegram_send_authorized_count",
"host_write_authorized_count",
"secret_value_collection_allowed_count",
"wazuh_api_live_query_authorized_count",
"wazuh_active_response_authorized_count",
"post_enable_readback_passed_count",
):
if key in summary and _int(summary.get(key)) != 0:
raise ValueError(f"{name}: {key} must remain 0")