feat(iwooos): add Wazuh registry export preflight
Some checks failed
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / tests (push) Successful in 1m42s
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled

This commit is contained in:
ogt
2026-06-25 14:17:12 +08:00
parent 5dbe2870b2
commit ffeab51bc1
8 changed files with 259 additions and 23 deletions

View File

@@ -15,6 +15,7 @@ Wazuh 用戶端消失事故不能用 Dashboard 畫面、代理服務在線、TCP
- `decision`
- `decision_reason`
- `affected_scope`
- `collection_method`
- `agent_total`
- `agent_active`
- `agent_disconnected`
@@ -22,6 +23,10 @@ Wazuh 用戶端消失事故不能用 Dashboard 畫面、代理服務在線、TCP
- `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`
- `redacted_evidence_refs`
@@ -33,6 +38,9 @@ Wazuh 用戶端消失事故不能用 Dashboard 畫面、代理服務在線、TCP
- 欄位齊全且皆為脫敏 metadata。
- `agent_total` 不可小於 `agent_active + agent_disconnected + agent_never_connected`
- `collection_method` 只能是既有唯讀 API 或 manager 端脫敏 CLI 匯出,不可要求 secret 明文。
- `registry_export_scope_aliases` 必須完整覆蓋 6 個公開節點別名。
- `per_host_registry_matrix` 每列只能使用公開別名不得包含內網位址、agent 原名或 raw payload。
- `last_seen` 時間窗需能覆蓋事故觀察區間。
- manager health ref 與 dashboard API status ref 不可互相替代。
- redacted evidence refs 不得包含 raw payload、截圖原文或主機完整輸出。
@@ -48,12 +56,53 @@ Wazuh 用戶端消失事故不能用 Dashboard 畫面、代理服務在線、TCP
- authorization header、token、basic auth、password、cookie、private key、client key。
- 夾帶 active response、host write、firewall change、Nginx reload 或其他 runtime 操作要求。
## Manager registry 脫敏匯出契約
Wazuh manager registry 才是判定「所有用戶端是否仍在」的主要來源。匯出時只能使用下列公開節點別名不得放內網位址、主機原名、agent 原名或完整 CLI / API 輸出。
| 節點別名 | 用途 |
|---|---|
| `managed_core_node_a` | 核心服務節點 |
| `managed_core_node_b` | 資料服務節點 |
| `managed_dev_node_a` | 開發工作節點 |
| `managed_dev_node_b` | 開發工作節點 |
| `managed_control_node_a` | 控制平面節點 |
| `managed_control_node_b` | 控制平面節點 |
允許的收集方式:
- `wazuh_api_readonly_redacted_counts`
- `manager_agent_control_redacted_export`
逐主機矩陣每列必填欄位:
- `node_alias`
- `scope_role`
- `registry_presence`
- `agent_status_bucket`
- `last_seen_state`
- `manager_group_ref`
- `agent_id_redacted_ref`
- `gap_reason`
- `redacted_evidence_ref`
脫敏要求:
- 只允許公開節點別名,不允許內網位址、主機原名或 agent 原名。
- agent id 僅能用不可逆 evidence ref不得放完整值、雜湊、前後綴或 client key。
- 每個缺口必須有 gap reason不得以 Dashboard 空白或口頭說明補成綠燈。
- 只收計數、狀態桶、時間窗與證據 ref不收 raw API payload、完整 CLI output 或截圖原文。
## 現況計數
| 項目 | 計數 |
|---|---:|
| 必要欄位 | `18` |
| Reviewer 檢查 | `7` |
| 必要欄位 | `23` |
| Reviewer 檢查 | `10` |
| 公開節點別名 | `6` |
| 逐主機必填欄位 | `9` |
| Registry export received | `0` |
| Registry export accepted | `0` |
| Outcome lanes | `5` |
| Forbidden payloads | `18` |
| Owner evidence received | `0` |
@@ -69,7 +118,7 @@ python3 scripts/security/wazuh-agent-visibility-owner-evidence-preflight.py --ro
預期:
```text
WAZUH_AGENT_VISIBILITY_OWNER_EVIDENCE_PREFLIGHT_OK fields=18 checks=7 received=0 accepted=0 runtime_gate=0
WAZUH_AGENT_VISIBILITY_OWNER_EVIDENCE_PREFLIGHT_OK fields=23 checks=10 aliases=6 export_received=0 received=0 accepted=0 runtime_gate=0
```
## 邊界

View File

@@ -26,17 +26,26 @@
## 綠燈前必備證據
1. Manager registry agent counts總數、在線、離線、從未連線、最後連線時間窗。
2. 逐主機 agent scope matrix只用公開別名不列內網位址、agent 原名或 raw payload。
2. 逐主機 agent scope matrix只用公開別名不列內網位址、agent 原名或 raw payload;欄位需符合 `WAZUH-AGENT-VISIBILITY-OWNER-EVIDENCE-PREFLIGHT.md` 的 manager registry 脫敏匯出契約
3. Dashboard API / RBAC / TLS 修復讀回stored API、rate-limit、run_as、TLS trust 都要有脫敏參照。
4. 唯讀認證中繼資料:只收 secret name、來源、owner、rotation / rollback owner不收明文值、雜湊或片段。
5. Owner responseowner role / team、decision、decision reason、affected scope、redacted evidence refs、followup owner、rollback owner。
6. IwoooS 啟用後讀回:不得回傳 raw log、agent 原名、內網位址、secret 或 host output。
## Manager registry export 最小格式
Wazuh agents 是否真的恢復,必須以 manager registry 脫敏匯出交叉檢查。IwoooS 目前接受下列最小格式:
- 範圍:`managed_core_node_a``managed_core_node_b``managed_dev_node_a``managed_dev_node_b``managed_control_node_a``managed_control_node_b`
- 收集方式:`wazuh_api_readonly_redacted_counts``manager_agent_control_redacted_export`
- 逐主機欄位:`node_alias``scope_role``registry_presence``agent_status_bucket``last_seen_state``manager_group_ref``agent_id_redacted_ref``gap_reason``redacted_evidence_ref`
- 驗收邊界:`registry_export_received_count=0``registry_export_accepted_count=0` 時,不得宣稱所有主機已納管。
## 後續優先順序
| 優先 | 工作 | 完成度 |
| --- | --- | ---: |
| P0-A | Manager registry 只讀計數與逐主機矩陣 | 0% |
| P0-A | Manager registry 只讀計數與逐主機矩陣脫敏匯出 | 0% |
| P0-B | Dashboard stored API / RBAC / rate-limit / TLS 修復 | 0% |
| P0-C | 直接無 transport 節點的合法只讀後檢 | 0% |
| P0-D | SSH 受阻節點 owner export 或只讀 access | 0% |

View File

@@ -21,6 +21,7 @@
"bearer_token",
"basic_auth",
"password",
"token",
"cookie",
"private_key",
"client_keys",
@@ -33,6 +34,7 @@
"operator_interpretation": [
"這是 Wazuh agent registry 脫敏證據收件前的預檢,不代表已收到或已接受 owner evidence。",
"agent service active、TCP 連線存在、Dashboard 可見或口頭宣稱都不可替代 manager registry counts。",
"逐主機 registry export 必須使用固定公開節點別名與狀態桶,不能把 agent 原名或內網識別資訊帶到前台。",
"若 evidence 夾帶 raw log、未脫敏截圖、內網位址、agent 原名或 secret必須隔離不得渲染到前台。",
"任何 active response、host write、firewall、Nginx、Docker、K8s 或 secret 變更都要切獨立人工批准。"
],
@@ -43,12 +45,46 @@
"reject_runtime_action_request",
"ready_for_reviewer_validation"
],
"registry_export_contract": {
"allowed_collection_methods": [
"wazuh_api_readonly_redacted_counts",
"manager_agent_control_redacted_export"
],
"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"
],
"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"
],
"redaction_requirements": [
"只允許公開節點別名,不允許內網位址、主機原名或 agent 原名。",
"agent id 僅能用不可逆 evidence ref不得放完整值、雜湊、前後綴或 client key。",
"每個缺口必須有 gap reason不得以 Dashboard 空白或口頭說明補成綠燈。",
"只收計數、狀態桶、時間窗與證據 ref不收 raw API payload、完整 CLI output 或截圖原文。"
],
"registry_export_accepted_count": 0,
"registry_export_received_count": 0
},
"required_fields": [
"owner_role",
"team",
"decision",
"decision_reason",
"affected_scope",
"collection_method",
"agent_total",
"agent_active",
"agent_disconnected",
@@ -56,6 +92,10 @@
"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",
"redacted_evidence_refs",
@@ -66,6 +106,9 @@
"reviewer_checks": [
"欄位齊全且皆為脫敏 metadata。",
"agent_total 不可小於 active + disconnected + never_connected。",
"collection_method 只能是既有唯讀 API 或 manager 端脫敏 CLI 匯出,不可要求 secret 明文。",
"registry_export_scope_aliases 必須完整覆蓋 6 個公開節點別名。",
"per_host_registry_matrix 每列只能使用公開別名不得包含內網位址、agent 原名或 raw payload。",
"last_seen 時間窗需能覆蓋事故觀察區間。",
"manager health ref 與 dashboard API status ref 不可互相替代。",
"redacted evidence refs 不得包含 raw payload、截圖原文或主機完整輸出。",
@@ -77,15 +120,19 @@
"status": "owner_evidence_preflight_ready_no_runtime_action",
"summary": {
"active_response_authorized_count": 0,
"forbidden_payload_count": 17,
"expected_scope_alias_count": 6,
"forbidden_payload_count": 18,
"host_write_authorized_count": 0,
"outcome_lane_count": 5,
"owner_evidence_accepted_count": 0,
"owner_evidence_quarantined_count": 0,
"owner_evidence_received_count": 0,
"owner_evidence_rejected_count": 0,
"required_field_count": 18,
"reviewer_check_count": 7,
"per_host_required_field_count": 9,
"registry_export_accepted_count": 0,
"registry_export_received_count": 0,
"required_field_count": 23,
"reviewer_check_count": 10,
"runtime_gate_count": 0,
"secret_value_collection_allowed_count": 0
}