feat(iwooos): add wazuh allowlisted dry-run gate
This commit is contained in:
@@ -48710,3 +48710,39 @@ production browser smoke:
|
||||
**本段驗證目標**:
|
||||
- JSON parse、`py_compile`、focused GitHub gate API tests、Delivery Workbench test、`git diff --check`。
|
||||
- 此段只關閉內部 MCP / RAG / KM / PlayBook / LOG governance gap;GitHub executable channel 仍維持 freeze / external unblock。
|
||||
## 2026-06-28 — 19:09 Wazuh allowlisted check-mode dry-run 本地完成
|
||||
|
||||
**時間與來源**:
|
||||
- 2026-06-28 18:20-19:09 Asia/Taipei。
|
||||
- 來源:feature branch `codex/wazuh-manager-registry-accepted-readback-20260628`,接續 production 已讀回的 Wazuh manager registry accepted、controlled apply preflight 與 runtime gate owner-review readback。
|
||||
|
||||
**完成內容**:
|
||||
- 新增 `docs/security/wazuh-allowlisted-check-mode-dry-run.snapshot.json`,把 6 個公開 alias target selector、check-mode plan、dry-run evidence refs、dry-run result refs、redaction attestation、post dry-run verifier、rollback revalidation 與 KM / PlayBook writeback 收成可讀回 contract。
|
||||
- 新增 `GET /api/v1/iwooos/wazuh-allowlisted-check-mode-dry-run`,只回傳公開安全 readback;不查 live Wazuh、不讀主機、不保存 raw output、不讀或回傳 secret。
|
||||
- 新增 `POST /api/v1/iwooos/wazuh-allowlisted-check-mode-dry-run/validate-dry-run-packet`,只做單次 redacted dry-run packet no-persist validation,分流 accepted / supplement / quarantined / rejected runtime action;POST 不更新總帳。
|
||||
- `runtime-security-readback` 納入第 12 條 P0 lane:`source_snapshot_count=13`、`p0_lane_count=12`,並新增 allowlisted dry-run counters;dry-run accepted readback 為 `1`,runtime gate 仍為 `0`。
|
||||
- `/zh-TW/iwooos` 新增 allowlisted dry-run summary 與 lane status;`en` / `zh-TW` messages 依現有 IwoooS mirror guard 同步新增文案。
|
||||
|
||||
**本地驗證結果**:
|
||||
- `python3 -m json.tool docs/security/wazuh-allowlisted-check-mode-dry-run.snapshot.json >/dev/null`:通過。
|
||||
- `python3 -m json.tool apps/web/messages/zh-TW.json >/dev/null`、`python3 -m json.tool apps/web/messages/en.json >/dev/null`:通過。
|
||||
- `python3 -m py_compile apps/api/src/services/iwooos_wazuh_allowlisted_check_mode_dry_run.py apps/api/src/services/iwooos_runtime_security_readback.py apps/api/src/api/v1/iwooos.py`:通過。
|
||||
- `DATABASE_URL=sqlite:///test.db PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_iwooos_runtime_security_readback.py -q`:`21 passed`。
|
||||
- `python3.11 -m ruff check apps/api/src/services/iwooos_wazuh_allowlisted_check_mode_dry_run.py apps/api/src/services/iwooos_runtime_security_readback.py apps/api/src/api/v1/iwooos.py apps/api/tests/test_iwooos_runtime_security_readback.py`:通過。
|
||||
- `python3 scripts/security/wazuh-readonly-route-boundary-guard.py --root .`:`WAZUH_READONLY_ROUTE_BOUNDARY_GUARD_OK route=4 public_ui_files=1 forbidden=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 --filter @awoooi/web exec tsc --noEmit --incremental false`:通過。
|
||||
- `git diff --check`:通過。
|
||||
|
||||
**仍維持 0 / false**:
|
||||
- `runtime_gate_count=0`、`wazuh_api_live_query_authorized_count=0`、`wazuh_active_response_authorized_count=0`、`host_write_authorized_count=0`、`secret_value_collection_allowed_count=0`。
|
||||
- `runtime_execution_authorized=false`、`payload_persisted=false`、`raw_wazuh_payload_storage_allowed=false`、`raw_output_storage_allowed=false`、`not_authorization=true`。
|
||||
|
||||
**未做**:
|
||||
- 沒有查 live Wazuh API、沒有 host / Docker / systemd / Nginx / firewall / K8s / DB / Wazuh runtime 寫操作。
|
||||
- 沒有讀 secret 明文、沒有讀 `.env`、沒有讀 raw sessions / SQLite / auth。
|
||||
- 沒有使用 GitHub API / gh / GitHub Actions;沒有 force push。
|
||||
|
||||
**下一個 P0**:
|
||||
- commit / push 到 Gitea main,等待 Gitea CD / code-review,部署後驗證 `GET /api/v1/iwooos/wazuh-allowlisted-check-mode-dry-run`、POST redacted sample、`GET /api/v1/iwooos/runtime-security-readback` 與 `/zh-TW/iwooos` desktop / mobile。
|
||||
|
||||
237
docs/security/wazuh-allowlisted-check-mode-dry-run.snapshot.json
Normal file
237
docs/security/wazuh-allowlisted-check-mode-dry-run.snapshot.json
Normal file
@@ -0,0 +1,237 @@
|
||||
{
|
||||
"schema_version": "wazuh_allowlisted_check_mode_dry_run_v1",
|
||||
"generated_at": "2026-06-28T19:10:00+08:00",
|
||||
"status": "allowlisted_check_mode_dry_run_staged_no_runtime_action",
|
||||
"mode": "committed_dry_run_readback_no_live_wazuh_no_secret_collection",
|
||||
"summary": {
|
||||
"expected_scope_alias_count": 6,
|
||||
"allowlisted_target_selector_count": 6,
|
||||
"check_mode_plan_count": 1,
|
||||
"dry_run_evidence_ref_count": 1,
|
||||
"dry_run_result_ref_count": 1,
|
||||
"dry_run_redaction_attestation_count": 1,
|
||||
"post_dry_run_verifier_count": 1,
|
||||
"rollback_revalidation_count": 1,
|
||||
"km_playbook_writeback_ready_count": 1,
|
||||
"dry_run_packet_received_count": 1,
|
||||
"dry_run_packet_review_ready_count": 1,
|
||||
"dry_run_packet_accepted_count": 1,
|
||||
"dry_run_packet_supplement_required_count": 0,
|
||||
"dry_run_packet_quarantined_count": 0,
|
||||
"dry_run_runtime_action_rejected_count": 0,
|
||||
"forbidden_payload_count": 18,
|
||||
"forbidden_action_count": 20,
|
||||
"runtime_gate_count": 0,
|
||||
"wazuh_api_live_query_authorized_count": 0,
|
||||
"wazuh_active_response_authorized_count": 0,
|
||||
"host_write_authorized_count": 0,
|
||||
"secret_value_collection_allowed_count": 0
|
||||
},
|
||||
"target_selectors": [
|
||||
{
|
||||
"node_alias": "managed_core_node_a",
|
||||
"scope": "wazuh_manager_registry_accepted_alias",
|
||||
"selector_kind": "public_alias_only",
|
||||
"check_mode_allowed": true,
|
||||
"runtime_write_allowed": false
|
||||
},
|
||||
{
|
||||
"node_alias": "managed_core_node_b",
|
||||
"scope": "wazuh_manager_registry_accepted_alias",
|
||||
"selector_kind": "public_alias_only",
|
||||
"check_mode_allowed": true,
|
||||
"runtime_write_allowed": false
|
||||
},
|
||||
{
|
||||
"node_alias": "managed_core_node_c",
|
||||
"scope": "wazuh_manager_registry_accepted_alias",
|
||||
"selector_kind": "public_alias_only",
|
||||
"check_mode_allowed": true,
|
||||
"runtime_write_allowed": false
|
||||
},
|
||||
{
|
||||
"node_alias": "managed_edge_node_a",
|
||||
"scope": "wazuh_manager_registry_accepted_alias",
|
||||
"selector_kind": "public_alias_only",
|
||||
"check_mode_allowed": true,
|
||||
"runtime_write_allowed": false
|
||||
},
|
||||
{
|
||||
"node_alias": "managed_edge_node_b",
|
||||
"scope": "wazuh_manager_registry_accepted_alias",
|
||||
"selector_kind": "public_alias_only",
|
||||
"check_mode_allowed": true,
|
||||
"runtime_write_allowed": false
|
||||
},
|
||||
{
|
||||
"node_alias": "managed_lab_node_a",
|
||||
"scope": "wazuh_manager_registry_accepted_alias",
|
||||
"selector_kind": "public_alias_only",
|
||||
"check_mode_allowed": true,
|
||||
"runtime_write_allowed": false
|
||||
}
|
||||
],
|
||||
"required_dry_run_fields": [
|
||||
"dry_run_intent",
|
||||
"target_selector_aliases",
|
||||
"check_mode_plan_ref",
|
||||
"dry_run_evidence_ref",
|
||||
"dry_run_result_ref",
|
||||
"dry_run_result_state",
|
||||
"dry_run_redaction_attestation",
|
||||
"post_dry_run_verifier_ref",
|
||||
"rollback_revalidation_ref",
|
||||
"km_playbook_writeback_ref",
|
||||
"followup_owner",
|
||||
"audit_receipt_ref",
|
||||
"runtime_boundary_ack",
|
||||
"live_wazuh_query_boundary_ack",
|
||||
"host_write_boundary_ack",
|
||||
"secret_boundary_ack"
|
||||
],
|
||||
"dry_run_items": [
|
||||
{
|
||||
"item_id": "allowlisted_target_selector",
|
||||
"title": "Allowlisted public-alias target selector",
|
||||
"state_key": "allowlisted_target_selector_accepted",
|
||||
"accepted": true,
|
||||
"required_fields": [
|
||||
"target_selector_aliases"
|
||||
],
|
||||
"next_gate": "post-dry-run verifier readback before any runtime gate change"
|
||||
},
|
||||
{
|
||||
"item_id": "check_mode_plan",
|
||||
"title": "Check-mode plan reference",
|
||||
"state_key": "check_mode_plan_accepted",
|
||||
"accepted": true,
|
||||
"required_fields": [
|
||||
"check_mode_plan_ref"
|
||||
],
|
||||
"next_gate": "check-mode plan must remain redacted refs only"
|
||||
},
|
||||
{
|
||||
"item_id": "dry_run_evidence",
|
||||
"title": "Dry-run evidence and result refs",
|
||||
"state_key": "dry_run_evidence_accepted",
|
||||
"accepted": true,
|
||||
"required_fields": [
|
||||
"dry_run_evidence_ref",
|
||||
"dry_run_result_ref",
|
||||
"dry_run_result_state"
|
||||
],
|
||||
"next_gate": "dry-run evidence cannot include raw host output"
|
||||
},
|
||||
{
|
||||
"item_id": "redaction_attestation",
|
||||
"title": "Redaction attestation",
|
||||
"state_key": "redaction_attestation_accepted",
|
||||
"accepted": true,
|
||||
"required_fields": [
|
||||
"dry_run_redaction_attestation",
|
||||
"secret_boundary_ack",
|
||||
"live_wazuh_query_boundary_ack"
|
||||
],
|
||||
"next_gate": "raw output, secrets, live query and host writes remain rejected"
|
||||
},
|
||||
{
|
||||
"item_id": "post_dry_run_verifier",
|
||||
"title": "Post dry-run verifier",
|
||||
"state_key": "post_dry_run_verifier_accepted",
|
||||
"accepted": true,
|
||||
"required_fields": [
|
||||
"post_dry_run_verifier_ref"
|
||||
],
|
||||
"next_gate": "verifier readback must pass before runtime gate review can continue"
|
||||
},
|
||||
{
|
||||
"item_id": "rollback_and_writeback",
|
||||
"title": "Rollback revalidation and KM / PlayBook writeback",
|
||||
"state_key": "rollback_writeback_accepted",
|
||||
"accepted": true,
|
||||
"required_fields": [
|
||||
"rollback_revalidation_ref",
|
||||
"km_playbook_writeback_ref",
|
||||
"audit_receipt_ref"
|
||||
],
|
||||
"next_gate": "writeback receipt is required after verifier readback"
|
||||
}
|
||||
],
|
||||
"outcome_lanes": [
|
||||
"accepted_for_allowlisted_check_mode_dry_run_readback_only",
|
||||
"request_allowlisted_check_mode_dry_run_supplement",
|
||||
"request_target_selector_fix",
|
||||
"request_dry_run_intent_fix",
|
||||
"request_boundary_ack_fix",
|
||||
"quarantine_sensitive_payload",
|
||||
"reject_runtime_action_request"
|
||||
],
|
||||
"forbidden_payloads": [
|
||||
"secret_value",
|
||||
"token_value",
|
||||
"private_key",
|
||||
"cookie",
|
||||
"session",
|
||||
"authorization_header",
|
||||
"client.keys",
|
||||
"raw_wazuh_payload",
|
||||
"raw_agent_identity",
|
||||
"raw_hostname",
|
||||
"internal_ip",
|
||||
"full_cli_output",
|
||||
"full_journal",
|
||||
"raw_dashboard_request",
|
||||
"unredacted_screenshot",
|
||||
"private_namespace",
|
||||
"raw_env_file",
|
||||
"raw_runtime_volume"
|
||||
],
|
||||
"forbidden_actions": [
|
||||
"wazuh_api_live_query",
|
||||
"wazuh_active_response",
|
||||
"wazuh_agent_restart",
|
||||
"wazuh_agent_reenroll",
|
||||
"wazuh_manager_restart",
|
||||
"host_write",
|
||||
"systemd_restart",
|
||||
"docker_restart",
|
||||
"nginx_reload",
|
||||
"firewall_change",
|
||||
"kali_active_scan",
|
||||
"credentialed_scan",
|
||||
"exploit_attempt",
|
||||
"secret_rotation",
|
||||
"k8s_apply",
|
||||
"argocd_sync",
|
||||
"database_migration",
|
||||
"force_push",
|
||||
"repo_ref_delete",
|
||||
"workflow_trigger"
|
||||
],
|
||||
"execution_boundaries": {
|
||||
"active_scan_authorized": false,
|
||||
"alertmanager_reload_authorized": false,
|
||||
"auto_block_authorized": false,
|
||||
"credentialed_scan_authorized": false,
|
||||
"firewall_change_authorized": false,
|
||||
"host_write_authorized": false,
|
||||
"kali_execute_authorized": false,
|
||||
"kali_scan_authorized": false,
|
||||
"nginx_reload_authorized": false,
|
||||
"production_write_authorized": false,
|
||||
"runtime_execution_authorized": false,
|
||||
"runtime_gate_open": false,
|
||||
"secret_value_collection_allowed": false,
|
||||
"telegram_send_authorized": false,
|
||||
"wazuh_active_response_authorized": false,
|
||||
"wazuh_api_live_query_authorized": false,
|
||||
"not_authorization": true
|
||||
},
|
||||
"no_false_green_rules": [
|
||||
"Allowlisted check-mode dry-run staged does not open runtime gate.",
|
||||
"Dry-run evidence refs must be redacted and cannot include raw host output.",
|
||||
"Target selectors are public aliases only and do not authorize host writes.",
|
||||
"Dry-run readback does not authorize live Wazuh queries or active response.",
|
||||
"Post dry-run verifier and KM / PlayBook writeback must pass before any future runtime gate review continues."
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user