# IwoooS Public Gateway / Nginx 事故後回讀計畫 | 項目 | 內容 | |------|------| | 日期 | 2026-06-15 | | 狀態 | `post_incident_readback_plan_ready_no_runtime_action` | | 工具 | `scripts/security/public-gateway-post-incident-readback-plan.py` | | 輸入 | `docs/security/public-gateway-rendered-diff-acceptance.snapshot.json` | | Snapshot | `docs/security/public-gateway-post-incident-readback-plan.snapshot.json` | | runtime gate | `0` | ## 1. 目的 Nginx public gateway 是公開網站、API、Webhook、WebSocket、TLS、ACME 與 AI provider proxy 的共同入口。若 live Nginx conf 被手動或緊急變更,IwoooS 不能只看 route `200`、Nginx active、dashboard up、CD success 或 UI 可見就判定事故已驗收。 本文件補上事故後回讀計畫:未來若發生 gateway / Nginx 變更或事故,必須用脫敏 evidence ref 回填 actor、時間窗、變更意圖或 break-glass、改前改後 route 狀態、source-to-live diff、`nginx -t` readback、reload / no-reload 判定、route smoke、TLS / ACME、WebSocket、upstream、AI provider、monitoring、跨專案同步、回滾、防再發與 no-false-green attestation。 這個計畫不是 live conf received、不是 rendered diff accepted、不是 `nginx -t` 授權、不是 Nginx reload、不是 route smoke、不是 DNS / TLS probe、不是 certbot renew、不是 host write,也不是 production write 或 runtime gate。 ## 2. 摘要 | 指標 | 值 | 說明 | |------|----|------| | readback candidate count | `3` | 對應三份 public gateway config | | C0 readback candidate count | `2` | 188 all sites、188 internal tools HTTPS | | C1 readback candidate count | `1` | 110 Ollama proxy | | readback field count | `36` | 每份事故後回讀欄位 | | required readback field count | `30` | 未來 owner evidence 必填欄位 | | reviewer check count | `28` | 補件、隔離、拒收、review 與 no-false-green 檢查 | | outcome lane count | `10` | 從等待回讀包到等待 runtime gate | | blocked action count | `41` | 不可直接執行或不可誤讀的動作 | | post-incident readback received / accepted | `0 / 0` | 尚未收到 / 驗收 | | nginx test / reload / route smoke authorized | `0 / 0 / 0` | 尚未授權且未執行 | | runtime gate / action button | `0 / 0` | 未開啟 | | coverage after readback plan | `92%` | 只代表只讀控管成熟度,不代表可 reload | ## 3. Readback 欄位 | 欄位 | 內容規則 | |------|----------| | `gateway_incident_or_change_ref` | incident、change、ticket 或 maintenance ref | | `actor_attribution_ref` | actor role / team,不接受匿名操作 | | `change_time_window_ref` | 變更 / 事故時間窗 | | `change_intent_or_break_glass_ref` | change intent 或 break-glass reason;break-glass 不等於事前批准 | | `before_route_state_ref` | 改前 route / upstream / TLS / WebSocket 摘要 ref | | `after_route_state_ref` | 改後 route / upstream / TLS / WebSocket 摘要 ref | | `source_live_diff_state_ref` | source-to-live diff 狀態 ref,不保存 raw conf 或完整 diff | | `nginx_test_readback_ref` | owner-provided `nginx -t` readback ref;本工具不得執行 | | `nginx_reload_or_no_reload_ref` | 是否 reload 與原因 ref | | `route_smoke_readback_ref` | affected routes、status、TLS、WebSocket、ACME 或不適用原因 | | `tls_acme_readback_ref` | TLS / ACME impact ref | | `websocket_readback_ref` | WebSocket / streaming route impact ref | | `upstream_health_ref` | upstream health、port、dependency impact ref | | `public_admin_api_route_impact_ref` | public / admin / API / callback / webhook 影響 ref | | `ai_provider_impact_ref` | Ollama、AI provider、model route 或 proxy 影響 ref | | `monitoring_alert_ref` | monitoring、alert、incident 或 dashboard ref | | `operator_notification_ref` | 已通知受影響產品 / owner / Session 的脫敏 ref | | `cross_project_sync_ref` | 跨專案同步 ref | | `rollback_validation_ref` | rollback owner 與回滾後驗證 ref | | `post_change_monitoring_ref` | post-change monitoring window ref | | `recovery_or_still_degraded_ref` | 已恢復或仍 degraded 的狀態 ref | | `postcheck_readback_ref` | 獨立 post-check readback ref | | `recurrence_guard_ref` | 防再發 guard、change freeze、owner review 或 automation block | | `maintenance_window` | 後續 runtime action 的維護窗口或明確禁止窗口 | | `rollback_owner` | rollback owner / team | | `followup_owner` | 補件或下一階段 owner | | `not_approval` | 必須為 `true` | ## 4. Reviewer Checks | Check | 規則 | |-------|------| | `source_diff_acceptance_current` | 來源 rendered diff acceptance snapshot 必須是目前版本 | | `incident_or_change_ref_present` | 必須有 incident / change ref | | `actor_attribution_present` | 必須標示 actor role / team | | `change_time_window_present` | 必須有變更 / 事故時間窗 | | `intent_or_break_glass_present` | 必須有 intent 或 break-glass reason | | `before_after_route_state_present` | 必須有 before / after route state | | `source_live_diff_state_present` | 必須有 source-to-live diff 狀態 | | `nginx_test_readback_is_owner_provided` | `nginx -t` 只能是 owner-provided readback | | `reload_or_no_reload_called_out` | 必須說明是否 reload | | `route_smoke_readback_present` | 必須列 route smoke 或不適用原因 | | `tls_acme_readback_present` | TLS / ACME 不可被 route 200 取代 | | `websocket_readback_present` | WebSocket / streaming route 需獨立回讀 | | `upstream_health_present` | upstream health / port / dependency 影響必須列 ref | | `public_admin_api_route_impact_present` | public / admin / API route 影響需列 ref | | `ai_provider_impact_present` | AI provider / proxy 影響需列 ref | | `monitoring_alert_present` | 需有 monitoring / alert / incident ref | | `operator_notification_present` | 需有通知 ref | | `cross_project_sync_present` | 需有跨專案同步 ref | | `rollback_validation_present` | 需有 rollback validation ref | | `post_change_monitoring_present` | 需有變更後監控窗口 | | `recovery_or_still_degraded_present` | 需說明恢復或仍 degraded | | `postcheck_independent` | post-check 必須獨立於原操作人與 UI | | `recurrence_guard_present` | 需有防再發措施 | | `maintenance_window_present` | 後續 runtime action 需有維護窗口 | | `no_false_green` | 不得把 route 200、Nginx active、dashboard up、CD success 或 UI 可見當驗收 | | `raw_payload_absent` | 不得保存 raw conf、完整 diff、private key、憑證內容、cookie、token 或未脫敏截圖 | | `runtime_stays_zero` | 不得觸發 `nginx -t`、reload、route smoke、DNS / TLS probe、certbot renew 或 host write | | `counts_transition_safe` | accepted count 只能由 reviewer record 更新,且不得同時開 runtime gate | ## 5. Outcome Lanes | Lane | 意義 | |------|------| | `waiting_post_incident_readback` | 尚未收到事故回讀包 | | `request_actor_or_time_supplement` | 缺 actor、時間窗、intent 或 break-glass reason | | `request_route_state_supplement` | 缺 before / after route、upstream、WebSocket、TLS / ACME 或 route smoke | | `request_diff_test_supplement` | 缺 source-live diff、`nginx -t` readback、reload / no-reload 或 rollback validation | | `request_dependency_supplement` | 缺 AI provider、monitoring、public/admin/API route 或跨專案影響 | | `quarantine_raw_payload` | raw conf、完整 diff、secret、憑證、cookie、token 或未脫敏截圖只能隔離 | | `reject_false_green_claim` | route 200、Nginx active、dashboard up、CD success 或 UI 可見不能當驗收 | | `ready_for_gateway_post_incident_review` | metadata 合格後進 reviewer review | | `recurrence_guard_backfill_required` | 需補防再發 guard | | `waiting_runtime_gate` | 即使 readback accepted,runtime gate 仍需獨立人工批准 | ## 6. Blocked Actions | Action | 邊界 | |--------|------| | `ssh_read_live_nginx_conf` | 未授權不得讀 live Nginx conf | | `store_raw_live_conf` | 不得保存 raw live conf | | `store_full_rendered_diff_payload` | 不得保存完整 diff payload | | `collect_secret_value` | 不得收 secret value | | `collect_private_key` | 不得收 private key | | `collect_certificate_body` | 不得收完整憑證內容 | | `run_nginx_test` | 不得由本計畫執行 `nginx -t` | | `reload_nginx` / `restart_nginx` | 不得由本計畫執行 | | `change_public_route` / `change_admin_route` / `change_api_route` | 不得改 route | | `change_websocket_route` / `change_acme_challenge_route` / `change_upstream` | 不得改路由、ACME 或 upstream | | `change_dns_record` / `tls_probe` / `dns_probe` / `certbot_renew` | 不得改 DNS / TLS 或 renew cert | | `route_smoke` / `websocket_smoke` | 不得由本計畫執行 smoke | | `host_write` / `firewall_change` / `docker_restart` / `systemd_restart` | 不得寫主機或重啟 | | `accept_route_200_as_all_green` / `accept_nginx_active_as_all_green` | 不得假性驗收 | | `mark_readback_accepted_without_reviewer_record` | 不得跳過 reviewer record | | `open_runtime_gate` / `add_action_button` | 不得開執行閘門或按鈕 | ## 7. 指令 產生 committed snapshot: ```bash python3 scripts/security/public-gateway-post-incident-readback-plan.py \ --root . \ --source-report docs/security/public-gateway-rendered-diff-acceptance.snapshot.json \ --output docs/security/public-gateway-post-incident-readback-plan.snapshot.json \ --generated-at 2026-06-15T22:10:00+08:00 ``` 集中驗證 guard: ```bash python3 scripts/security/security-mirror-progress-guard.py --root . ``` ## 8. 完成度 | 工作 | 完成度 | 說明 | |------|--------|------| | Public Gateway / Nginx post-incident readback plan | `100%` | 產生器、snapshot 與文件已固定 | | post-incident readback received / accepted | `0%` | 尚未收到 / 接受 | | nginx test / reload / route smoke | `0%` | 未授權且未執行 | | DNS / TLS / certbot | `0%` | 未授權且未執行 | | runtime reload / host write | `0%` | 未授權且未執行 |