feat(iwooos): expose wazuh manager registry reviewer validation
Some checks failed
Code Review / ai-code-review (push) Successful in 16s
CD Pipeline / tests (push) Successful in 1m37s
CD Pipeline / build-and-deploy (push) Successful in 4m43s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
Some checks failed
Code Review / ai-code-review (push) Successful in 16s
CD Pipeline / tests (push) Successful in 1m37s
CD Pipeline / build-and-deploy (push) Successful in 4m43s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
This commit is contained in:
@@ -1,3 +1,43 @@
|
||||
## 2026-06-27|IwoooS Wazuh manager registry reviewer validation 本地完成
|
||||
|
||||
**背景**:Wazuh 受管主機覆蓋已能由正式 API / 前台讀回,但 `manager_registry_accepted_count` 仍為 `0`。本段補上 owner-provided redacted manager registry export 進來後的 reviewer validation contract,避免把 Dashboard 可開、index pattern 正常、HTTP 200、agent transport observed 或前台卡片可見誤判為全主機已納管。
|
||||
|
||||
**完成內容**:
|
||||
- 新增 committed snapshot:`docs/security/wazuh-manager-registry-reviewer-validation.snapshot.json`。
|
||||
- 新增只讀 guard:`scripts/security/wazuh-manager-registry-reviewer-validation.py`,驗證 6 個公開別名、28 個 owner 欄位、9 個逐主機欄位、10 個 reviewer checks、13 條 outcome lanes、6 個 evidence slots 與 27 類 forbidden payload。
|
||||
- 新增 API:`GET /api/v1/iwooos/wazuh-manager-registry-reviewer-validation`,schema 為 `iwooos_wazuh_manager_registry_reviewer_validation_readback_v1`。
|
||||
- `/zh-TW/iwooos` 新增 reviewer validation 卡,讀取 API 後顯示 evidence slots、reviewer checks 與 no-false-green boundary markers;API 未回時只顯示保守 fallback。
|
||||
- `security-mirror-progress-guard.py` 已納入 API route、service schema、client method、前台測試 id、i18n 文案與 `owner_registry_export_received_count=0`、`owner_registry_export_accepted_count=0`、`manager_registry_accepted_count=0`、`runtime_gate_count=0` source markers。
|
||||
- `zh-TW` 與目前鏡像訊息皆為繁體中文;未放入工作視窗對話、個人 namespace、內網位址、agent 原名或 secret。
|
||||
|
||||
**本地驗證結果**:
|
||||
- `python3 -m py_compile scripts/security/wazuh-manager-registry-reviewer-validation.py apps/api/src/services/iwooos_wazuh_manager_registry_reviewer_validation.py apps/api/src/api/v1/iwooos.py scripts/security/security-mirror-progress-guard.py`:通過。
|
||||
- `DATABASE_URL=sqlite:///test.db python3.11 -m pytest apps/api/tests/test_iwooos_wazuh_manager_registry_reviewer_validation.py apps/api/tests/test_iwooos_wazuh_managed_host_coverage.py apps/api/tests/test_iwooos_runtime_security_readback.py apps/api/tests/test_iwooos_wazuh_api.py -q`:`18 passed`。
|
||||
- `node -e "JSON.parse(...zh-TW.json); JSON.parse(...en.json)"`:通過。
|
||||
- `python3 scripts/security/wazuh-manager-registry-reviewer-validation.py --root .`:`WAZUH_MANAGER_REGISTRY_REVIEWER_VALIDATION_OK aliases=6 checks=10 slots=6 received=0 accepted=0 runtime_gate=0`。
|
||||
- `python3 scripts/security/iwooos-frontend-display-redaction-guard.py --root .`:`IWOOOS_FRONTEND_DISPLAY_REDACTION_GUARD_OK`。
|
||||
- `python3 scripts/security/security-mirror-progress-guard.py --root .`:`SECURITY_MIRROR_PROGRESS_GUARD_OK`。
|
||||
- `pnpm --dir apps/web typecheck`:通過。
|
||||
- `git diff --check`:通過。
|
||||
|
||||
**完成度 / 邊界**:
|
||||
- 本段「Wazuh manager registry reviewer validation contract」本地:`0% -> 85%`。尚待 rebase、commit、push、CD、production API readback 與 desktop / mobile browser smoke。
|
||||
- IwoooS 整體暫保守維持 `68%`,等正式讀回完成後再上修。
|
||||
- Wazuh manager registry accepted:`35% -> 55%`,目前只是 reviewer validation contract 與前台讀回準備完成,不代表 owner export received / accepted 或所有主機已納管。
|
||||
|
||||
**仍維持 0 / false**:
|
||||
- `owner_registry_export_received_count=0`、`owner_registry_export_accepted_count=0`、`reviewer_validation_passed_count=0`、`reviewer_validation_quarantined_count=0`、`manager_registry_accepted_count=0`、`post_enable_readback_passed_count=0`、`runtime_gate_count=0`。
|
||||
- `wazuh_api_live_query_authorized=false`、`wazuh_agent_reenroll_authorized=false`、`wazuh_agent_restart_authorized=false`、`wazuh_manager_restart_authorized=false`、`wazuh_active_response_authorized=false`、`host_write_authorized=false`、`secret_value_collection_allowed=false`、`raw_wazuh_payload_storage_allowed=false`、`kali_active_scan_authorized=false`、`runtime_execution_authorized=false`、`not_authorization=true`。
|
||||
|
||||
**做過的命令類型**:
|
||||
- 寫入:repo API / test / frontend / i18n / guard / snapshot / LOGBOOK。
|
||||
- 只讀:git fetch / diff、repo snapshot 驗證、本地測試與型別檢查。
|
||||
- 未做:沒有 host / Docker / systemd / Nginx / firewall / K8s / DB / Wazuh runtime 寫操作;沒有讀 secret 明文;沒有重新註冊 agent;沒有 Wazuh restart;沒有 Wazuh active response;沒有 Kali active scan;沒有 force push。
|
||||
|
||||
**下一步**:
|
||||
- rebase 到最新 `gitea/main` 後 commit / push,等待 Gitea CD。
|
||||
- production 驗證 `GET /api/v1/iwooos/wazuh-manager-registry-reviewer-validation`、`/zh-TW/iwooos` desktop / mobile、forbidden hits、console errors 與水平溢出。
|
||||
|
||||
## 2026-06-27|D1M 正式站驗證:修復候選已寫入 check-mode worker 可 claim receipt
|
||||
|
||||
**正式部署基準 / Runs**:
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
{
|
||||
"evidence_slots": [
|
||||
{
|
||||
"accepted": false,
|
||||
"next_gate": "owner_provided_redacted_export",
|
||||
"quarantined": false,
|
||||
"received": false,
|
||||
"required_fields": [
|
||||
"agent_total",
|
||||
"agent_active",
|
||||
"agent_disconnected",
|
||||
"agent_never_connected",
|
||||
"registry_export_summary_ref"
|
||||
],
|
||||
"slot_id": "manager_registry_agent_counts",
|
||||
"title": "Manager registry agent counts"
|
||||
},
|
||||
{
|
||||
"accepted": false,
|
||||
"next_gate": "owner_provided_redacted_export",
|
||||
"quarantined": false,
|
||||
"received": false,
|
||||
"required_fields": [
|
||||
"registry_export_scope_aliases",
|
||||
"per_host_registry_matrix",
|
||||
"registry_gap_reason_by_alias"
|
||||
],
|
||||
"slot_id": "per_host_agent_scope_matrix",
|
||||
"title": "逐主機 agent scope matrix"
|
||||
},
|
||||
{
|
||||
"accepted": false,
|
||||
"next_gate": "owner_provided_redacted_export",
|
||||
"quarantined": false,
|
||||
"received": false,
|
||||
"required_fields": [
|
||||
"dashboard_api_connection_check_status",
|
||||
"dashboard_api_version_check_status",
|
||||
"dashboard_index_pattern_statuses",
|
||||
"dashboard_api_degradation_root_cause",
|
||||
"dashboard_api_repair_postcheck_ref"
|
||||
],
|
||||
"slot_id": "dashboard_api_rbac_tls_repair_readback",
|
||||
"title": "Dashboard API / RBAC / TLS 修復讀回"
|
||||
},
|
||||
{
|
||||
"accepted": false,
|
||||
"next_gate": "owner_provided_redacted_export",
|
||||
"quarantined": false,
|
||||
"received": false,
|
||||
"required_fields": [
|
||||
"collection_method",
|
||||
"manager_health_ref",
|
||||
"redacted_evidence_refs"
|
||||
],
|
||||
"slot_id": "readonly_credential_metadata_without_secret",
|
||||
"title": "唯讀 credential metadata,不含 secret"
|
||||
},
|
||||
{
|
||||
"accepted": false,
|
||||
"next_gate": "owner_provided_redacted_export",
|
||||
"quarantined": false,
|
||||
"received": false,
|
||||
"required_fields": [
|
||||
"owner_role",
|
||||
"team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"followup_owner",
|
||||
"rollback_owner"
|
||||
],
|
||||
"slot_id": "owner_response_and_rollback_owner",
|
||||
"title": "Owner response / rollback owner"
|
||||
},
|
||||
{
|
||||
"accepted": false,
|
||||
"next_gate": "owner_provided_redacted_export",
|
||||
"quarantined": false,
|
||||
"received": false,
|
||||
"required_fields": [
|
||||
"postcheck_plan",
|
||||
"redacted_evidence_refs"
|
||||
],
|
||||
"slot_id": "post_enable_iwooos_readback",
|
||||
"title": "Post-enable IwoooS readback"
|
||||
}
|
||||
],
|
||||
"execution_boundaries": {
|
||||
"agent_identity_public_display_allowed": false,
|
||||
"host_write_authorized": false,
|
||||
"internal_ip_public_display_allowed": false,
|
||||
"kali_active_scan_authorized": false,
|
||||
"not_authorization": true,
|
||||
"raw_wazuh_payload_storage_allowed": false,
|
||||
"runtime_execution_authorized": false,
|
||||
"secret_value_collection_allowed": false,
|
||||
"wazuh_active_response_authorized": false,
|
||||
"wazuh_agent_reenroll_authorized": false,
|
||||
"wazuh_agent_restart_authorized": false,
|
||||
"wazuh_api_live_query_authorized": false,
|
||||
"wazuh_manager_restart_authorized": false
|
||||
},
|
||||
"expected_scope_aliases": [
|
||||
"managed_core_node_a",
|
||||
"managed_core_node_b",
|
||||
"managed_dev_node_a",
|
||||
"managed_dev_node_b",
|
||||
"managed_control_node_a",
|
||||
"managed_control_node_b"
|
||||
],
|
||||
"forbidden_actions": [
|
||||
"wazuh_api_live_query",
|
||||
"wazuh_agent_reenroll",
|
||||
"wazuh_agent_restart",
|
||||
"wazuh_manager_restart",
|
||||
"wazuh_active_response",
|
||||
"wazuh_dashboard_secret_patch",
|
||||
"host_write",
|
||||
"firewall_change",
|
||||
"nginx_reload",
|
||||
"k8s_or_argocd_change",
|
||||
"kali_active_scan"
|
||||
],
|
||||
"forbidden_payloads": [
|
||||
"raw_wazuh_payload",
|
||||
"raw_log",
|
||||
"full_journal",
|
||||
"full_cli_output",
|
||||
"unredacted_screenshot",
|
||||
"agent_name",
|
||||
"agent_id_plaintext",
|
||||
"internal_ip",
|
||||
"hostname",
|
||||
"authorization_header",
|
||||
"bearer_token",
|
||||
"basic_auth",
|
||||
"password",
|
||||
"token",
|
||||
"cookie",
|
||||
"private_key",
|
||||
"client_keys",
|
||||
"raw_dashboard_request",
|
||||
"dashboard_api_secret",
|
||||
"stored_api_password",
|
||||
"api_token",
|
||||
"active_response_enable",
|
||||
"agent_reenroll",
|
||||
"agent_restart",
|
||||
"host_write",
|
||||
"firewall_change",
|
||||
"nginx_reload"
|
||||
],
|
||||
"generated_at": "2026-06-27T15:24:00+08:00",
|
||||
"mode": "committed_validation_contract_no_runtime_no_secret_collection",
|
||||
"no_false_green_rules": [
|
||||
"reviewer validation contract 可見不代表 owner registry export 已收到。",
|
||||
"owner registry export received 不代表 manager_registry_accepted_count 可增加。",
|
||||
"Dashboard 可見、index pattern 三綠勾、HTTP 200 或 transport observed 不可替代 manager registry counts。",
|
||||
"reviewer accepted 只可更新只讀 posture;active response、agent restart、reenroll、host write、secret rotation 或掃描仍需獨立 runtime gate。"
|
||||
],
|
||||
"outcome_lanes": [
|
||||
"waiting_owner_registry_export",
|
||||
"request_missing_fields",
|
||||
"request_counts_arithmetic_fix",
|
||||
"request_alias_scope_parity_fix",
|
||||
"request_per_host_matrix_supplement",
|
||||
"request_dashboard_api_repair_postcheck",
|
||||
"request_readonly_credential_metadata",
|
||||
"request_owner_accountability_supplement",
|
||||
"quarantine_sensitive_payload",
|
||||
"reject_runtime_action_request",
|
||||
"ready_for_reviewer_validation",
|
||||
"accepted_for_readonly_posture_only",
|
||||
"waiting_post_enable_iwooos_readback"
|
||||
],
|
||||
"per_host_required_fields": [
|
||||
"node_alias",
|
||||
"scope_role",
|
||||
"registry_presence",
|
||||
"agent_status_bucket",
|
||||
"last_seen_state",
|
||||
"manager_group_ref",
|
||||
"agent_id_redacted_ref",
|
||||
"gap_reason",
|
||||
"redacted_evidence_ref"
|
||||
],
|
||||
"required_owner_fields": [
|
||||
"owner_role",
|
||||
"team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"collection_method",
|
||||
"agent_total",
|
||||
"agent_active",
|
||||
"agent_disconnected",
|
||||
"agent_never_connected",
|
||||
"last_seen_window_start",
|
||||
"last_seen_window_end",
|
||||
"registry_collected_at",
|
||||
"registry_export_scope_aliases",
|
||||
"per_host_registry_matrix",
|
||||
"registry_gap_reason_by_alias",
|
||||
"registry_export_summary_ref",
|
||||
"manager_health_ref",
|
||||
"dashboard_api_status_ref",
|
||||
"dashboard_api_connection_check_status",
|
||||
"dashboard_api_version_check_status",
|
||||
"dashboard_index_pattern_statuses",
|
||||
"dashboard_api_degradation_root_cause",
|
||||
"dashboard_api_repair_postcheck_ref",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"postcheck_plan"
|
||||
],
|
||||
"reviewer_validation_checks": [
|
||||
{
|
||||
"check_id": "RV-01",
|
||||
"failure_lane": "request_missing_fields",
|
||||
"required_evidence": "owner_role、team、decision、decision_reason、affected_scope、collection_method 與 redacted evidence refs 必須存在。",
|
||||
"title": "Export envelope 欄位齊全"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-02",
|
||||
"failure_lane": "request_counts_arithmetic_fix",
|
||||
"required_evidence": "agent_total 不得小於 active + disconnected + never_connected,且需有 registry_export_summary_ref。",
|
||||
"title": "Registry counts 算術一致"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-03",
|
||||
"failure_lane": "request_alias_scope_parity_fix",
|
||||
"required_evidence": "registry_export_scope_aliases 必須剛好覆蓋 6 個公開別名,不得加入真實主機名或內網識別。",
|
||||
"title": "Alias scope 與 IwoooS 覆蓋矩陣一致"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-04",
|
||||
"failure_lane": "request_per_host_matrix_supplement",
|
||||
"required_evidence": "每個公開節點別名都要有 9 個 per-host 欄位與 gap reason。",
|
||||
"title": "逐主機矩陣欄位完整"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-05",
|
||||
"failure_lane": "request_dashboard_api_repair_postcheck",
|
||||
"required_evidence": "API connection、API version、index pattern、degradation root cause 與 repair postcheck 需分欄。",
|
||||
"title": "Dashboard API 狀態不可用 index pattern 代替"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-06",
|
||||
"failure_lane": "request_readonly_credential_metadata",
|
||||
"required_evidence": "manager_health_ref 與 readonly credential metadata 只能是脫敏來源資訊,不得含 secret value。",
|
||||
"title": "Manager health 與 readonly credential metadata 可追溯"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-07",
|
||||
"failure_lane": "quarantine_sensitive_payload",
|
||||
"required_evidence": "不得含 raw Wazuh payload、完整 CLI output、未脫敏截圖、agent 原名、內網位址、token、密碼或 client key。",
|
||||
"title": "Forbidden payload 一律隔離"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-08",
|
||||
"failure_lane": "request_owner_accountability_supplement",
|
||||
"required_evidence": "followup_owner、rollback_owner、維護窗口與 postcheck plan 必須能被 reviewer 追蹤。",
|
||||
"title": "Owner / followup / rollback 責任可讀"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-09",
|
||||
"failure_lane": "reject_runtime_action_request",
|
||||
"required_evidence": "owner decision 不可夾帶 active response、agent restart、reenroll、host write、Nginx、firewall、K8s 或 secret rotation。",
|
||||
"title": "收件不等於 runtime 授權"
|
||||
},
|
||||
{
|
||||
"check_id": "RV-10",
|
||||
"failure_lane": "waiting_post_enable_iwooos_readback",
|
||||
"required_evidence": "即使 reviewer 未來接受 evidence,也只能進 read-only posture;必須另有 post-enable readback 才能更新 runtime truth。",
|
||||
"title": "Post-enable IwoooS readback 仍是下一關"
|
||||
}
|
||||
],
|
||||
"schema_version": "wazuh_manager_registry_reviewer_validation_v1",
|
||||
"scope": "wazuh_manager_registry_owner_export_reviewer_validation",
|
||||
"source_refs": [
|
||||
"docs/security/wazuh-agent-visibility-owner-evidence-preflight.snapshot.json",
|
||||
"docs/security/wazuh-managed-host-coverage-gate.snapshot.json"
|
||||
],
|
||||
"status": "waiting_owner_registry_export_for_reviewer_validation",
|
||||
"summary": {
|
||||
"active_response_authorized_count": 0,
|
||||
"evidence_slot_count": 6,
|
||||
"expected_scope_alias_count": 6,
|
||||
"forbidden_action_count": 11,
|
||||
"forbidden_payload_count": 27,
|
||||
"host_write_authorized_count": 0,
|
||||
"manager_registry_accepted_count": 0,
|
||||
"outcome_lane_count": 13,
|
||||
"owner_registry_export_accepted_count": 0,
|
||||
"owner_registry_export_received_count": 0,
|
||||
"per_host_required_field_count": 9,
|
||||
"post_enable_readback_passed_count": 0,
|
||||
"required_owner_field_count": 28,
|
||||
"reviewer_validation_check_count": 10,
|
||||
"reviewer_validation_failed_count": 0,
|
||||
"reviewer_validation_passed_count": 0,
|
||||
"reviewer_validation_quarantined_count": 0,
|
||||
"reviewer_validation_ready_count": 0,
|
||||
"runtime_gate_count": 0,
|
||||
"secret_value_collection_allowed_count": 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user