# 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 會在每次 rebase 後改變;請在 release 前用 `git log --oneline gitea/main..HEAD` 讀回,不硬寫在本文件內。 - `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/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` - `docs/security/wazuh-readonly-release-gate.snapshot.json` - `docs/security/wazuh-readonly-release-lane-preflight.snapshot.json` - `docs/security/wazuh-readonly-release-owner-request.snapshot.json` - `docs/security/wazuh-readonly-release-owner-response-acceptance.snapshot.json` - `docs/security/wazuh-readonly-live-metadata-env-gate.snapshot.json` - `apps/web/src/app/[locale]/iwooos/page.tsx` - `apps/web/messages/zh-TW.json` - `apps/web/messages/en.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。 - 回傳資料只允許 metadata:agent 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 誤判成通過。 - 新增 release lane preflight snapshot 與 guard,固定正式 release 前必須選擇 `formal_gitea_merge`、`formal_patch_apply` 或 `maintainer_local_push_with_safe_credential` 其中一條合規 lane,且 owner ack / evidence 未到齊前不得 push、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` 執行: ```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/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/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 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`:`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`。 - `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=0 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` / `en` messages mirror:通過。 - `pnpm --filter @awoooi/web typecheck`:通過。 - Web production build:通過,`92/92` static pages,`/zh-TW/iwooos` route size `61.8 kB`、First Load JS `292 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: ```bash git worktree add /private/tmp/awoooi-iwooos-wazuh-release-apply-check- gitea/main git am /private/tmp/awoooi-iwooos-wazuh-boundary-release-patch-/*.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/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 現況記錄: ```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。 - release lane preflight 目前固定 `formal_release_lane_ready_count=0`、`accepted_ack_flag_count=0/6`、`accepted_evidence_field_count=0/6`;不得把一般「批准繼續」當成 release lane owner response。 - 目前非互動式 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 | | 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 / owner / secret metadata / live query 仍 `0` | | IwoooS 前台 Wazuh live metadata env gate 卡片 | `100%` | source-side 與本機桌機 / 手機驗證完成;production deploy 仍 `0` | | 乾淨套用 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. 先依 `wazuh-readonly-release-owner-request.snapshot.json` 補 release lane owner response:選擇 formal merge、formal patch apply 或安全 credential push,並補 6 個 ack 與 6 個 evidence 欄位。 2. 解決受控 workspace Gitea HTTPS push 認證,或由正式 release lane 合併 `codex/iwooos-wazuh-boundary-guard-20260624` 分支 HEAD。 3. 部署後先驗證 `/api/iwooos/wazuh` 不再 404,且預設 disabled 邊界正確。 4. 另依 `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。 5. 收件 Wazuh manager health ref、agent status ref、event refs、host forensic refs 與 containment / recovery proof。 6. 仍禁止 active response、host write、firewall / Nginx / Docker / K8s runtime action、Kali active scan、secret 明文收集。