18 KiB
IwoooS Wazuh 只讀 API Release Handoff
狀態:source-side 修補、feature branch、正式主線、deploy marker 與 production route readback 已完成;仍等待 Wazuh live metadata owner gate、manager registry 驗收與 Dashboard stored API / RBAC / TLS 修復。 本文件不包含 secret、token、內網 Wazuh URL、raw log、raw Wazuh payload 或工作視窗逐字稿。
目前分層狀態
- feature branch:
codex/iwooos-wazuh-boundary-guard-20260624已推送到 Gitea;精確 HEAD 請用git ls-remote讀回,不在本文件硬寫避免文件 commit 後自我漂移。 - formal main release:
100%,Wazuh 只讀 route / no-false-green patch 已進正式主線。 - production deploy:
100%,正式 API 已讀回200 disabled_waiting_iwooos_wazuh_owner_gate。 - Wazuh live metadata env enable:
0%,尚未收到正式負責人回覆、機密來源中繼資料、唯讀帳號範圍與 post-enable readback。 - Wazuh manager agent registry accepted:
0%,尚未取得可驗收的 manager registry 只讀讀回。 - active response / host write / Kali active scan:
0%,必須維持關閉。
根因判定
正式釋出前,https://awoooi.wooo.work/api/iwooos/wazuh 曾回 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 已未安裝。
- 正式釋出後,production route 已讀回
200 disabled_waiting_iwooos_wazuh_owner_gate;這只代表 IwoooS route 已部署,不代表 Wazuh manager registry 已恢復或所有 agent 已納管。
Source-Side 修補
本地 commit:
codex/iwooos-wazuh-boundary-guard-20260624Wazuh API commit 會在每次 rebase 或文件同步後改變;請在 release 前用git log --oneline gitea/main..HEAD與git ls-remote讀回,不硬寫在本文件內。codex/iwooos-wazuh-boundary-guard-20260624feature branch 已推送;但 feature branch push 不等於 formal main release、production deploy 或 Wazuh live metadata 授權。- Release patch set 需在最終 docs commit 後以
git format-patch gitea/main..HEAD重新產生,再用shasum -a 256讀回;不得沿用 rebase 前或文件修正前的舊 patch SHA。
變更範圍:
apps/api/src/api/v1/iwooos.pyapps/api/src/services/iwooos_wazuh_readonly_status.pyapps/api/src/services/iwooos_runtime_security_readback.pyapps/api/src/main.pyapps/api/tests/test_iwooos_wazuh_api.pyapps/api/tests/test_iwooos_runtime_security_readback.pyscripts/security/wazuh-readonly-route-boundary-guard.pyscripts/security/wazuh-readonly-production-readback.pyscripts/security/wazuh-readonly-release-gate.pyscripts/security/wazuh-readonly-release-lane-preflight.pyscripts/security/wazuh-readonly-release-owner-request.pyscripts/security/wazuh-readonly-release-owner-response-acceptance.pyscripts/security/wazuh-readonly-live-metadata-env-gate.pyscripts/security/security-mirror-progress-guard.pydocs/security/wazuh-readonly-release-gate.snapshot.jsondocs/security/wazuh-readonly-release-lane-preflight.snapshot.jsondocs/security/wazuh-readonly-release-owner-request.snapshot.jsondocs/security/wazuh-readonly-release-owner-response-acceptance.snapshot.jsondocs/security/wazuh-readonly-live-metadata-env-gate.snapshot.jsonapps/web/src/app/[locale]/iwooos/page.tsxapps/web/messages/zh-TW.jsonapps/web/messages/en.jsondocs/LOGBOOK.md
完成內容:
- 新增 FastAPI
GET /api/iwooos/wazuh。 - 新增 FastAPI
GET /api/v1/iwooos/wazuh。 - 將 Wazuh 只讀 metadata 邏輯抽成
iwooos_wazuh_readonly_status.py,讓正式 route、Runtime 資安讀回與後續告警鏈共用同一份脫敏 aggregate 結果。 GET /api/v1/iwooos/runtime-security-readback新增wazuh_live_routeP0 lane 與wazuh_live_*summary;正式路由 disabled、misconfigured、registry empty、below expected 或 unavailable 都會在 Runtime board 顯示退化,不再只藏在下方卡片。- 預設回
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。
- 回傳資料只允許 metadata:agent alias、status、OS 類別、last_seen_present 與 aggregate counts。
- 新增 agent registry no-false-green:若 Wazuh manager registry 回
agent_total=0,API 必須回wazuh_agent_registry_empty;若低於 server-sideIWOOOS_WAZUH_EXPECTED_MIN_AGENT_COUNT,API 必須回wazuh_agent_registry_below_expected。 - summary 會回
expected_min_agent_count、agent_registry_empty_count、agent_below_expected_minimum_count、agent_visibility_no_false_green_count;這些只描述 aggregate 狀態,不公開 agent 身分或內網位址。 - 不回傳 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、feature branch push、formal main release、production deploy 與 production route readback 已完成;同時保留 Wazuh live metadata / manager registry / active response / host write 仍未授權,避免後續把 route 200 誤判成 Wazuh 納管恢復。
- 新增 release lane preflight snapshot 與 guard,固定正式 release 前必須選擇
formal_gitea_merge、formal_patch_apply或maintainer_local_push_with_safe_credential其中一條合規 lane,且 owner ack / evidence 未到齊前不得推主線、deploy、force push、使用明文 token workaround 或改 runtime。 - 新增 release owner request 草稿與 owner response acceptance 帳本,將 required ack flags、required evidence fields、allowed release methods、blocked actions、forbidden payloads 與 reviewer checks 機器可讀化;目前 request sent、response received / accepted、release ready、runtime gate 全部維持
0。 - 新增 live metadata env gate,固定部署後要先通過 production route readback、server-side env owner response、secret source metadata、Wazuh manager health ref、readonly account scope、post-enable readback、rollback 與 no-secret / no-raw-payload attestation;目前 live query authorized 仍為
0。 - 新增 IwoooS 前台「Wazuh 即時中繼資料環境閘門」卡片,公開顯示上述 gate 的
0 / false邊界;文案全部為繁體中文治理語,不放工作視窗逐字稿、委派 XML、聊天內容或個人英文名稱。
已完成驗證
已在 /private/tmp/awoooi-iwooos-wazuh-boundary-verify-20260624 執行:
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/wazuh-readonly-release-lane-preflight.py --root .
python3 scripts/security/wazuh-readonly-release-owner-request.py --root .
python3 scripts/security/wazuh-readonly-release-owner-response-acceptance.py --root .
python3 scripts/security/wazuh-readonly-live-metadata-env-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/api/src/services/iwooos_wazuh_readonly_status.py apps/api/src/services/iwooos_runtime_security_readback.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 scripts/security/wazuh-readonly-release-lane-preflight.py scripts/security/wazuh-readonly-release-owner-request.py scripts/security/wazuh-readonly-release-owner-response-acceptance.py scripts/security/wazuh-readonly-live-metadata-env-gate.py
python3 -m py_compile apps/api/src/api/v1/iwooos.py apps/api/src/services/iwooos_wazuh_readonly_status.py apps/api/src/services/iwooos_runtime_security_readback.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/wazuh-readonly-release-lane-preflight.py scripts/security/wazuh-readonly-release-owner-request.py scripts/security/wazuh-readonly-release-owner-response-acceptance.py scripts/security/wazuh-readonly-live-metadata-env-gate.py scripts/security/security-mirror-progress-guard.py
git diff --check
node -e "JSON.parse(require('fs').readFileSync('apps/web/messages/zh-TW.json','utf8')); JSON.parse(require('fs').readFileSync('apps/web/messages/en.json','utf8')); console.log('i18n json ok')"
cmp -s apps/web/messages/zh-TW.json apps/web/messages/en.json
pnpm --filter @awoooi/web typecheck
NEXT_PUBLIC_API_URL=https://awoooi.wooo.work NEXT_PRIVATE_BUILD_WORKER_COUNT=1 SENTRY_SUPPRESS_GLOBAL_ERROR_HANDLER_FILE_WARNING=1 pnpm --filter @awoooi/web build
驗證結果:
pytest apps/api/tests/test_iwooos_wazuh_api.py:6 passed。wazuh-readonly-route-boundary-guard:route=3 public_ui_files=1 forbidden=0 runtime_gate=0。wazuh-readonly-release-gate:source=1 push=1 main=1 deploy=1 readback=1 runtime_gate=0。wazuh-readonly-release-lane-preflight:ready=0 acks=0/6 evidence=0/6 runtime_gate=0。wazuh-readonly-release-owner-request:drafts=1 sent=0 accepted=0 runtime_gate=0。wazuh-readonly-release-owner-response-acceptance:received=0 accepted=0 acks=0/6 evidence=0/6 runtime_gate=0。wazuh-readonly-live-metadata-env-gate:route_readback=1 owner=0 secret_meta=0 live_query=0 runtime_gate=0。security-mirror-progress-guard:SECURITY_MIRROR_PROGRESS_GUARD_OK。doc-secrets-sanity-check:DOC_SECRET_SANITY_OK scanned_files=973。py_compile:通過。git diff --check:通過。- i18n JSON parse:通過。
zh-TW/enmessages mirror:通過。pnpm --filter @awoooi/web typecheck:通過。- Web production build:通過,
92/92static pages,/zh-TW/iwooosroute size61.8 kB、First Load JS292 kB;build env 使用公網NEXT_PUBLIC_API_URL=https://awoooi.wooo.work,未使用內網 IP。 - 本機 preview desktop:
/zh-TW/iwooos卡片可見,水平溢出false,沒有工作視窗 / 委派 / 對話字樣,卡片沒有英文流程裸字。 - 本機 preview mobile
390x844:卡片可見,水平溢出false,同樣沒有工作視窗 / 委派 / 對話字樣。
乾淨套用 Proof
乾淨套用 proof 需從最新 gitea/main 建立獨立 worktree:
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,不代表已合併主線、已部署或已啟用 Wazuh live metadata。最終 patch SHA 與 apply-check commit 應由 release 執行者在 final docs commit 之後用命令讀回,不寫入會自我漂移的 committed 文件。
乾淨套用 worktree 驗證結果:
pytest apps/api/tests/test_iwooos_wazuh_api.py:6 passed。python3 scripts/security/wazuh-readonly-route-boundary-guard.py --root .:WAZUH_READONLY_ROUTE_BOUNDARY_GUARD_OK route=3 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=1 main=1 deploy=1 readback=1 runtime_gate=0。python3 scripts/security/wazuh-readonly-release-lane-preflight.py --root .:WAZUH_READONLY_RELEASE_LANE_PREFLIGHT_OK ready=0 acks=0/6 evidence=0/6 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=973。python3 -m py_compile ...:通過。git diff --check:通過。
正式部署後的 production 現況記錄:
python3 scripts/security/wazuh-readonly-production-readback.py --json
預期只可回 IwoooS Wazuh read-only route 的安全邊界狀態;目前尚未啟用 Wazuh live metadata,因此不得顯示綠燈。
目前實測:
{"api_status":"disabled_waiting_iwooos_wazuh_owner_gate","configured":false,"http_status":200,"runtime_gate_count":0,"schema_version":"iwooos_wazuh_production_readback_v1","status":"production_readback_passed"}
這個讀回不代表 Wazuh manager registry 已恢復;它只代表 route 部署完成且目前仍正確停在 owner gate。
Release 前 Gate
下一階段 gate 需確認:
- Wazuh live metadata env gate 目前固定
owner=0、secret_meta=0、live_query=0;不得把一般「批准繼續」當成 server-side env owner response。 - route 已部署完成;下一步不是再修 404,而是建立 Wazuh manager registry 只讀驗收、Dashboard stored API / RBAC / TLS 修復與 post-enable readback。
- 不得複製舊 workspace 的內嵌明文 Gitea token。
- 不得把 Wazuh URL、帳密、token、cookie、private key、runner token 或 webhook secret 寫入 repo。
- 不得為了讓 agent 顯示回來而直接改 Nginx、Docker、K8s、firewall、Wazuh manager、Wazuh rule、Wazuh decoder、stored API、RBAC、TLS 或 Wazuh active response。
- 若要啟用 live metadata query,必須由正式 secrets / env 注入
IWOOOS_WAZUH_READONLY_ENABLED=true與 Wazuh server-side env,且要先有 owner gate。
Production Readback 預期
部署後、尚未啟用 Wazuh env 時:
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。
正式驗收命令:
python3 scripts/security/wazuh-readonly-production-readback.py --json
正式驗收不接受 404;若仍回 404,代表 FastAPI 相容 route 尚未部署或 gateway 尚未接到新 API。
若 owner gate 與 server-side env 已正式啟用:
- 成功時可回
readonly_metadata_available。 - manager registry 為空時必須回
wazuh_agent_registry_empty,不得顯示綠燈。 - manager registry 低於
IWOOOS_WAZUH_EXPECTED_MIN_AGENT_COUNT時必須回wazuh_agent_registry_below_expected,不得顯示綠燈。 - 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% |
已完成;固定 source / feature branch / main / deploy / readback 已完成,live metadata 仍 blocked |
| Wazuh release lane preflight | 100% |
已完成;owner acks 0/6、evidence 0/6、正式 release ready 0 |
| Wazuh release owner request / acceptance | 100% |
已完成只讀草稿與收件帳本;request sent 0、response accepted 0 |
| Wazuh live metadata env gate | 100% |
已完成只讀 gate;route readback 1,owner / secret metadata / live query 仍 0 |
| Wazuh agent registry no-false-green | 100% |
source-side 已能區分 registry 空與低於預期;production live registry accepted 仍 0 |
| IwoooS 前台 Wazuh live metadata env gate 卡片 | 100% |
source-side 與本機桌機 / 手機驗證完成;production route readback 已完成,live metadata 仍 0 |
| 乾淨套用 proof | 100% |
patch set 可落在最新 gitea/main 並通過同組 guard;最終 hash 以 release 前 readback 為準 |
| Gitea feature branch push | 100% |
codex/iwooos-wazuh-boundary-guard-20260624 已推送;精確 HEAD 以 release 前讀回為準 |
| Formal main release | 100% |
已進正式主線 |
| Production deploy / readback | 100% |
已回 200 disabled_waiting_iwooos_wazuh_owner_gate |
| Wazuh server-side env enable | 0% |
等待 owner gate 與 secrets 注入 |
| Wazuh manager agent registry accepted | 0% |
尚未取得可驗收 registry truth |
| Wazuh event refs / host forensic refs accepted | 0% |
尚未收到合格證據 |
| Wazuh active response / host write / Kali active scan | 0% |
必須維持 false |
下一步優先序
- 依
wazuh-readonly-live-metadata-env-gate.snapshot.json補 server-side env owner response、secret source metadata、Wazuh manager health ref、readonly account scope 與 post-enable readback,才可考慮啟用 Wazuh read-only metadata query。 - 取得 Wazuh manager agent registry 的脫敏、可驗收只讀讀回:總數、在線、離線、從未連線、最後連線時間窗與 Dashboard API 狀態參照。
- 修復 Dashboard stored API / RBAC / run_as / rate-limit / TLS trust 退化;修復前不得把 Dashboard 看不到 agent 解讀成 agent 全部消失,也不得把 transport count 解讀成 agent registry 恢復。
- 收件 Wazuh manager health ref、agent status ref、event refs、host forensic refs 與 containment / recovery proof。
- 仍禁止 active response、host write、firewall / Nginx / Docker / K8s runtime action、Kali active scan、secret 明文收集。