Files
awoooi/docs/security/IWOOOS-WAZUH-READONLY-API-RELEASE-HANDOFF.md

178 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IwoooS Wazuh 只讀 API Release Handoff
> 狀態source-side 修補完成,等待具備正式 Gitea push / release 權限的 lane 合併與部署。
> 本文件不包含 secret、token、內網 Wazuh URL、raw log、raw Wazuh payload 或工作視窗逐字稿。
## 根因判定
`https://awoooi.wooo.work/api/iwooos/wazuh` production 目前回 `404 {"detail":"Not Found"}`,同時 `https://awoooi.wooo.work/zh-TW/iwooos``200`
判定根因:
- production `/api` 目前落到 FastAPI 後端。
- 既有 `apps/web/src/app/api/iwooos/wazuh/route.ts` 是 Next.js route沒有被 public gateway 暴露到這條 production path。
- FastAPI 後端原本沒有 `/api/iwooos/wazuh` 相容 route因此回 404。
- 這個 404 不能被解讀成 Wazuh manager 一定故障,也不能被解讀成 Wazuh 已未安裝。
## Source-Side 修補
本地 commit
- `codex/iwooos-wazuh-boundary-guard-20260624` Wazuh API commit`47d36e85 fix(iwooos): 接上 Wazuh 只讀 API 邊界`
- `codex/iwooos-wazuh-boundary-guard-20260624` 最終分支 HEAD 不硬寫在本文件內;請在 release 前用 `git rev-parse HEAD` 讀回,避免 commit 自我引用造成 hash 漂移。
- Release patch set 需在最終 docs commit 後以 `git format-patch gitea/main..HEAD` 重新產生,再用 `shasum -a 256` 讀回;不得沿用 rebase 前或文件修正前的舊 patch SHA。
變更範圍:
- `apps/api/src/api/v1/iwooos.py`
- `apps/api/src/main.py`
- `apps/api/tests/test_iwooos_wazuh_api.py`
- `scripts/security/wazuh-readonly-route-boundary-guard.py`
- `scripts/security/wazuh-readonly-production-readback.py`
- `scripts/security/wazuh-readonly-release-gate.py`
- `scripts/security/security-mirror-progress-guard.py`
- `docs/security/wazuh-readonly-release-gate.snapshot.json`
- `docs/LOGBOOK.md`
完成內容:
- 新增 FastAPI `GET /api/iwooos/wazuh`
- 新增 FastAPI `GET /api/v1/iwooos/wazuh`
- 預設回 `disabled_waiting_iwooos_wazuh_owner_gate`,避免 production 繼續用 404 表示未啟用。
- live Wazuh 查詢仍需 `IWOOOS_WAZUH_READONLY_ENABLED=true` 與 server-side env`WAZUH_API_BASE_URL``WAZUH_API_USERNAME``WAZUH_API_PASSWORD`
- 強制 Wazuh base URL 使用 HTTPS。
- 回傳資料只允許 metadataagent alias、status、OS 類別、last_seen_present 與 aggregate counts。
- 不回傳 raw Wazuh payload、agent 原名、內網 IP、token、password 或 secret。
- 新增 source guard阻擋硬編 Wazuh 內網 URL / port、帳密、關 TLS、假 SOC dashboard、假 CVE、raw payload 與 legacy dashboard component 回流。
- 新增 production readback 腳本,部署後可直接驗證 public API 不再 404、schema / status / boundary 正確,且沒有 raw payload、內網 IP、agent 原名或 secret 洩漏。
- 新增 release gate snapshot 與 guard固定 source-side 已完成、Gitea push / production deploy / production readback 尚未完成,避免後續把 predeploy 404 誤判成通過。
## 已完成驗證
已在 `/private/tmp/awoooi-iwooos-wazuh-boundary-verify-20260624` 執行:
```bash
pytest apps/api/tests/test_iwooos_wazuh_api.py
python3 scripts/security/wazuh-readonly-route-boundary-guard.py --root .
python3 scripts/security/wazuh-readonly-release-gate.py --root .
python3 scripts/security/security-mirror-progress-guard.py --root .
python3 scripts/ops/doc-secrets-sanity-check.py docs apps/api/src/api/v1/iwooos.py apps/web/src/app/api/iwooos/wazuh/route.ts scripts/security/wazuh-readonly-route-boundary-guard.py scripts/security/wazuh-readonly-production-readback.py scripts/security/wazuh-readonly-release-gate.py
python3 -m py_compile apps/api/src/api/v1/iwooos.py scripts/security/wazuh-readonly-route-boundary-guard.py scripts/security/wazuh-readonly-production-readback.py scripts/security/wazuh-readonly-release-gate.py scripts/security/security-mirror-progress-guard.py
git diff --check
```
驗證結果:
- `pytest apps/api/tests/test_iwooos_wazuh_api.py``4 passed`
- `wazuh-readonly-route-boundary-guard``route=2 public_ui_files=1 forbidden=0 runtime_gate=0`
- `wazuh-readonly-release-gate``source=1 push=0 deploy=0 readback=0 runtime_gate=0`
- `security-mirror-progress-guard``SECURITY_MIRROR_PROGRESS_GUARD_OK`
- `doc-secrets-sanity-check``DOC_SECRET_SANITY_OK scanned_files=969`
- `py_compile`:通過。
- `git diff --check`:通過。
## 乾淨套用 Proof
乾淨套用 proof 需從最新 `gitea/main=80604403` 或更新的主線建立獨立 worktree
```bash
git worktree add /private/tmp/awoooi-iwooos-wazuh-release-apply-check-<timestamp> gitea/main
git am /private/tmp/awoooi-iwooos-wazuh-boundary-release-patch-<timestamp>/*.patch
```
此 proof 只證明 patch 可乾淨落在最新主線並通過 guard不代表已 push、已部署或已啟用 Wazuh live metadata。最終 patch SHA 與 apply-check commit 應由 release 執行者在 final docs commit 之後用命令讀回,不寫入會自我漂移的 committed 文件。
乾淨套用 worktree 驗證結果:
- `pytest apps/api/tests/test_iwooos_wazuh_api.py``4 passed`
- `python3 scripts/security/wazuh-readonly-route-boundary-guard.py --root .``WAZUH_READONLY_ROUTE_BOUNDARY_GUARD_OK route=2 public_ui_files=1 forbidden=0 runtime_gate=0`
- `python3 scripts/security/wazuh-readonly-release-gate.py --root .``WAZUH_READONLY_RELEASE_GATE_OK source=1 push=0 deploy=0 readback=0 runtime_gate=0`
- `python3 scripts/security/security-mirror-progress-guard.py --root .``SECURITY_MIRROR_PROGRESS_GUARD_OK`
- `python3 scripts/ops/doc-secrets-sanity-check.py ...``DOC_SECRET_SANITY_OK scanned_files=969`
- `python3 -m py_compile ...`:通過。
- `git diff --check`:通過。
尚未部署前的 production 現況記錄:
```bash
python3 scripts/security/wazuh-readonly-production-readback.py --allow-predeploy-404 --json
```
預期只可回 `status=predeploy_404_observed`。正式部署驗收不得加 `--allow-predeploy-404`
目前實測:
```json
{"http_status": 404, "runtime_gate_count": 0, "schema_version": "iwooos_wazuh_production_readback_v1", "status": "predeploy_404_observed"}
```
不加 `--allow-predeploy-404` 時會正確阻擋:`BLOCKED production readback returned 404; Wazuh FastAPI compatibility route is not deployed`
## Release 前 Gate
合併 / 部署前需確認:
- 使用具備正式權限的 Gitea lane 合併 `codex/iwooos-wazuh-boundary-guard-20260624` 分支 HEAD 或同等 patch不得 force push。
- 目前非互動式 push 實測仍被 Gitea HTTPS credential 擋住:`fatal: could not read Username for 'https://gitea.wooo.work': terminal prompts disabled`
- 不得複製舊 workspace 的內嵌明文 Gitea token。
- 不得把 Wazuh URL、帳密、token、cookie、private key、runner token 或 webhook secret 寫入 repo。
- 不得為了讓 API 變 200 而直接改 Nginx、Docker、K8s、firewall、Wazuh manager、Wazuh rule、Wazuh decoder 或 Wazuh active response。
- 若要啟用 live metadata query必須由正式 secrets / env 注入 `IWOOOS_WAZUH_READONLY_ENABLED=true` 與 Wazuh server-side env且要先有 owner gate。
## Production Readback 預期
部署後、尚未啟用 Wazuh env 時:
```bash
curl -sS https://awoooi.wooo.work/api/iwooos/wazuh
```
預期:
- HTTP `200`
- `schema_version=iwooos_wazuh_readonly_status_v1`
- `status=disabled_waiting_iwooos_wazuh_owner_gate`
- `configured=false`
- `runtime_gate_count=0`
- `active_response_authorized=false`
- `host_write_authorized=false`
- 不含內網 IP、agent 原名、token、password、raw payload。
正式驗收命令:
```bash
python3 scripts/security/wazuh-readonly-production-readback.py --json
```
正式驗收不接受 404若仍回 404代表 FastAPI 相容 route 尚未部署或 gateway 尚未接到新 API。
若 owner gate 與 server-side env 已正式啟用:
- 成功時可回 `readonly_metadata_available`
- Wazuh 不可達時可回 `wazuh_readonly_metadata_unavailable`
- 任何情況都不得回 raw payload、agent 原名、內網 IP、secret。
- 任何情況都不得因 route 可用而自動打開 active response、host write、Kali active scan 或 SOAR action。
## 完成度
| 項目 | 完成度 | 狀態 |
|---|---:|---|
| Wazuh public API 404 source-side 修補 | `100%` | 已完成本地分支 HEAD |
| Wazuh route boundary source guard | `100%` | 已納入 `security-mirror-progress-guard` |
| Production readback 驗收腳本 | `100%` | 已完成;正式部署後不得接受 404 |
| Wazuh release gate snapshot / guard | `100%` | 已完成;固定 push/deploy/readback 仍 blocked |
| 乾淨套用 proof | `100%` | patch set 可落在最新 `gitea/main` 並通過同組 guard最終 hash 以 release 前 readback 為準 |
| Gitea push | `0%` | 受控 workspace HTTPS credential 缺失 |
| Production deploy / readback | `0%` | 等待 release lane |
| Wazuh server-side env enable | `0%` | 等待 owner gate 與 secrets 注入 |
| Wazuh event refs / host forensic refs accepted | `0%` | 尚未收到合格證據 |
| Wazuh active response / host write / Kali active scan | `0%` | 必須維持 false |
## 下一步優先序
1. 解決受控 workspace Gitea HTTPS push 認證,或由正式 release lane 合併 `codex/iwooos-wazuh-boundary-guard-20260624` 分支 HEAD。
2. 部署後先驗證 `/api/iwooos/wazuh` 不再 404且預設 disabled 邊界正確。
3. 另開 owner gate 決定是否啟用 server-side Wazuh read-only metadata query。
4. 收件 Wazuh manager health ref、agent status ref、event refs、host forensic refs 與 containment / recovery proof。
5. 仍禁止 active response、host write、firewall / Nginx / Docker / K8s runtime action、Kali active scan、secret 明文收集。