feat(security): 新增 public gateway preflight 只讀清冊
This commit is contained in:
@@ -89,3 +89,9 @@ python3 scripts/security/domain-tls-certbot-inventory.py --root .
|
||||
| IwoooS 前台只讀呈現 | `待本輪部署驗證` | 只顯示摘要與邊界,不提供操作按鈕 |
|
||||
| live DNS / TLS validation | `0%` | 尚未批准;不得用本清冊替代 live probe |
|
||||
| certbot renew / Nginx reload | `0%` | 未授權,未執行 |
|
||||
|
||||
## 8. Preflight 銜接
|
||||
|
||||
`docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md` 會把本清冊中的 domain、TLS certificate path、ACME、admin route 與 WebSocket 影響面,轉成 public gateway reload / route change 前的 route smoke 與 owner check 條件。
|
||||
|
||||
此銜接仍不代表 DNS 查詢、TLS probe、certbot renew、Nginx reload 或主機寫入已授權。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 日期 | 2026-06-11 |
|
||||
| 日期 | 2026-06-12 |
|
||||
| 狀態 | `coverage_matrix_ready` |
|
||||
| 工具 | `scripts/security/high-value-config-control-coverage.py` |
|
||||
| Snapshot | `docs/security/high-value-config-control-coverage.snapshot.json` |
|
||||
@@ -25,7 +25,7 @@
|
||||
| C2 類別 | `1` | 產品 runtime route 與跨產品邊界 |
|
||||
| C3 類別 | `1` | security evidence / snapshot / guard tooling |
|
||||
| 平均只讀控管成熟度 | `66%` | 僅代表框架 / evidence / owner packet 準備度,不代表 runtime 可執行 |
|
||||
| 需要 live evidence 的類別 | `6` | 只能等 owner-provided redacted evidence 或維護窗口,不主動修改主機 |
|
||||
| 需要 live evidence 的類別 | `7` | 只能等 owner-provided redacted evidence 或維護窗口,不主動修改主機 |
|
||||
| owner response required | `14` | 每類都需要 owner response 才能往 accepted 前進 |
|
||||
| owner response received / accepted | `0 / 0` | 不得假性提高 |
|
||||
| runtime gate | `0` | 不得產生執行按鈕 |
|
||||
@@ -46,6 +46,15 @@
|
||||
```text
|
||||
runtime_execution_authorized=false
|
||||
host_write_authorized=false
|
||||
host_live_conf_read_authorized=false
|
||||
nginx_test_authorized=false
|
||||
public_gateway_reload_authorized=false
|
||||
public_route_change_authorized=false
|
||||
admin_route_change_authorized=false
|
||||
websocket_route_change_authorized=false
|
||||
acme_challenge_change_authorized=false
|
||||
route_smoke_authorized=false
|
||||
rollback_executed=false
|
||||
nginx_reload_authorized=false
|
||||
dns_tls_change_authorized=false
|
||||
certbot_renew_authorized=false
|
||||
@@ -138,3 +147,7 @@ python3 scripts/security/high-value-config-control-coverage.py \
|
||||
## 11. P1-4 Monitoring / alerting / observability 清冊更新
|
||||
|
||||
`monitoring_alerting_observability_inventory_v1` 已把 Prometheus、Alertmanager、Grafana、SigNoz、Sentry、Langfuse、OTEL、Telegram / notification policy、deploy / reload scripts 與 alert chain smoke scripts 納入 repo-only 清冊,共 `60` 個 surface、`13` 個 alert rule surface、`6` 個 deploy / reload surface、`11` 個 write-capable surface 與 `1` 個 drift guard surface。此更新只讓 `monitoring_alerting_observability` 從 `56%` 推進到 `62%`;owner response、live evidence、reload owner、receiver owner、route smoke、runtime gate 與 action button 仍全部為 `0`。
|
||||
|
||||
## 12. P0 Public Gateway Preflight 清冊更新
|
||||
|
||||
`public_gateway_preflight_inventory_v1` 已把 Nginx public gateway reload / route change 前置 Gate 固定成只讀清冊,共 `3` 份 source config、`14` 個 route impact、`14` 個 unique upstream、`12` 個 preflight gate,其中 `2` 個 gate 只代表 repo-only ready,`10` 個 gate 仍需 owner acceptance。此更新只讓 `nginx_public_gateway` 從 `78%` 推進到 `84%`;owner response、owner-provided live conf、rendered diff、`nginx -t` evidence、route smoke、maintenance window、rollback owner、runtime gate 與 action button 仍全部為 `0`。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 日期 | 2026-06-11 |
|
||||
| 日期 | 2026-06-12 |
|
||||
| 狀態 | `inventory_and_classification_gate_ready` |
|
||||
| 範圍 | AWOOOI / IwoooS 全產品重要配置 |
|
||||
| 本階段模式 | source-control 修補 + 只讀盤點,不做 live reload / restart / sync |
|
||||
@@ -33,7 +33,7 @@
|
||||
| C0 類別 | `8` | Nginx、DNS / TLS、K8s、secret、workflow / runner、runtime config、backup、agent-bounty runtime |
|
||||
| C1 類別 | `4` | 監控、Docker / systemd、SSH / network、AI provider |
|
||||
| 平均只讀控管成熟度 | `66%` | 只代表框架 / evidence / owner packet 準備度 |
|
||||
| 需要 live evidence 類別 | `6` | 只能等 owner-provided redacted evidence 或維護窗口,不主動 SSH |
|
||||
| 需要 live evidence 類別 | `7` | 只能等 owner-provided redacted evidence 或維護窗口,不主動 SSH |
|
||||
| owner response required | `14` | owner response received / accepted 仍 `0 / 0` |
|
||||
| runtime gate | `0` | 不提供執行按鈕 |
|
||||
|
||||
@@ -63,16 +63,22 @@
|
||||
|
||||
此更新仍不是 live alert chain truth:owner response、live evidence、reload owner、receiver owner、route smoke、maintenance window、rollback owner 與 runtime gate 全部仍為 `0`,也不得執行 Prometheus reload、Alertmanager reload、Grafana import、SigNoz rule apply、Sentry deploy、Langfuse change、OTEL reload、remote write change、silence change、Telegram send、live alert fire、alert chain smoke、SSH 或 kubectl。
|
||||
|
||||
### 0.6 2026-06-12 Public Gateway Preflight repo-only 清冊
|
||||
|
||||
`public_gateway_preflight_inventory_v1` 已把 Nginx public gateway reload / route change 前置 Gate 固定成只讀 snapshot。清冊目前共有 `3` 份 Nginx source config、`2` 份 C0 source config、`14` 個 route impact、`14` 個 unique upstream、`10` 條 TLS certificate path、`4` 個 certificate owner 確認缺口、`7` 個 ACME challenge domain、`1` 個 admin route domain、`6` 個 WebSocket route domain 與 `12` 個 preflight gate,讓 Nginx public gateway 類別成熟度從 `78%` 推進到 `84%`。
|
||||
|
||||
此更新仍不是 live gateway truth:owner response、owner-provided live conf、rendered diff、`nginx -t` evidence、route smoke、maintenance window、rollback owner 與 runtime gate 全部仍為 `0`,也不得 SSH、讀 live conf、執行 `nginx -t`、reload Nginx、改 public route、改 admin route、改 WebSocket / API route、改 ACME、做 DNS / TLS probe、執行 certbot renew 或寫入主機。
|
||||
|
||||
## 1. 目前已不符合新要求的項目
|
||||
|
||||
| 優先 | 項目 | 現況 | 風險 | 本階段處置 |
|
||||
|------|------|------|------|------------|
|
||||
| P0 | Nginx public gateway | 已有 Ansible source-of-truth,但缺少資安等級、owner gate、drift evidence、reload 前後驗證與跨產品通知規範 | 手改 live conf 會讓公開網站、admin route、TLS、API、WebSocket 或 ACME 被改壞,且不易追責 | 已新增高價值配置 Hard Rule 與本清冊;live drift detector 尚未實作 |
|
||||
| P0 | Nginx public gateway | 已有 Ansible source-of-truth、repo-only drift detector、DNS / TLS 清冊與 public gateway preflight Gate,但尚缺 owner-provided live conf、rendered diff、`nginx -t` evidence、route smoke、maintenance window 與 rollback owner | 手改 live conf 會讓公開網站、admin route、TLS、API、WebSocket 或 ACME 被改壞,且不易追責 | 已新增高價值配置 Hard Rule、drift detector 與 preflight 清冊;仍不得 SSH 或 reload |
|
||||
| P0 | `docs/runbooks/SECRETS-MANAGEMENT.md` Gitea token 範例 | 文件內存在可疑 token 範例 | 可能造成 Gitea API 權限外洩或複製貼上事故 | 已改為 owner-managed token env,不保存 value |
|
||||
| P0 | `k8s/monitoring/docker-compose-110.yml` Grafana admin 密碼 | compose 內有固定密碼常值 | 若被當作 live 密碼或複製使用,會造成監控後台弱控管 | 已改為 `GRAFANA_ADMIN_PASSWORD` owner secret store 注入 |
|
||||
| P0 | `ops/monitoring/discover_docker.py` SSH host key 驗證 | 仍使用關閉 host key 驗證的參數 | MITM 或錯誤主機信任風險 | 已改為 `BatchMode=yes` + `accept-new`;後續升級 pinned known_hosts |
|
||||
| P0 | `apps/api/src/api/v1/monitoring.py` Grafana 探測認證 | 程式碼內有 Grafana Basic Auth 常值 | API 程式碼保存 credential,且會被複製到後續部署 | 已改為 `settings.GRAFANA_API_KEY` Bearer token;未設定時不送 Authorization header |
|
||||
| P1 | Nginx 188 / 110 live conf drift | repo 有 templates,但尚未自動比較 live hash / rendered hash | 手改後 repo 不知道,下一次 Ansible 可能覆蓋或保留錯誤路由 | 新增為 P0 後續任務:只讀 drift detector |
|
||||
| P1 | Nginx 188 / 110 live conf drift | repo 有 templates 與 drift detector,比對模式需 owner 提供脫敏 live conf;目前 live evidence 仍為 `0` | 手改後 repo 不知道,下一次 Ansible 可能覆蓋或保留錯誤路由 | 下一步收 owner-provided live conf 與 rendered diff,不主動 SSH |
|
||||
| P1 | 高價值配置變更 Gate | 已有 C0-C3 清冊與 Hard Rule,但原本缺少可重跑 path 分類 | reviewer 只能靠人工記憶判斷 Nginx、workflow、secret、K8s、DNS、AI provider 是否需 owner gate | 已新增 `scripts/security/high-value-config-change-gate.py`;本階段只分類,不接 CI blocking |
|
||||
| P1 | DNS / TLS / certbot | 多產品共用 188 / 110 public gateway,憑證路徑與 renewal 仍分散在 runbook / template | 憑證過期、錯誤 cert path、ACME challenge 被覆蓋會造成公開服務中斷 | 納入 C0,需建立 domain / cert / renewal 清冊 |
|
||||
| P1 | workflow / runner / deploy key / secret name | 已有 Gitea / GitHub readiness 盤點,但尚未把配置變更和 IwoooS 高價值配置共用 gate 合併 | workflow 或 runner 改錯會直接影響部署與 secret 注入 | 納入 C0,維持只讀 owner response,不收 secret value |
|
||||
@@ -156,7 +162,7 @@ Nginx 是目前必須最先資安控管的配置,原因是它同時控制公
|
||||
| 規範 | 目前狀態 | 調整方向 |
|
||||
|------|----------|----------|
|
||||
| IwoooS 初期低摩擦 | 原本偏只讀框架 | 保留只讀框架,但 P0 即時危害可先做 source-control 止血 |
|
||||
| Nginx DR runbook | 已寫禁止直接手改 live conf | 補 owner gate、drift detector、跨產品通知、post-check |
|
||||
| Nginx DR runbook | 已寫禁止直接手改 live conf | 補 owner-provided live conf、rendered diff、`nginx -t` evidence、route smoke、跨產品通知、post-check |
|
||||
| Secrets 管理手冊 | 有 secret 來源與 CD 注入說明 | 去除可用 token 範例,補「metadata only」與 owner secret store |
|
||||
| Gitea / GitHub readiness | 已有 repo / workflow / secret name 盤點 | 與高價值配置分級合併,workflow 變更仍需獨立批准 |
|
||||
| Deployment verification | 偏重 Pod / health | 加入 Nginx / DNS / TLS / public route / admin route smoke |
|
||||
@@ -171,6 +177,7 @@ Nginx 是目前必須最先資安控管的配置,原因是它同時控制公
|
||||
| Nginx 控管機制定義 | `100%` | 已定義 source-of-truth、live path、gate、drift 原則 |
|
||||
| source-control P0 止血 | `100%` | 已清掉本波掃到的 token 範例、Grafana 密碼常值與 SSH host key 關閉 |
|
||||
| repo-only Nginx drift detector | `100%` | 已新增 `scripts/security/nginx-config-drift-detector.py` 與 repo source-of-truth snapshot |
|
||||
| public gateway preflight 清冊 | `100%` | 已新增 `public_gateway_preflight_inventory_v1`,固定 12 個 reload / route change 前置 Gate;成熟度 `78% -> 84%` |
|
||||
| 高價值配置變更分類 Gate | `100%` | 已新增 `scripts/security/high-value-config-change-gate.py`,可用 git diff 或手動檔案分類 C0/C1/C2/C3 並列出 owner / rollback / evidence / 驗證欄位 |
|
||||
| owner response evidence JSON 欄位檢查 | `70%` | Gate 可檢查必要欄位與 false flags;尚未接正式收件 API 或 AwoooP queue |
|
||||
| Gate → owner response packet 草案 | `100%` | 已新增 `scripts/security/high-value-config-owner-packet.py`,可將 impacted category 轉成 canonical owner response packet 草案 |
|
||||
|
||||
@@ -89,11 +89,12 @@ IwoooS 首版只讀取或對齊以下已提交 evidence:
|
||||
51. 10 個 frontend surface reverse bridge statuses,顯示既有資安入口目前是 embedded bridge、direct bridge 或 AwoooP read-only candidate;這只是連接狀態,不代表 owner response、runtime authorization、Code Review blocker、Gitea/GitHub action 或任何執行控制。
|
||||
52. 6 個 source control primary readiness items,顯示 GitHub primary 前置缺口:candidate repo inventory、primary ready counter、owner response validation、refs truth、workflow / secret name inventory、rollback ADR;這只是 readiness,不代表 repo 建立、visibility 變更、refs mutation、secret value collection、primary switch 或 Gitea 停用。
|
||||
53. 4 個 rollout risk read-only items,顯示風險來源部署 marker、`AWOOOI_ROLLOUT_RISK=1`、ArgoCD `Degraded` / `OutOfSync`、API health / smoke 已通過與執行期閘門仍為 0;這只是部署風險可見性,不代表 ArgoCD sync、kubectl、主機重啟、修復、部署或 runtime gate 已授權。
|
||||
54. 14 類 high-value config control coverage statuses,顯示 Nginx、DNS / TLS、K8s、secret、workflow、backup、agent-bounty runtime、monitoring、Docker / systemd、SSH / network、AI provider、產品 route 與 security evidence 的全域配置控管覆蓋矩陣;平均只讀成熟度 `66%`、C0 類別 `8`、需 live evidence 類別 `6`、owner response received / accepted 與 runtime gate 仍為 `0`,不代表 reload、sync、scan、secret rotation、payout 或主機操作授權。
|
||||
54. 14 類 high-value config control coverage statuses,顯示 Nginx、DNS / TLS、K8s、secret、workflow、backup、agent-bounty runtime、monitoring、Docker / systemd、SSH / network、AI provider、產品 route 與 security evidence 的全域配置控管覆蓋矩陣;平均只讀成熟度 `66%`、C0 類別 `8`、需 live evidence 類別 `7`、owner response received / accepted 與 runtime gate 仍為 `0`,不代表 reload、sync、scan、secret rotation、payout 或主機操作授權。
|
||||
55. 9 個 host-service config repo-only inventory surfaces,顯示 Docker Compose、systemd / repair-bot、Ansible service role 與 host config backup capture 的第一層清冊;write-capable surface `3`、repair-bot whitelist `2`、systemd restart surface `1`,owner response、live evidence、restart window、rollback owner、runtime gate 與 action button 仍全部為 `0`,不代表 `docker compose`、`systemctl`、repair-bot 或 Ansible apply 已授權。
|
||||
56. 16 個 SSH / network access repo-only inventory surfaces,顯示 SSH target、known_hosts workflow、CI deploy SSH、monitoring SSH、backup SSH capture、sudoers wrapper、NetworkPolicy、NodePort、WireGuard runbook 與 alert SSH action catalog 的第一層清冊;write-capable surface `6`、NetworkPolicy `2`、NodePort `2`、sudoers `1`、WireGuard `1`,owner response、live evidence、maintenance window、rollback owner、runtime gate 與 action button 仍全部為 `0`,不代表 SSH、sudo、firewall、NetworkPolicy、NodePort、WireGuard 或 known_hosts patch 已授權。
|
||||
57. 38 個 Backup / restore / escrow / retention repo-only inventory surfaces,顯示 backup orchestration、service backup scripts、restic retention、offsite sync、credential escrow、Velero restore drill、backup health alert 與 cold-start / DR runbook 的第一層清冊;write-capable surface `27`、restore drill surface `4`、offsite / escrow surface `8`,owner response、live evidence、restore drill、offsite sync、credential escrow、retention change、runtime gate 與 action button 仍全部為 `0`,不代表 backup、restore、offsite sync、remote delete、restic prune、escrow marker write、rclone config 或 Velero restore 已授權。
|
||||
58. 60 個 Monitoring / alerting / observability repo-only inventory surfaces,顯示 Prometheus、Alertmanager、Grafana、SigNoz、Sentry、Langfuse、OTEL、Telegram / notification policy、deploy / reload scripts 與 alert chain smoke scripts 的第一層清冊;write-capable surface `11`、alert rule surface `13`、deploy / reload surface `6`,owner response、live evidence、reload owner、receiver owner、route smoke、runtime gate 與 action button 仍全部為 `0`,不代表 Prometheus reload、Alertmanager reload、Grafana import、SigNoz apply、Sentry deploy、Telegram send、live alert fire 或 alert chain smoke 已授權。
|
||||
59. 12 個 Public Gateway Preflight repo-only gates,顯示 Nginx public gateway reload / route change 前必備的 owner、live conf、rendered diff、`nginx -t`、public / admin / WebSocket route smoke、ACME / TLS owner check、maintenance window 與 rollback owner;source config `3`、route impact `14`、repo-only ready gate `2`,owner acceptance、live conf、rendered diff、`nginx -t` evidence、route smoke、runtime gate 與 action button 仍全部為 `0`,不代表 SSH、live conf read、Nginx reload、route change、DNS / TLS probe 或 certbot renew 已授權。
|
||||
|
||||
## 3.1 既有前端資安頁面整合
|
||||
|
||||
|
||||
@@ -79,3 +79,9 @@ python3 scripts/security/nginx-config-drift-detector.py \
|
||||
| owner-provided live file 比對格式 | `70%` | 支援手動提供 live conf 檔,不主動取得 live |
|
||||
| live Nginx 證據收集 | `0%` | 本階段不 SSH、不讀主機 |
|
||||
| Nginx reload / restart | `0%` | 未授權且未執行 |
|
||||
|
||||
## 8. Preflight 銜接
|
||||
|
||||
`docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md` 會消費本工具與 DNS / TLS 清冊的 repo-only 結果,固定 Nginx reload / route change 前必備的 owner、live conf、rendered diff、`nginx -t`、route smoke、maintenance window 與 rollback owner 欄位。
|
||||
|
||||
此銜接仍不代表 live conf 已收、drift 已判定、`nginx -t` 已執行或 reload 已授權。
|
||||
|
||||
115
docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md
Normal file
115
docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# IwoooS Public Gateway 變更前置 Gate 只讀清冊
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 日期 | 2026-06-12 |
|
||||
| 狀態 | `repo_only_preflight_contract_ready` |
|
||||
| 工具 | `scripts/security/public-gateway-preflight-inventory.py` |
|
||||
| Snapshot | `docs/security/public-gateway-preflight-inventory.snapshot.json` |
|
||||
| Schema | `docs/schemas/public_gateway_preflight_inventory_v1.schema.json` |
|
||||
| runtime gate | `0` |
|
||||
|
||||
## 1. 目的
|
||||
|
||||
Public gateway 是所有產品、後台、API、callback、Webhook、ACME 與 WebSocket 的入口。Nginx 或 reverse proxy 若被手動修改,可能造成公開路由錯轉、管理後台暴露、憑證路徑錯置、ACME renew 失敗、WebSocket 中斷或 AI provider proxy 失效。
|
||||
|
||||
本清冊把 Nginx reload / public route change 前必備證據固定成只讀 Gate:誰負責、影響哪些 route、是否有 live conf evidence、是否有 rendered diff、是否有 `nginx -t`、是否有 route smoke、是否有 rollback owner。它不做任何 live 操作。
|
||||
|
||||
## 2. repo-only 摘要
|
||||
|
||||
| 指標 | 值 |
|
||||
|------|----|
|
||||
| Nginx source config | `3` |
|
||||
| C0 source config | `2` |
|
||||
| route impact | `14` |
|
||||
| unique upstream | `14` |
|
||||
| TLS certificate path | `10` |
|
||||
| certificate owner 確認缺口 | `4` |
|
||||
| ACME challenge domain | `7` |
|
||||
| admin route domain | `1` |
|
||||
| WebSocket route domain | `6` |
|
||||
| preflight gate | `12` |
|
||||
| repo-only ready gate | `2` |
|
||||
| owner acceptance required gate | `10` |
|
||||
| owner response / accepted | `0 / 0` |
|
||||
| live conf / rendered diff / nginx -t / route smoke | `0 / 0 / 0 / 0` |
|
||||
| maintenance window / rollback owner | `0 / 0` |
|
||||
| runtime gate / action button | `0 / 0` |
|
||||
|
||||
## 3. 已納入的 public gateway source
|
||||
|
||||
| config id | 主機 | 角色 | 等級 | source |
|
||||
|-----------|------|------|------|--------|
|
||||
| `host188_all_sites` | `192.168.0.188` | public gateway all sites | C0 | `infra/ansible/roles/nginx/templates/188-all-sites.conf.j2` |
|
||||
| `host188_internal_tools_https` | `192.168.0.188` | internal tools HTTPS | C0 | `infra/ansible/roles/nginx/templates/188-internal-tools-https.conf.j2` |
|
||||
| `host110_ollama_proxy` | `192.168.0.110` | Ollama proxy gateway | C1 | `infra/ansible/roles/nginx/templates/110-ollama-proxy.conf.j2` |
|
||||
|
||||
## 4. Reload / route change 前置 Gate
|
||||
|
||||
| Gate | 內容 | 目前狀態 |
|
||||
|------|------|----------|
|
||||
| PG1 | source-of-truth hash | repo-only ready |
|
||||
| PG2 | affected route list | repo-only ready |
|
||||
| PG3 | owner response | `0` |
|
||||
| PG4 | owner-provided live config | `0` |
|
||||
| PG5 | rendered diff | `0` |
|
||||
| PG6 | `nginx -t` evidence | `0` |
|
||||
| PG7 | public route smoke | `0` |
|
||||
| PG8 | admin route smoke | `0` |
|
||||
| PG9 | WebSocket / API smoke | `0` |
|
||||
| PG10 | ACME / TLS owner check | `0` |
|
||||
| PG11 | maintenance window | `0` |
|
||||
| PG12 | rollback owner and ref | `0` |
|
||||
|
||||
## 5. owner response 欄位
|
||||
|
||||
任何 public gateway 變更、live drift 判讀或 reload 候選,都至少要具備:
|
||||
|
||||
1. `owner_role_or_team`
|
||||
2. `decision`
|
||||
3. `decision_reason`
|
||||
4. `affected_scope`
|
||||
5. `redacted_evidence_refs`
|
||||
6. `followup_owner`
|
||||
7. `rollback_owner`
|
||||
8. `maintenance_window`
|
||||
9. `validation_plan`
|
||||
10. `nginx_test_evidence_ref`
|
||||
11. `route_smoke_evidence_ref`
|
||||
|
||||
## 6. 指令
|
||||
|
||||
更新 snapshot:
|
||||
|
||||
```bash
|
||||
python3 scripts/security/public-gateway-preflight-inventory.py \
|
||||
--root . \
|
||||
--generated-at 2026-06-12T10:30:00+08:00 \
|
||||
--output docs/security/public-gateway-preflight-inventory.snapshot.json
|
||||
```
|
||||
|
||||
只輸出目前清冊:
|
||||
|
||||
```bash
|
||||
python3 scripts/security/public-gateway-preflight-inventory.py --root .
|
||||
```
|
||||
|
||||
## 7. 邊界
|
||||
|
||||
1. 本清冊不執行 SSH。
|
||||
2. 本清冊不讀 live Nginx conf。
|
||||
3. 本清冊不執行 `nginx -t`。
|
||||
4. 本清冊不 reload / restart Nginx。
|
||||
5. 本清冊不做 DNS query、TLS probe 或 certbot renew。
|
||||
6. 本清冊不修改主機、不改 DNS、不改憑證、不讀 private key。
|
||||
7. IwoooS UI 可顯示 preflight Gate,但不得把卡片可見視為 owner 已確認或 runtime 已授權。
|
||||
|
||||
## 8. 完成度
|
||||
|
||||
| 工作 | 完成度 | 說明 |
|
||||
|------|--------|------|
|
||||
| public gateway preflight 契約 | `100%` | 已固定 12 個 reload / route change 前置 Gate |
|
||||
| source-of-truth hash / affected route list | `100%` | 由既有 Nginx / DNS-TLS snapshot 推導 |
|
||||
| owner response / live conf / rendered diff | `0%` | 尚未收到,不能宣稱 live 無漂移 |
|
||||
| `nginx -t` / route smoke / rollback owner | `0%` | 尚未批准且未執行 |
|
||||
| runtime reload / host write | `0%` | 未授權,未執行 |
|
||||
@@ -4,16 +4,19 @@
|
||||
"action_buttons_allowed": false,
|
||||
"category_id": "nginx_public_gateway",
|
||||
"control_tier": "C0",
|
||||
"coverage_percent": 78,
|
||||
"coverage_status": "repo_only_drift_detector_ready",
|
||||
"current_gap": "缺 owner-provided live conf 匯出與 approved maintenance window;不得 SSH 擷取或 reload。",
|
||||
"coverage_percent": 84,
|
||||
"coverage_status": "repo_only_preflight_contract_ready_needs_owner_live_diff",
|
||||
"current_gap": "已固定 12 個 public gateway preflight gate;owner response、live conf、rendered diff、nginx -t、route smoke、maintenance window 與 rollback owner 仍全部為 0。",
|
||||
"evidence_refs": [
|
||||
"docs/security/NGINX-CONFIG-DRIFT-DETECTOR.md",
|
||||
"docs/security/nginx-config-drift-repo.snapshot.json",
|
||||
"docs/security/DOMAIN-TLS-CERTBOT-INVENTORY.md"
|
||||
"docs/security/DOMAIN-TLS-CERTBOT-INVENTORY.md",
|
||||
"docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md",
|
||||
"docs/security/public-gateway-preflight-inventory.snapshot.json",
|
||||
"docs/schemas/public_gateway_preflight_inventory_v1.schema.json"
|
||||
],
|
||||
"label": "Nginx / reverse proxy / public route",
|
||||
"next_owner_action": "提供脫敏 live conf 匯出檔或確認維護窗口、rollback owner 與 route smoke plan。",
|
||||
"next_owner_action": "補 public gateway owner、owner-provided live conf、source-to-live rendered diff、nginx -t evidence、route smoke、maintenance window 與 rollback owner。",
|
||||
"owner_response_accepted": false,
|
||||
"owner_response_received": false,
|
||||
"owner_response_required": true,
|
||||
@@ -509,8 +512,10 @@
|
||||
}
|
||||
],
|
||||
"execution_boundaries": {
|
||||
"acme_challenge_change_authorized": false,
|
||||
"action_buttons_allowed": false,
|
||||
"active_scan_authorized": false,
|
||||
"admin_route_change_authorized": false,
|
||||
"agent_bounty_runtime_authorized": false,
|
||||
"alert_chain_smoke_authorized": false,
|
||||
"alertmanager_reload_authorized": false,
|
||||
@@ -522,17 +527,21 @@
|
||||
"exporter_deploy_authorized": false,
|
||||
"force_push_authorized": false,
|
||||
"grafana_dashboard_apply_authorized": false,
|
||||
"host_live_conf_read_authorized": false,
|
||||
"host_write_authorized": false,
|
||||
"kubectl_action_authorized": false,
|
||||
"langfuse_config_change_authorized": false,
|
||||
"live_alert_fire_authorized": false,
|
||||
"nginx_reload_authorized": false,
|
||||
"nginx_test_authorized": false,
|
||||
"notification_route_change_authorized": false,
|
||||
"offsite_remote_delete_authorized": false,
|
||||
"offsite_sync_authorized": false,
|
||||
"otel_collector_reload_authorized": false,
|
||||
"payout_or_withdrawal_authorized": false,
|
||||
"prometheus_reload_authorized": false,
|
||||
"public_gateway_reload_authorized": false,
|
||||
"public_route_change_authorized": false,
|
||||
"rclone_config_authorized": false,
|
||||
"receiver_route_change_authorized": false,
|
||||
"refs_sync_authorized": false,
|
||||
@@ -541,6 +550,8 @@
|
||||
"restore_drill_authorized": false,
|
||||
"restore_run_authorized": false,
|
||||
"retention_change_authorized": false,
|
||||
"rollback_executed": false,
|
||||
"route_smoke_authorized": false,
|
||||
"runner_change_authorized": false,
|
||||
"runtime_execution_authorized": false,
|
||||
"secret_value_collection_allowed": false,
|
||||
@@ -550,10 +561,11 @@
|
||||
"telegram_send_authorized": false,
|
||||
"velero_restore_authorized": false,
|
||||
"webhook_receiver_change_authorized": false,
|
||||
"websocket_route_change_authorized": false,
|
||||
"workflow_modification_authorized": false
|
||||
},
|
||||
"generated_at": "2026-06-12T09:05:00+08:00",
|
||||
"git_commit": "7a7daa33",
|
||||
"generated_at": "2026-06-12T10:35:00+08:00",
|
||||
"git_commit": "e4747722",
|
||||
"lowest_coverage_categories": [
|
||||
{
|
||||
"category_id": "docker_compose_systemd_host_config",
|
||||
@@ -613,7 +625,7 @@
|
||||
"c3_category_count": 1,
|
||||
"category_count": 14,
|
||||
"lowest_coverage_category_count": 4,
|
||||
"needs_live_evidence_count": 6,
|
||||
"needs_live_evidence_count": 7,
|
||||
"owner_response_accepted_count": 0,
|
||||
"owner_response_received_count": 0,
|
||||
"owner_response_required_count": 14,
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
"docs/security/HIGH-VALUE-CONFIG-OWNER-PACKET.md",
|
||||
"docs/security/high-value-config-change-gate.snapshot.json",
|
||||
"docs/security/HIGH-VALUE-CONFIG-CHANGE-GATE.md",
|
||||
"docs/security/public-gateway-preflight-inventory.snapshot.json",
|
||||
"docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md",
|
||||
"docs/schemas/public_gateway_preflight_inventory_v1.schema.json",
|
||||
"docs/security/domain-tls-certbot-inventory.snapshot.json",
|
||||
"docs/security/DOMAIN-TLS-CERTBOT-INVENTORY.md",
|
||||
"docs/schemas/domain_tls_certbot_inventory_v1.schema.json",
|
||||
@@ -246,7 +249,7 @@
|
||||
"high_value_config_control_coverage_c0_category_count": 8,
|
||||
"high_value_config_control_coverage_c1_category_count": 4,
|
||||
"high_value_config_control_coverage_average_percent": 66,
|
||||
"high_value_config_control_coverage_needs_live_evidence_count": 6,
|
||||
"high_value_config_control_coverage_needs_live_evidence_count": 7,
|
||||
"high_value_config_control_coverage_owner_response_required_count": 14,
|
||||
"high_value_config_control_coverage_owner_response_received_count": 0,
|
||||
"high_value_config_control_coverage_owner_response_accepted_count": 0,
|
||||
@@ -467,7 +470,36 @@
|
||||
"monitoring_alerting_observability_inventory_runtime_gate_count": 0,
|
||||
"monitoring_alerting_observability_inventory_action_button_count": 0,
|
||||
"monitoring_alerting_observability_inventory_coverage_percent_before_inventory": 56,
|
||||
"monitoring_alerting_observability_inventory_coverage_percent_after_inventory": 62
|
||||
"monitoring_alerting_observability_inventory_coverage_percent_after_inventory": 62,
|
||||
"public_gateway_preflight_first_layer": true,
|
||||
"public_gateway_preflight_summary_count": 4,
|
||||
"public_gateway_preflight_item_count": 6,
|
||||
"public_gateway_preflight_source_config_count": 3,
|
||||
"public_gateway_preflight_c0_source_config_count": 2,
|
||||
"public_gateway_preflight_managed_domain_count": 14,
|
||||
"public_gateway_preflight_route_impact_count": 14,
|
||||
"public_gateway_preflight_unique_upstream_count": 14,
|
||||
"public_gateway_preflight_tls_certificate_path_count": 10,
|
||||
"public_gateway_preflight_certificate_owner_confirmation_required_count": 4,
|
||||
"public_gateway_preflight_admin_route_domain_count": 1,
|
||||
"public_gateway_preflight_websocket_route_domain_count": 6,
|
||||
"public_gateway_preflight_acme_challenge_domain_count": 7,
|
||||
"public_gateway_preflight_gate_count": 12,
|
||||
"public_gateway_preflight_repo_only_ready_count": 2,
|
||||
"public_gateway_preflight_owner_acceptance_required_gate_count": 10,
|
||||
"public_gateway_preflight_gate_accepted_count": 0,
|
||||
"public_gateway_preflight_owner_response_received_count": 0,
|
||||
"public_gateway_preflight_owner_response_accepted_count": 0,
|
||||
"public_gateway_preflight_owner_provided_live_conf_received_count": 0,
|
||||
"public_gateway_preflight_rendered_diff_ready_count": 0,
|
||||
"public_gateway_preflight_nginx_test_evidence_count": 0,
|
||||
"public_gateway_preflight_route_smoke_evidence_count": 0,
|
||||
"public_gateway_preflight_maintenance_window_accepted_count": 0,
|
||||
"public_gateway_preflight_rollback_owner_accepted_count": 0,
|
||||
"public_gateway_preflight_runtime_gate_count": 0,
|
||||
"public_gateway_preflight_action_button_count": 0,
|
||||
"public_gateway_preflight_coverage_percent_before_preflight": 78,
|
||||
"public_gateway_preflight_coverage_percent_after_preflight": 84
|
||||
},
|
||||
"progress": {
|
||||
"overall_percent": 64,
|
||||
|
||||
589
docs/security/public-gateway-preflight-inventory.snapshot.json
Normal file
589
docs/security/public-gateway-preflight-inventory.snapshot.json
Normal file
@@ -0,0 +1,589 @@
|
||||
{
|
||||
"config_preflight_rows": [
|
||||
{
|
||||
"acme_route_count": 2,
|
||||
"admin_route_count": 2,
|
||||
"config_id": "host188_all_sites",
|
||||
"control_tier": "C0",
|
||||
"host": "192.168.0.188",
|
||||
"live_conf_evidence_received": false,
|
||||
"live_path": "/etc/nginx/sites-enabled/all-sites.conf",
|
||||
"maintenance_window_accepted": false,
|
||||
"nginx_test_evidence_received": false,
|
||||
"owner_gate": "public_gateway_owner_response_required",
|
||||
"owner_response_accepted": false,
|
||||
"owner_response_received": false,
|
||||
"rendered_diff_ready": false,
|
||||
"repo_source_hash_ready": true,
|
||||
"repo_source_path": "infra/ansible/roles/nginx/templates/188-all-sites.conf.j2",
|
||||
"role": "public_gateway_all_sites",
|
||||
"rollback_owner_accepted": false,
|
||||
"route_smoke_evidence_received": false,
|
||||
"runtime_gate_open": false,
|
||||
"server_block_count": 15,
|
||||
"server_name_count": 9,
|
||||
"tls_certificate_path_count": 7,
|
||||
"upstream_count": 10,
|
||||
"websocket_route_count": 5
|
||||
},
|
||||
{
|
||||
"acme_route_count": 1,
|
||||
"admin_route_count": 0,
|
||||
"config_id": "host188_internal_tools_https",
|
||||
"control_tier": "C0",
|
||||
"host": "192.168.0.188",
|
||||
"live_conf_evidence_received": false,
|
||||
"live_path": "owner_confirmation_required",
|
||||
"maintenance_window_accepted": false,
|
||||
"nginx_test_evidence_received": false,
|
||||
"owner_gate": "public_tools_owner_response_required",
|
||||
"owner_response_accepted": false,
|
||||
"owner_response_received": false,
|
||||
"rendered_diff_ready": false,
|
||||
"repo_source_hash_ready": true,
|
||||
"repo_source_path": "infra/ansible/roles/nginx/templates/188-internal-tools-https.conf.j2",
|
||||
"role": "public_internal_tools_https",
|
||||
"rollback_owner_accepted": false,
|
||||
"route_smoke_evidence_received": false,
|
||||
"runtime_gate_open": false,
|
||||
"server_block_count": 8,
|
||||
"server_name_count": 7,
|
||||
"tls_certificate_path_count": 4,
|
||||
"upstream_count": 6,
|
||||
"websocket_route_count": 2
|
||||
},
|
||||
{
|
||||
"acme_route_count": 0,
|
||||
"admin_route_count": 0,
|
||||
"config_id": "host110_ollama_proxy",
|
||||
"control_tier": "C1",
|
||||
"host": "192.168.0.110",
|
||||
"live_conf_evidence_received": false,
|
||||
"live_path": "/etc/nginx/sites-enabled/110-ollama-proxy.conf",
|
||||
"maintenance_window_accepted": false,
|
||||
"nginx_test_evidence_received": false,
|
||||
"owner_gate": "ai_provider_proxy_owner_response_required",
|
||||
"owner_response_accepted": false,
|
||||
"owner_response_received": false,
|
||||
"rendered_diff_ready": false,
|
||||
"repo_source_hash_ready": true,
|
||||
"repo_source_path": "infra/ansible/roles/nginx/templates/110-ollama-proxy.conf.j2",
|
||||
"role": "ollama_proxy_gateway",
|
||||
"rollback_owner_accepted": false,
|
||||
"route_smoke_evidence_received": false,
|
||||
"runtime_gate_open": false,
|
||||
"server_block_count": 3,
|
||||
"server_name_count": 0,
|
||||
"tls_certificate_path_count": 0,
|
||||
"upstream_count": 3,
|
||||
"websocket_route_count": 0
|
||||
}
|
||||
],
|
||||
"execution_boundaries": {
|
||||
"acme_challenge_change_authorized": false,
|
||||
"action_buttons_allowed": false,
|
||||
"admin_route_change_authorized": false,
|
||||
"certbot_renew_authorized": false,
|
||||
"certbot_renew_executed": false,
|
||||
"dns_query_executed": false,
|
||||
"host_live_conf_read_authorized": false,
|
||||
"host_write_authorized": false,
|
||||
"live_tls_probe_executed": false,
|
||||
"nginx_reload_authorized": false,
|
||||
"nginx_reload_executed": false,
|
||||
"nginx_test_authorized": false,
|
||||
"nginx_test_executed": false,
|
||||
"public_gateway_reload_authorized": false,
|
||||
"public_route_change_authorized": false,
|
||||
"rollback_executed": false,
|
||||
"route_smoke_authorized": false,
|
||||
"route_smoke_executed": false,
|
||||
"runtime_execution_authorized": false,
|
||||
"secret_value_collection_allowed": false,
|
||||
"ssh_read_authorized": false,
|
||||
"ssh_write_authorized": false,
|
||||
"websocket_route_change_authorized": false
|
||||
},
|
||||
"generated_at": "2026-06-12T10:30:00+08:00",
|
||||
"git_commit": "e4747722",
|
||||
"next_collection_order": [
|
||||
"public_gateway_owner_response",
|
||||
"owner_provided_live_conf_export",
|
||||
"source_to_live_rendered_diff",
|
||||
"nginx_t_evidence",
|
||||
"affected_public_route_smoke",
|
||||
"admin_route_smoke_if_affected",
|
||||
"websocket_or_api_smoke_if_affected",
|
||||
"tls_certificate_owner_confirmation",
|
||||
"maintenance_window",
|
||||
"rollback_owner_and_ref"
|
||||
],
|
||||
"operator_interpretation": [
|
||||
"這是 Nginx public gateway 變更前置控管清冊,不是 reload 授權。",
|
||||
"repo-only ready 只代表 source hash 與 affected route list 已能重跑產生。",
|
||||
"owner response、live conf、rendered diff、nginx -t、route smoke、maintenance window 與 rollback owner 全部仍為 0。",
|
||||
"若未來發現 live drift,只能建立 evidence 與 owner decision,不得自動覆寫 live。"
|
||||
],
|
||||
"required_owner_fields": [
|
||||
"owner_role_or_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan",
|
||||
"nginx_test_evidence_ref",
|
||||
"route_smoke_evidence_ref"
|
||||
],
|
||||
"required_preflight_gates": [
|
||||
{
|
||||
"gate_id": "PG1",
|
||||
"label": "source-of-truth hash",
|
||||
"owner_acceptance_required": false,
|
||||
"repo_only_ready": true,
|
||||
"required_evidence": "repo_source_raw_and_normalized_sha256"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG2",
|
||||
"label": "affected route list",
|
||||
"owner_acceptance_required": false,
|
||||
"repo_only_ready": true,
|
||||
"required_evidence": "domain_route_upstream_tls_admin_websocket_acme_inventory"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG3",
|
||||
"label": "owner response",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "owner role/team, decision, reason, affected scope, redacted refs, followup owner"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG4",
|
||||
"label": "owner-provided live config",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "redacted live conf export or owner statement"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG5",
|
||||
"label": "rendered diff",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "source-to-live rendered diff with redaction"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG6",
|
||||
"label": "nginx -t evidence",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "syntax test output captured by approved maintainer"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG7",
|
||||
"label": "public route smoke",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "public route smoke plan and result for affected domains"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG8",
|
||||
"label": "admin route smoke",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "admin/auth route smoke when admin path is affected"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG9",
|
||||
"label": "WebSocket / API smoke",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "WebSocket or API smoke when upstream or upgrade header is affected"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG10",
|
||||
"label": "ACME / TLS owner check",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "certificate path, SAN/wildcard/shared-cert statement, ACME impact"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG11",
|
||||
"label": "maintenance window",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "approved window and notification scope"
|
||||
},
|
||||
{
|
||||
"gate_id": "PG12",
|
||||
"label": "rollback owner and ref",
|
||||
"owner_acceptance_required": true,
|
||||
"repo_only_ready": false,
|
||||
"required_evidence": "rollback owner, rollback file/ref, post-rollback smoke"
|
||||
}
|
||||
],
|
||||
"route_impacts": [
|
||||
{
|
||||
"acme_challenge_present": false,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_all_sites"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "aiops.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 3,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 1
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": false,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_all_sites"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "bitan.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 1
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": true,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": true,
|
||||
"config_ids": [
|
||||
"host188_internal_tools_https"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "gitea.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": true,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 1
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": false,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_all_sites"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "gitlab.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 0
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": true,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_internal_tools_https"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "harbor.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 0
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": true,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": true,
|
||||
"config_ids": [
|
||||
"host188_internal_tools_https"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "langfuse.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": true,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 0
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": false,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_all_sites"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "mo.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 0
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": true,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_internal_tools_https"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "registry.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 0
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": true,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_internal_tools_https"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "sentry.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 0
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": false,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": true,
|
||||
"config_ids": [
|
||||
"host188_all_sites",
|
||||
"host188_internal_tools_https"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "signoz.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": true,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 1
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": true,
|
||||
"admin_route_count": 2,
|
||||
"admin_route_smoke_required": true,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_all_sites",
|
||||
"host188_internal_tools_https"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "stock.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 2
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": false,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": true,
|
||||
"config_ids": [
|
||||
"host188_all_sites"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "tsenyang.com",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": true,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 0
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": true,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_all_sites"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "vtuber.wooo.work",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 1
|
||||
},
|
||||
{
|
||||
"acme_challenge_present": false,
|
||||
"admin_route_count": 0,
|
||||
"admin_route_smoke_required": false,
|
||||
"certificate_owner_confirmation_required": false,
|
||||
"config_ids": [
|
||||
"host188_all_sites"
|
||||
],
|
||||
"control_tier": "C0",
|
||||
"domain": "www.tsenyang.com",
|
||||
"has_tls_certificate_path": true,
|
||||
"hosts": [
|
||||
"192.168.0.188"
|
||||
],
|
||||
"owner_response_accepted": false,
|
||||
"public_route_smoke_required": true,
|
||||
"route_smoke_accepted": false,
|
||||
"tls_owner_check_required": false,
|
||||
"upstream_count": 1,
|
||||
"websocket_or_api_smoke_required": true,
|
||||
"websocket_route_count": 0
|
||||
}
|
||||
],
|
||||
"schema_version": "public_gateway_preflight_inventory_v1",
|
||||
"source_reports": [
|
||||
"docs/security/nginx-config-drift-repo.snapshot.json",
|
||||
"docs/security/domain-tls-certbot-inventory.snapshot.json"
|
||||
],
|
||||
"source_scope": "committed_nginx_and_domain_tls_snapshots_only",
|
||||
"status": "repo_only_preflight_contract_ready",
|
||||
"summary": {
|
||||
"acme_challenge_domain_count": 7,
|
||||
"action_button_count": 0,
|
||||
"admin_route_domain_count": 1,
|
||||
"c0_source_config_count": 2,
|
||||
"certificate_owner_confirmation_required_count": 4,
|
||||
"coverage_percent_after_preflight": 84,
|
||||
"coverage_percent_before_preflight": 78,
|
||||
"maintenance_window_accepted_count": 0,
|
||||
"managed_domain_count": 14,
|
||||
"nginx_test_evidence_count": 0,
|
||||
"owner_acceptance_required_gate_count": 10,
|
||||
"owner_provided_live_conf_received_count": 0,
|
||||
"owner_response_accepted_count": 0,
|
||||
"owner_response_received_count": 0,
|
||||
"preflight_gate_accepted_count": 0,
|
||||
"preflight_gate_count": 12,
|
||||
"rendered_diff_ready_count": 0,
|
||||
"repo_only_preflight_ready_count": 2,
|
||||
"rollback_owner_accepted_count": 0,
|
||||
"route_impact_count": 14,
|
||||
"route_smoke_evidence_count": 0,
|
||||
"runtime_gate_count": 0,
|
||||
"source_config_count": 3,
|
||||
"tls_certificate_path_count": 10,
|
||||
"unique_upstream_count": 14,
|
||||
"websocket_route_domain_count": 6
|
||||
},
|
||||
"unique_upstreams": [
|
||||
"http://127.0.0.1:3000",
|
||||
"http://127.0.0.1:3301",
|
||||
"http://127.0.0.1:5003",
|
||||
"http://192.168.0.110:3001",
|
||||
"http://192.168.0.110:3003",
|
||||
"http://192.168.0.110:3100",
|
||||
"http://192.168.0.110:31235",
|
||||
"http://192.168.0.110:5000",
|
||||
"http://192.168.0.110:8929",
|
||||
"http://192.168.0.110:9000",
|
||||
"http://192.168.0.125:32334/api/",
|
||||
"http://192.168.0.125:32334/api/v1/ws",
|
||||
"http://192.168.0.125:32335",
|
||||
"https://192.168.0.110"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user