Files
awoooi/docs/security/PUBLIC-GATEWAY-POST-INCIDENT-READBACK-PLAN.md
Your Name 5254a0c88b
All checks were successful
Code Review / ai-code-review (push) Successful in 11s
CD Pipeline / tests (push) Successful in 1m36s
CD Pipeline / build-and-deploy (push) Successful in 4m49s
CD Pipeline / post-deploy-checks (push) Successful in 1m48s
feat(iwooos): 新增 Nginx 事故回讀 gate
2026-06-16 10:31:13 +08:00

165 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 reasonbreak-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 acceptedruntime 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%` | 未授權且未執行 |