From c7740f5d1deff09ec12ea7ad66a5ef506c09cefb Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 19 Jun 2026 02:08:26 +0800 Subject: [PATCH] =?UTF-8?q?docs(security):=20=E7=B6=81=E5=AE=9A=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E5=87=BA=E5=8F=A3=E5=8F=AF=E8=AE=80=E6=80=A7=E9=A9=97?= =?UTF-8?q?=E6=94=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/LOGBOOK.md | 8 +++- .../HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md | 2 +- .../IWOOOS-CONFIG-CONTROL-INVENTORY.md | 2 +- .../SECURITY-SUPPLY-CHAIN-PROGRESS.md | 2 +- ...CATION-EGRESS-OWNER-RESPONSE-ACCEPTANCE.md | 7 +-- ...ss-owner-response-acceptance.snapshot.json | 43 +++++++++++++++++-- ...026-06-04-iwooos-security-governance-p0.md | 2 +- .../security-mirror-progress-guard.py | 13 ++++-- ...cation-egress-owner-response-acceptance.py | 6 +++ 9 files changed, 69 insertions(+), 16 deletions(-) diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 6722914b..dfb8defa 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -16,9 +16,14 @@ - test contract `10`。 - AI signal lane `6`:Wazuh、Kali、Nginx drift、backup / restore、provider freshness、supply-chain。 - Host resource lane `6`:orphan browser smoke、CI runner saturation、Prisma generate、build pressure、Node process、generic host pressure。 -- blocked raw output marker `12`,包含 process list、`checkpoint.prisma.io`、`node_modules`、`/workspace/wooo`、`/opt/hostedtoolcache`、raw Wazuh / Nginx path、內網 IP、token 與 raw Prisma JSON。 +- blocked raw output marker `12`,包含 process line、外部版本檢查 URL、套件樹路徑、workspace 路徑、runner toolcache 路徑、raw Wazuh / Nginx path、內網 IP、token-like 字串與 raw Prisma JSON 類別。 - runtime gate / action button / Telegram send / Bot API call 全部 `0`。 +**同段追加收斂**: +- `telegram_notification_egress_owner_response_acceptance_v1` 已新增 `message_readability_guard_ref`,每個 direct egress candidate 都固定指向 `docs/security/telegram-alert-readability-guard.snapshot.json`。 +- acceptance field 從 `32` 收斂為 `33`,reviewer check 從 `22` 收斂為 `23`。 +- Direct Bot API 遷移審查不得繞過告警卡片化、脫敏、`runtime_write_gate=0` 與 no-false-green;既有 direct Bot API convergence 仍維持 `0%`。 + **驗證**: - `TELEGRAM_ALERT_READABILITY_GUARD_OK tests=10 ai_lanes=6 host_lanes=6 runtime_gate=0`。 - `apps/api/tests/test_telegram_message_templates.py`:`72 passed`。 @@ -29,6 +34,7 @@ **完成度同步**: - Telegram 告警可讀性防退化 guard:`100%`。 - P0-6 Telegram 監控告警 / 通知出口治理:新增 readability guard slice `100%`。 +- Direct egress owner-response readability binding:`100%`。 - Direct Bot API convergence:仍 `0%`。 - Delivery receipt accepted:仍 `0%`。 - IwoooS headline:仍維持 `64%`。 diff --git a/docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md b/docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md index 900a806c..080eeeb7 100644 --- a/docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md +++ b/docs/security/HIGH-VALUE-CONFIG-CONTROL-COVERAGE.md @@ -56,7 +56,7 @@ 2026-06-19 再新增 `docs/security/TELEGRAM-NOTIFICATION-EGRESS-NO-NEW-BYPASS-GUARD.md` 與 `docs/security/telegram-notification-egress-no-new-bypass-guard.snapshot.json`,把既有 18 個 direct send 固定為 no-new-bypass baseline。固定 `guarded_method_count=9`、`current_direct_bot_api_call_count=18`、`new_bypass_count=0`、`sendDocument_call_count=0`、`sendPhoto_call_count=0`、`sendMediaGroup_call_count=0`、`runtime_gate_count=0`。這是 repo source 防新增旁路 guard,不代表既有 direct send 已收斂。 -同日再新增 `docs/security/TELEGRAM-NOTIFICATION-EGRESS-OWNER-RESPONSE-ACCEPTANCE.md` 與 `docs/security/telegram-notification-egress-owner-response-acceptance.snapshot.json`,把 11 份 direct egress 檔案轉成 owner response acceptance 候選。固定 `acceptance_candidate_count=11`、workflow `6`、ops script `4`、API direct `1`、`acceptance_field_count=32`、`required_owner_field_count=19`、`reviewer_check_count=22`、`outcome_lane_count=10`、`blocked_action_count=35`;owner response received / accepted、formatter convergence accepted、redaction contract accepted、delivery receipt accepted、migration authorized、workflow / script / API sender modification、Telegram send、Bot API call、secret collection、production write、runtime gate 與 action button 仍全部為 `0 / false`。 +同日再新增 `docs/security/TELEGRAM-NOTIFICATION-EGRESS-OWNER-RESPONSE-ACCEPTANCE.md` 與 `docs/security/telegram-notification-egress-owner-response-acceptance.snapshot.json`,把 11 份 direct egress 檔案轉成 owner response acceptance 候選。2026-06-19 已補 `message_readability_guard_ref`,固定指向 `docs/security/telegram-alert-readability-guard.snapshot.json`,避免 direct egress 遷移審查繞過告警卡片化、脫敏、`runtime_write_gate=0` 與 no-false-green。固定 `acceptance_candidate_count=11`、workflow `6`、ops script `4`、API direct `1`、`acceptance_field_count=33`、`required_owner_field_count=19`、`reviewer_check_count=23`、`outcome_lane_count=10`、`blocked_action_count=35`;owner response received / accepted、formatter convergence accepted、redaction contract accepted、delivery receipt accepted、migration authorized、workflow / script / API sender modification、Telegram send、Bot API call、secret collection、production write、runtime gate 與 action button 仍全部為 `0 / false`。 同日再新增 `docs/security/TELEGRAM-ALERT-READABILITY-GUARD.md`、`docs/security/telegram-alert-readability-guard.snapshot.json` 與 `scripts/security/telegram-alert-readability-guard.py`,把 Telegram 告警最後出口可讀性固定成可重跑 guard。固定 `source_formatter_marker_count=11`、`final_exit_contract_count=3`、`test_contract_count=10`、`ai_signal_lane_count=6`、`host_resource_lane_count=6`、`blocked_raw_output_marker_count=12`、`required_output_marker_count=6`。此更新鎖住 Host CPU / root Node.js / Prisma / Next build、Wazuh、Kali、Nginx drift、backup / restore、provider freshness 與 supply-chain 類訊號必須轉成 AI 事件卡,且不得把 process list、raw JSON、內網 IP、完整路徑、URL、token 或 raw Wazuh / Nginx path 直接送進 Telegram;但 Telegram send、Bot API call、delivery receipt、direct egress migration、workflow / script / API sender 修改、production write、runtime gate 與 action button 仍全部為 `0 / false`。 diff --git a/docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md b/docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md index d9ee0b4d..233c0dee 100644 --- a/docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md +++ b/docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md @@ -95,7 +95,7 @@ 2026-06-19 再新增 `telegram_notification_egress_no_new_bypass_guard_v1`,將既有 18 個 direct send 固定成 baseline signature,並掃描 `sendMessage`、`sendDocument`、`sendPhoto`、`sendMediaGroup`、`editMessageText`、`sendAnimation`、`sendVideo`、`sendAudio`、`sendVoice` 等 9 類 Bot API method。固定 `baseline_signature_count=18`、`current_direct_bot_api_call_count=18`、`new_bypass_count=0`、`sendDocument_call_count=0`、`runtime_gate_count=0`。此更新只代表 repo source 目前沒有新增未登記 Telegram 直送旁路;既有 18 個 direct send 仍未遷移,owner response、migration authorized、workflow / script modification、API sender refactor、Telegram send、Bot API call、secret collection、raw payload storage、production write、runtime gate 仍全部為 `0 / false`。 -同日再新增 `telegram_notification_egress_owner_response_acceptance_v1`,把 11 份 owner request draft 與 11 份 migration candidate 轉成 owner response acceptance 帳本。固定 `acceptance_candidate_count=11`、workflow `6`、ops script `4`、API direct `1`、`acceptance_field_count=32`、`required_owner_field_count=19`、`reviewer_check_count=22`、`outcome_lane_count=10`、`forbidden_payload_count=14`、`blocked_action_count=35`。owner response received / accepted / rejected / quarantined、supplement requested、formatter convergence accepted、redaction contract accepted、delivery receipt accepted、break-glass fallback accepted、maintenance / rollback / postcheck accepted、migration authorized、workflow / script / API sender modification、Telegram send、Bot API call、workflow dispatch、production deploy、secret collection、raw payload storage、runtime gate 仍全部為 `0 / false`。 +同日再新增 `telegram_notification_egress_owner_response_acceptance_v1`,把 11 份 owner request draft 與 11 份 migration candidate 轉成 owner response acceptance 帳本。2026-06-19 已補 `message_readability_guard_ref`,固定指向 `docs/security/telegram-alert-readability-guard.snapshot.json`,讓每個 direct egress candidate 都必須帶告警可讀性、脫敏、`runtime_write_gate=0` 與 no-false-green guard ref。固定 `acceptance_candidate_count=11`、workflow `6`、ops script `4`、API direct `1`、`acceptance_field_count=33`、`required_owner_field_count=19`、`reviewer_check_count=23`、`outcome_lane_count=10`、`forbidden_payload_count=14`、`blocked_action_count=35`。owner response received / accepted / rejected / quarantined、supplement requested、formatter convergence accepted、redaction contract accepted、delivery receipt accepted、break-glass fallback accepted、maintenance / rollback / postcheck accepted、migration authorized、workflow / script / API sender modification、Telegram send、Bot API call、workflow dispatch、production deploy、secret collection、raw payload storage、runtime gate 仍全部為 `0 / false`。 同日再新增 `telegram_alert_readability_guard_v1`,把 Telegram 告警最後出口可讀性納入高價值配置控管。固定 `source_formatter_marker_count=11`、`final_exit_contract_count=3`、`test_contract_count=10`、`ai_signal_lane_count=6`、`host_resource_lane_count=6`、`blocked_raw_output_marker_count=12`、`required_output_marker_count=6`,並由 `security-mirror-progress-guard.py` 直接呼叫。此 guard 確認 `_send_request()`、`send_alert_notification()` 與 `send_text()` 都會套用 normalizer,且 Prisma / root Node.js / Next build / Wazuh / Kali / Nginx drift 等告警只能變成脫敏 AI 事件卡;Telegram 實發、Bot API call、delivery receipt、direct egress migration、workflow / script / API sender 修改、production write、runtime gate 仍全部為 `0 / false`。 diff --git a/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md b/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md index d0741da0..97feadce 100644 --- a/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md +++ b/docs/security/SECURITY-SUPPLY-CHAIN-PROGRESS.md @@ -110,7 +110,7 @@ 本輪新增 `telegram_notification_egress_no_new_bypass_guard_v1`,把既有 18 個 direct send 固定成 no-new-bypass baseline,並把 `sendDocument`、`sendPhoto`、`sendMediaGroup`、`editMessageText` 等附件 / 編輯型 Bot API method 一併納入 repo source guard。固定 `current_direct_bot_api_call_count=18`、`guarded_method_count=9`、`new_bypass_count=0`、`sendDocument_call_count=0`、`removed_baseline_call_count=0`、`runtime_gate_count=0`。 -同步新增 `telegram_notification_egress_owner_response_acceptance_v1`,把 11 個 direct egress 檔案轉成 reviewer 可驗收的 owner response acceptance 候選。固定 `acceptance_candidate_count=11`、workflow `6`、ops script `4`、API direct `1`、`acceptance_field_count=32`、`required_owner_field_count=19`、`reviewer_check_count=22`、`outcome_lane_count=10`、`forbidden_payload_count=14`、`blocked_action_count=35`。 +同步新增 `telegram_notification_egress_owner_response_acceptance_v1`,把 11 個 direct egress 檔案轉成 reviewer 可驗收的 owner response acceptance 候選。2026-06-19 已補 `message_readability_guard_ref=docs/security/telegram-alert-readability-guard.snapshot.json`,讓 direct egress 遷移審查必須同時引用告警可讀性、脫敏、`runtime_write_gate=0` 與 no-false-green guard。固定 `acceptance_candidate_count=11`、workflow `6`、ops script `4`、API direct `1`、`acceptance_field_count=33`、`required_owner_field_count=19`、`reviewer_check_count=23`、`outcome_lane_count=10`、`forbidden_payload_count=14`、`blocked_action_count=35`。 同步邊界:IwoooS headline 維持 `64%`,active runtime gate 維持 `0`;既有 direct Bot API 收斂仍為 `0%`,owner response received / accepted、migration authorized、workflow / script / API sender modification、Telegram send、Bot API call、workflow dispatch、production deploy、secret value collection、raw payload storage、runtime gate 與 action buttons 全部仍為 `0 / false`。本段只更新文件、snapshot 與 guard,不送 Telegram、不讀 Bot token、不改 workflow、不改 host、不 dispatch workflow、不觸發部署。 diff --git a/docs/security/TELEGRAM-NOTIFICATION-EGRESS-OWNER-RESPONSE-ACCEPTANCE.md b/docs/security/TELEGRAM-NOTIFICATION-EGRESS-OWNER-RESPONSE-ACCEPTANCE.md index 4d6d723b..169f6d76 100644 --- a/docs/security/TELEGRAM-NOTIFICATION-EGRESS-OWNER-RESPONSE-ACCEPTANCE.md +++ b/docs/security/TELEGRAM-NOTIFICATION-EGRESS-OWNER-RESPONSE-ACCEPTANCE.md @@ -27,9 +27,9 @@ | `workflow_acceptance_candidate_count` | `6` | Gitea workflow 類 | | `ops_script_acceptance_candidate_count` | `4` | Ops script 類 | | `api_direct_acceptance_candidate_count` | `1` | API direct sender 類 | -| `acceptance_field_count` | `32` | 每個 candidate 的驗收欄位 | +| `acceptance_field_count` | `33` | 每個 candidate 的驗收欄位 | | `required_owner_field_count` | `19` | owner response 必填欄位 | -| `reviewer_check_count` | `22` | reviewer 必檢規則 | +| `reviewer_check_count` | `23` | reviewer 必檢規則 | | `outcome_lane_count` | `10` | 收件結果分流 | | `forbidden_payload_count` | `14` | 禁止出現在回覆中的 payload 類型 | | `blocked_action_count` | `35` | 帳本階段禁止動作 | @@ -43,7 +43,8 @@ Reviewer 必須確認: - source owner request draft 與 migration plan 都是目前版本。 - owner identity、decision、decision reason、affected scope 與 followup owner 完整。 - 所有 evidence refs 都是脫敏 metadata,不包含 secret value、hash、partial token、raw message payload 或 raw workflow log。 -- message shape contract、redaction contract、formatter convergence、gateway / Alertmanager target、break-glass fallback、delivery receipt、dedup / fingerprint、maintenance window、rollback owner 與 postcheck evidence 都明確存在。 +- message shape contract、`message_readability_guard_ref`、redaction contract、formatter convergence、gateway / Alertmanager target、break-glass fallback、delivery receipt、dedup / fingerprint、maintenance window、rollback owner 與 postcheck evidence 都明確存在。 +- `message_readability_guard_ref` 必須固定指向 `docs/security/telegram-alert-readability-guard.snapshot.json`,確保 direct egress 遷移審查不能繞過告警卡片化、脫敏、`runtime_write_gate=0` 與 no-false-green。 - `no_secret_value_attestation`、`no_raw_payload_attestation`、`no_false_green_attestation` 都存在。 - migration authorization 與 runtime approval 必須分離;此帳本不能直接批准 workflow / script / API sender 修改。 - runtime gate 維持 `0`。 diff --git a/docs/security/telegram-notification-egress-owner-response-acceptance.snapshot.json b/docs/security/telegram-notification-egress-owner-response-acceptance.snapshot.json index 52cba7b8..66c337d6 100644 --- a/docs/security/telegram-notification-egress-owner-response-acceptance.snapshot.json +++ b/docs/security/telegram-notification-egress-owner-response-acceptance.snapshot.json @@ -1,7 +1,7 @@ { "schema_version": "telegram_notification_egress_owner_response_acceptance_v1", - "generated_at": "2026-06-19T09:45:00+08:00", - "git_commit": "4d0150e1", + "generated_at": "2026-06-19T02:05:13+08:00", + "git_commit": "1eaa51e6", "status": "owner_response_acceptance_ledger_ready_no_runtime_action", "mode": "metadata_only_no_secret_value_no_telegram_send_no_workflow_script_api_change", "source_owner_request_snapshot": "docs/security/telegram-notification-egress-owner-request-draft.snapshot.json", @@ -10,6 +10,7 @@ "source_migration_plan_snapshot": "docs/security/telegram-notification-egress-migration-plan-draft.snapshot.json", "source_migration_plan_schema_version": "telegram_notification_egress_migration_plan_draft_v1", "source_migration_plan_status": "migration_plan_draft_ready_no_runtime_action", + "message_readability_guard_snapshot": "docs/security/telegram-alert-readability-guard.snapshot.json", "summary": { "source_request_draft_count": 11, "source_migration_candidate_count": 11, @@ -18,9 +19,9 @@ "workflow_acceptance_candidate_count": 6, "ops_script_acceptance_candidate_count": 4, "api_direct_acceptance_candidate_count": 1, - "acceptance_field_count": 32, + "acceptance_field_count": 33, "required_owner_field_count": 19, - "reviewer_check_count": 22, + "reviewer_check_count": 23, "outcome_lane_count": 10, "forbidden_payload_count": 14, "blocked_action_count": 35, @@ -102,6 +103,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -134,6 +136,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -183,6 +186,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -326,6 +330,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -358,6 +363,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -407,6 +413,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -544,6 +551,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -576,6 +584,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -625,6 +634,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -760,6 +770,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -792,6 +803,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -841,6 +853,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -976,6 +989,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -1008,6 +1022,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -1057,6 +1072,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -1192,6 +1208,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -1224,6 +1241,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -1273,6 +1291,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -1408,6 +1427,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -1440,6 +1460,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -1489,6 +1510,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -1624,6 +1646,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -1656,6 +1679,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -1705,6 +1729,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -1840,6 +1865,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -1872,6 +1898,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -1921,6 +1948,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -2056,6 +2084,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -2088,6 +2117,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -2137,6 +2167,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -2272,6 +2303,7 @@ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": null, + "message_readability_guard_ref": "docs/security/telegram-alert-readability-guard.snapshot.json", "redaction_contract_ref": null, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -2304,6 +2336,7 @@ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -2353,6 +2386,7 @@ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -2467,6 +2501,7 @@ ], "operator_interpretation": [ "此帳本只是 reviewer 驗收模板;owner response received / accepted 仍維持 0。", + "每個 direct egress candidate 都必須引用 Telegram 告警可讀性 guard,migration review 不得繞過卡片化、脫敏與 runtime_write_gate=0。", "CD success、route 200、UI 可見或 Telegram sent 狀態本身都不是 delivery receipt。", "workflow、script 與 API sender 收斂仍需獨立 runtime approval 與 change evidence。" ] diff --git a/docs/workplans/2026-06-04-iwooos-security-governance-p0.md b/docs/workplans/2026-06-04-iwooos-security-governance-p0.md index 16a000ed..b4a8bc0d 100644 --- a/docs/workplans/2026-06-04-iwooos-security-governance-p0.md +++ b/docs/workplans/2026-06-04-iwooos-security-governance-p0.md @@ -84,7 +84,7 @@ | P0-3 | AwoooP 同步封包 | 100% | 已送至 AwoooP 平行工作 thread `019e9154-7d5e-7b72-85be-c9d97e43ecc9`;後續仍需每次推版前重新 fetch / fast-forward | 本文件、thread send readback、mirror checklist readback | | P0-4 | production live sanity 節點 | 100% | desktop / mobile / 展開區塊 / overflow / action href 檢查已完成 | Playwright production sanity 通過 | | P0-5 | LOGBOOK 與完成度更新 | 100% | D2 comments-only、D2 AIOps sample、D2 Code Review 候選分類與 D2 AwoooP Runs fallback 皆已回填;可見 / bundle 變更皆已補 local / production desktop + mobile smoke | `docs/LOGBOOK.md` readback | -| P0-6 | Telegram 監控告警 / 通知出口治理 | outbound 主鏈路 100%;靜音 / recurrence slice 88%;通知出口清冊 100%;owner request draft 100%;migration plan draft 100%;防新增旁路 guard 100%;owner response acceptance 100%;告警可讀性防退化 guard 100%;direct Bot API convergence 0% | Alertmanager 缺 project context、既有 approval 收斂告警靜音、AI 分析中重複告警靜音皆已修復並正式 smoke;`TelegramGateway` final-exit formatter 已完成 host / multi-signal 卡片化;direct Bot API egress inventory 固定 workflow 13、ops script 4、API direct 1,並聚成 11 份 owner request 草稿與 3 個遷移波次;no-new-bypass guard 已覆蓋 `sendMessage` / `sendDocument` / `sendPhoto` / `sendMediaGroup` / `editMessageText` 等 9 類 Bot API method;本輪新增 readability guard,鎖住 Prisma / root Node.js / Next build / Wazuh / Kali / Nginx drift 等告警必須轉成脫敏 AI 事件卡,不能把 process list、raw JSON、URL、內網 IP、完整路徑或 token 直接送到 Telegram;後續需 owner response 後分批收斂,不得把 API formatter、防新增 guard 或 readability guard 完成誤判成既有旁路已收斂或 delivery receipt 已完成 | API health、Telegram health、API pod Alertmanager smoke、production logs `converged_alert_recurrence_sent`、`telegram-notification-egress-inventory.snapshot.json`、`telegram-notification-egress-owner-request-draft.snapshot.json`、`telegram-notification-egress-migration-plan-draft.snapshot.json`、`telegram-notification-egress-no-new-bypass-guard.snapshot.json`、`telegram-notification-egress-owner-response-acceptance.snapshot.json`、`telegram-alert-readability-guard.snapshot.json` | +| P0-6 | Telegram 監控告警 / 通知出口治理 | outbound 主鏈路 100%;靜音 / recurrence slice 88%;通知出口清冊 100%;owner request draft 100%;migration plan draft 100%;防新增旁路 guard 100%;owner response acceptance 100%;告警可讀性防退化 guard 100%;direct Bot API convergence 0% | Alertmanager 缺 project context、既有 approval 收斂告警靜音、AI 分析中重複告警靜音皆已修復並正式 smoke;`TelegramGateway` final-exit formatter 已完成 host / multi-signal 卡片化;direct Bot API egress inventory 固定 workflow 13、ops script 4、API direct 1,並聚成 11 份 owner request 草稿與 3 個遷移波次;no-new-bypass guard 已覆蓋 `sendMessage` / `sendDocument` / `sendPhoto` / `sendMediaGroup` / `editMessageText` 等 9 類 Bot API method;本輪新增 readability guard,鎖住 Prisma / root Node.js / Next build / Wazuh / Kali / Nginx drift 等告警必須轉成脫敏 AI 事件卡,不能把 process list、raw JSON、URL、內網 IP、完整路徑或 token 直接送到 Telegram;owner response acceptance 已補 `message_readability_guard_ref=docs/security/telegram-alert-readability-guard.snapshot.json`,後續 direct egress 遷移審查不得繞過卡片化、脫敏、`runtime_write_gate=0` 與 no-false-green;後續需 owner response 後分批收斂,不得把 API formatter、防新增 guard 或 readability guard 完成誤判成既有旁路已收斂或 delivery receipt 已完成 | API health、Telegram health、API pod Alertmanager smoke、production logs `converged_alert_recurrence_sent`、`telegram-notification-egress-inventory.snapshot.json`、`telegram-notification-egress-owner-request-draft.snapshot.json`、`telegram-notification-egress-migration-plan-draft.snapshot.json`、`telegram-notification-egress-no-new-bypass-guard.snapshot.json`、`telegram-notification-egress-owner-response-acceptance.snapshot.json`、`telegram-alert-readability-guard.snapshot.json` | | P0-7 | Telegram 批准後執行真相鏈止血 | 100% | no-action approval 不再顯示批准 / 執行中;可執行修復 approval 會寫入 `auto_repair_executions`、KM 與 verifier;下一步補 MCP evidence / PlayBook trust 產生真正修復候選 | 目標 pytest `125 passed`、py_compile、guard、production health、API / worker rollout、production pod classifier readback | | P0-8 | Telegram no-action 人工處置包與操作入口 | 100% | no-action 卡片已新增人工處置包、證據補齊清單、AwoooP 修復候選建立步驟、verifier / KM / PlayBook 回寫提醒,並改成 `處置包`、`重診`、`歷史`、`靜默`、`真相鏈`、`Runs` 鍵盤;舊訊息不 retroactive 改寫 | 目標 pytest `64 passed + 44 passed`、py_compile、guard、production health、API / worker rollout、production pod render / keyboard smoke | | P0-9 | MCP evidence -> PlayBook 修復候選產生 | D5 `88%`;Approvals ledger `100%`;Runs ledger desktop `100%`;Alerts ledger desktop / mobile `100%` | 已補 webhook fallback 先建立 incident,再收 MCP evidence、查 approved PlayBook、檢查 trust / command safety、產生 medium approval candidate 與 verifier plan;D1 追加通用兜底 PlayBook / 診斷型命令不可誤當修復、阻擋理由繁中化;D2 在缺候選時產生 `repair_candidate_draft_package_v1`、`playbook_draft_required`、下一步與必填欄位;D3 新增 `awooop_repair_candidate_draft_work_item_v1` read-only projection 與 Telegram `工作項目` deeplink;D4 讓 AwoooP Work Items 詳細呈現 PlayBook 草案處置板、必填欄位、阻擋原因、下一步、Runs / 審批連結;D5 新增 `repair_candidate_coverage_gap_v1`,讓 blocked result 帶出 coverage key、target kind、blocking stage、必收 MCP evidence refs、PlayBook template fields 與 runtime 0 / false 邊界;Approvals / Runs / Alerts 已新增 `資產沉澱` 欄或焦點矩陣,可直接看到 KM / PlayBook / 腳本 / 排程 / Verifier 的完成與卡點;下一步要補 Runs mobile smoke,並把同一總帳接到正式 Telegram 告警卡、Observability 與 Tenants,用真實告警驗證 approval -> execution -> verifier -> KM / PlayBook 回寫 | Approvals code `dafe5342` 已隨 deploy marker `42c08ece` 正式站 desktop / mobile smoke;Runs code `11c2b5d4` 已隨 deploy marker `8b6ab87c` 正式站 desktop DOM smoke;Alerts code `10cd6167` 已隨 deploy marker `d36d764a` 正式站 desktop / mobile DOM smoke;P2-407 API production readback `overall_completion_percent=100`;status-chain 後續仍必須看到 tool call、PlayBook id、risk gate、repair candidate、verifier plan | diff --git a/scripts/security/security-mirror-progress-guard.py b/scripts/security/security-mirror-progress-guard.py index d9456cb3..b82b5d1a 100755 --- a/scripts/security/security-mirror-progress-guard.py +++ b/scripts/security/security-mirror-progress-guard.py @@ -22006,9 +22006,9 @@ def validate(root: Path) -> None: "workflow_acceptance_candidate_count": 6, "ops_script_acceptance_candidate_count": 4, "api_direct_acceptance_candidate_count": 1, - "acceptance_field_count": 32, + "acceptance_field_count": 33, "required_owner_field_count": 19, - "reviewer_check_count": 22, + "reviewer_check_count": 23, "outcome_lane_count": 10, "forbidden_payload_count": 14, "blocked_action_count": 35, @@ -22069,7 +22069,7 @@ def validate(root: Path) -> None: assert_equal( f"telegram_notification_egress_owner_response_acceptance.{item['acceptance_candidate_id']}.acceptance_fields", len(item["acceptance_fields"]), - 32, + 33, ) assert_equal( f"telegram_notification_egress_owner_response_acceptance.{item['acceptance_candidate_id']}.required_owner_fields", @@ -22079,7 +22079,12 @@ def validate(root: Path) -> None: assert_equal( f"telegram_notification_egress_owner_response_acceptance.{item['acceptance_candidate_id']}.reviewer_checks", len(item["reviewer_checks"]), - 22, + 23, + ) + assert_equal( + f"telegram_notification_egress_owner_response_acceptance.{item['acceptance_candidate_id']}.message_readability_guard_ref", + item.get("message_readability_guard_ref"), + "docs/security/telegram-alert-readability-guard.snapshot.json", ) assert_equal( f"telegram_notification_egress_owner_response_acceptance.{item['acceptance_candidate_id']}.outcome_lanes", diff --git a/scripts/security/telegram-notification-egress-owner-response-acceptance.py b/scripts/security/telegram-notification-egress-owner-response-acceptance.py index 345baedb..ad0ada54 100644 --- a/scripts/security/telegram-notification-egress-owner-response-acceptance.py +++ b/scripts/security/telegram-notification-egress-owner-response-acceptance.py @@ -21,6 +21,7 @@ TAIPEI = timezone(timedelta(hours=8)) OWNER_REQUEST_SNAPSHOT = Path("docs/security/telegram-notification-egress-owner-request-draft.snapshot.json") MIGRATION_PLAN_SNAPSHOT = Path("docs/security/telegram-notification-egress-migration-plan-draft.snapshot.json") +MESSAGE_READABILITY_GUARD_SNAPSHOT = Path("docs/security/telegram-alert-readability-guard.snapshot.json") ACCEPTANCE_FIELDS = [ "acceptance_candidate_id", @@ -38,6 +39,7 @@ ACCEPTANCE_FIELDS = [ "affected_scope", "redacted_evidence_refs", "message_shape_contract_ref", + "message_readability_guard_ref", "redaction_contract_ref", "formatter_convergence_decision", "gateway_or_alertmanager_target", @@ -67,6 +69,7 @@ REVIEWER_CHECKS = [ "no_secret_or_token_value", "no_raw_message_payload", "message_shape_contract_present", + "message_readability_guard_present", "redaction_contract_present", "formatter_convergence_explicit", "gateway_or_alertmanager_target_valid", @@ -190,6 +193,7 @@ def build_candidate(request: dict[str, Any], migration: dict[str, Any]) -> dict[ "affected_scope": "pending_owner_response", "redacted_evidence_refs": [], "message_shape_contract_ref": None, + "message_readability_guard_ref": MESSAGE_READABILITY_GUARD_SNAPSHOT.as_posix(), "redaction_contract_ref": None, "formatter_convergence_decision": "pending_owner_response", "gateway_or_alertmanager_target": "pending_owner_response", @@ -274,6 +278,7 @@ def build_report(root: Path, generated_at: str | None = None) -> dict[str, Any]: "source_migration_plan_snapshot": MIGRATION_PLAN_SNAPSHOT.as_posix(), "source_migration_plan_schema_version": migration_plan["schema_version"], "source_migration_plan_status": migration_plan["status"], + "message_readability_guard_snapshot": MESSAGE_READABILITY_GUARD_SNAPSHOT.as_posix(), "summary": { "source_request_draft_count": owner_request["summary"]["request_draft_count"], "source_migration_candidate_count": migration_plan["summary"]["migration_candidate_count"], @@ -340,6 +345,7 @@ def build_report(root: Path, generated_at: str | None = None) -> dict[str, Any]: "acceptance_candidates": candidates, "operator_interpretation": [ "此帳本只是 reviewer 驗收模板;owner response received / accepted 仍維持 0。", + "每個 direct egress candidate 都必須引用 Telegram 告警可讀性 guard,migration review 不得繞過卡片化、脫敏與 runtime_write_gate=0。", "CD success、route 200、UI 可見或 Telegram sent 狀態本身都不是 delivery receipt。", "workflow、script 與 API sender 收斂仍需獨立 runtime approval 與 change evidence。", ],