feat(security): 建立高價值配置變更 gate [skip ci]
This commit is contained in:
132
docs/security/HIGH-VALUE-CONFIG-CHANGE-GATE.md
Normal file
132
docs/security/HIGH-VALUE-CONFIG-CHANGE-GATE.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# IwoooS 高價值配置變更 Gate
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 日期 | 2026-06-11 |
|
||||
| 狀態 | `classification_gate_ready` |
|
||||
| 工具 | `scripts/security/high-value-config-change-gate.py` |
|
||||
| Snapshot | `docs/security/high-value-config-change-gate.snapshot.json` |
|
||||
| runtime gate | `0` |
|
||||
|
||||
## 1. 目的
|
||||
|
||||
此 Gate 將「所有重要配置都要被控管」落成可重跑的只讀分類流程。它會讀取 git diff 或手動指定檔案,判斷是否碰到 C0 / C1 / C2 / C3 高價值配置,並列出後續 owner response、rollback、redacted evidence 與驗證需求。
|
||||
|
||||
本階段是低摩擦分類 Gate,不接 CI blocking,不修改 workflow、不讀 secret value、不 SSH、不 reload、不部署、不開 runtime gate。
|
||||
|
||||
## 2. 納管配置
|
||||
|
||||
| 優先 | 等級 | 配置類別 |
|
||||
|------|------|----------|
|
||||
| P0 | C0 | Nginx / reverse proxy / public route |
|
||||
| P0 | C0 | DNS / TLS / certbot / certificate path |
|
||||
| P0 | C0 | K8s / ArgoCD / production manifests |
|
||||
| P0 | C0 | Secret metadata / injection / redaction |
|
||||
| P0 | C0 | Gitea workflow / runner / deploy key / webhook / branch protection |
|
||||
| P0 | C0 | Public / admin / API / frontend runtime config |
|
||||
| P0 | C0 | Backup / restore / escrow / retention |
|
||||
| P0 | C0 | `agent-bounty-protocol` runtime / MCP / A2A / treasury boundary |
|
||||
| P1 | C1 | Prometheus / Alertmanager / Grafana / SigNoz / Sentry / Langfuse |
|
||||
| P1 | C1 | Docker Compose / systemd / host service config |
|
||||
| P1 | C1 | SSH / sudoers / known_hosts / firewall / WireGuard / NodePort |
|
||||
| P1 | C1 | AI provider / model routing / Ollama proxy / cost and privacy |
|
||||
| P2 | C2 | AWOOOI / AwoooP / IwoooS / VibeWork / other product runtime routes |
|
||||
| P3 | C3 | Security evidence / snapshot / guard tooling |
|
||||
|
||||
## 3. 指令
|
||||
|
||||
檢查目前 commit 相對前一個 commit:
|
||||
|
||||
```bash
|
||||
python3 scripts/security/high-value-config-change-gate.py \
|
||||
--root . \
|
||||
--base HEAD~1 \
|
||||
--head HEAD
|
||||
```
|
||||
|
||||
手動分類單一檔案:
|
||||
|
||||
```bash
|
||||
python3 scripts/security/high-value-config-change-gate.py \
|
||||
--root . \
|
||||
--changed-file infra/ansible/roles/nginx/templates/188-all-sites.conf.j2
|
||||
```
|
||||
|
||||
更新 committed snapshot:
|
||||
|
||||
```bash
|
||||
python3 scripts/security/high-value-config-change-gate.py \
|
||||
--root . \
|
||||
--base HEAD~1 \
|
||||
--head HEAD \
|
||||
--generated-at 2026-06-11T12:30:00+08:00 \
|
||||
--output docs/security/high-value-config-change-gate.snapshot.json
|
||||
```
|
||||
|
||||
未來若要升級成更嚴格的人工審核,可提供 owner response evidence JSON:
|
||||
|
||||
```bash
|
||||
python3 scripts/security/high-value-config-change-gate.py \
|
||||
--root . \
|
||||
--base gitea/main \
|
||||
--head HEAD \
|
||||
--evidence /path/to/redacted-owner-response.json \
|
||||
--fail-on-missing-evidence
|
||||
```
|
||||
|
||||
## 4. owner response 欄位
|
||||
|
||||
所有 C0 / C1 高價值配置變更至少要補:
|
||||
|
||||
1. `owner_role_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`
|
||||
|
||||
這些欄位只是讓 reviewer 可以判斷,不等同 runtime 授權。
|
||||
|
||||
## 5. 必須維持 false
|
||||
|
||||
| flag | 要求 |
|
||||
|------|------|
|
||||
| `runtime_execution_authorized` | `false` |
|
||||
| `host_write_authorized` | `false` |
|
||||
| `secret_value_collection_allowed` | `false` |
|
||||
| `workflow_modification_authorized` | `false` |
|
||||
| `runner_change_authorized` | `false` |
|
||||
| `refs_sync_authorized` | `false` |
|
||||
| `force_push_authorized` | `false` |
|
||||
| `active_scan_authorized` | `false` |
|
||||
| `action_buttons_allowed` | `false` |
|
||||
|
||||
## 6. 判讀規則
|
||||
|
||||
| 狀態 | 意義 | 可做事項 |
|
||||
|------|------|----------|
|
||||
| `impacted_c0_category_count > 0` | 變更碰到公開入口、secret、部署、備份、agent runtime 等最高風險配置 | 先建立 owner response packet;不可直接 reload、deploy、sync 或修改主機 |
|
||||
| `impacted_c1_category_count > 0` | 變更碰到監控、主機服務、網路、AI provider 等近程高風險配置 | 建立 maintenance window、rollback owner 與驗證計畫 |
|
||||
| 只有 C2 | 產品 runtime route 或前端呈現變更 | 需要產品 owner、i18n、desktop / mobile smoke |
|
||||
| 只有 C3 | 文件、snapshot、guard 或 evidence tooling | 跑 guard、JSON parse、doc secret sanity;不可提高 runtime gate |
|
||||
|
||||
## 7. 邊界
|
||||
|
||||
1. 本工具不接 CI blocking。
|
||||
2. 本工具不修改 `.gitea/workflows`。
|
||||
3. 本工具不讀 secret value、hash、partial token、private key、runner token 或 webhook secret。
|
||||
4. 本工具不 SSH、不執行 `nginx -t`、不 reload / restart。
|
||||
5. 本工具不做 DNS 修改、TLS renew、ArgoCD sync、kubectl、active scan 或 agent-bounty runtime execution。
|
||||
6. IwoooS UI 可顯示分類結果,但不得把分類結果當 runtime 授權。
|
||||
|
||||
## 8. 完成度
|
||||
|
||||
| 工作 | 完成度 | 說明 |
|
||||
|------|--------|------|
|
||||
| 高價值配置 path pattern 分類 | `100%` | 已覆蓋 Nginx、DNS / TLS、K8s、secret、workflow、runner、backup、monitoring、host service、network、AI provider、agent-bounty-protocol 與產品 route |
|
||||
| owner response 欄位檢查 | `70%` | 支援 evidence JSON 欄位與 false flag 檢查;尚未接正式收件 API |
|
||||
| CI blocking | `0%` | 本階段刻意不接,避免初期摩擦過大 |
|
||||
| live runtime 驗證 | `0%` | 本工具只分類,不執行 live probe |
|
||||
@@ -3,7 +3,7 @@
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 日期 | 2026-06-11 |
|
||||
| 狀態 | `inventory_and_control_policy_ready` |
|
||||
| 狀態 | `inventory_and_classification_gate_ready` |
|
||||
| 範圍 | AWOOOI / IwoooS 全產品重要配置 |
|
||||
| 本階段模式 | source-control 修補 + 只讀盤點,不做 live reload / restart / sync |
|
||||
| runtime gate | `0` |
|
||||
@@ -31,6 +31,7 @@
|
||||
| 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 | 高價值配置變更 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 |
|
||||
| P1 | Docker Compose / systemd live config | 110 / 188 多服務由 compose、systemd 與 recovery scripts 管理 | restart policy、port、volume、env 改動會影響 Harbor、Sentry、Langfuse、Gitea、agent-bounty-protocol | 納入 C1,先做只讀 inventory |
|
||||
@@ -127,6 +128,9 @@ 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 |
|
||||
| 高價值配置變更分類 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 |
|
||||
| CI blocking / workflow gate | `0%` | 本階段刻意不修改 `.gitea/workflows`,避免初期資安流程摩擦過大 |
|
||||
| owner-provided live Nginx file compare | `70%` | 工具可吃 owner 匯出的 live conf 檔比較;本階段不主動 SSH 取得 |
|
||||
| live Nginx evidence collection | `0%` | 尚未 SSH / Ansible check-mode / live hash;需 owner 與維護窗口規則 |
|
||||
| live Nginx reload / restart | `0%` | 未授權,未執行 |
|
||||
@@ -135,13 +139,14 @@ Nginx 是目前必須最先資安控管的配置,原因是它同時控制公
|
||||
|
||||
## 7. 下一階段優先順序
|
||||
|
||||
1. P0:由 owner 提供脫敏 live Nginx conf 匯出檔,重跑 compare mode;不自動覆寫、不 reload。
|
||||
2. P0:補 DNS / TLS / certbot domain inventory,先只讀,不 renew、不 reload。
|
||||
3. P0:把 workflow / runner / secret name owner response 與高價值配置 C0 gate 串成同一個 IwoooS 狀態。
|
||||
4. P1:盤點 110 / 188 Docker Compose 與 systemd live config,標記 Harbor、Sentry、Langfuse、Gitea、agent-bounty-protocol 影響面。
|
||||
5. P1:盤點 Prometheus / Alertmanager / Grafana / SigNoz / Sentry 設定 drift 與 secret externalization。
|
||||
6. P1:補 Kali 112、111、168 維護窗口 owner 欄位,仍不做 upgrade / restart / scan。
|
||||
7. P2:把 `/zh-TW/iwooos` 配置控管摘要產品化,但不得顯示內部工作對話、token、secret 或可執行按鈕。
|
||||
1. P0:把高價值配置 Gate 的分類結果接成 owner response packet 草案;先只讀,不接 blocking CI。
|
||||
2. P0:由 owner 提供脫敏 live Nginx conf 匯出檔,重跑 compare mode;不自動覆寫、不 reload。
|
||||
3. P0:補 DNS / TLS / certbot domain inventory,先只讀,不 renew、不 reload。
|
||||
4. P0:把 workflow / runner / secret name owner response 與高價值配置 C0 gate 串成同一個 IwoooS 狀態。
|
||||
5. P1:盤點 110 / 188 Docker Compose 與 systemd live config,標記 Harbor、Sentry、Langfuse、Gitea、agent-bounty-protocol 影響面。
|
||||
6. P1:盤點 Prometheus / Alertmanager / Grafana / SigNoz / Sentry 設定 drift 與 secret externalization。
|
||||
7. P1:補 Kali 112、111、168 維護窗口 owner 欄位,仍不做 upgrade / restart / scan。
|
||||
8. P2:把 `/zh-TW/iwooos` 配置控管摘要產品化,但不得顯示內部工作對話、token、secret 或可執行按鈕。
|
||||
|
||||
## 8. 邊界
|
||||
|
||||
|
||||
665
docs/security/high-value-config-change-gate.snapshot.json
Normal file
665
docs/security/high-value-config-change-gate.snapshot.json
Normal file
@@ -0,0 +1,665 @@
|
||||
{
|
||||
"changed_files": [
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"category_id": "security_evidence_tooling",
|
||||
"control_tier": "C3",
|
||||
"label": "Security evidence / snapshot / guard tooling",
|
||||
"priority": "P3",
|
||||
"required_gate": "security_evidence_owner_review_required",
|
||||
"required_validation": [
|
||||
"snapshot_parse",
|
||||
"guard_smoke",
|
||||
"doc_secret_sanity",
|
||||
"no_runtime_gate_increase"
|
||||
]
|
||||
}
|
||||
],
|
||||
"matched": true,
|
||||
"path": "docs/LOGBOOK.md",
|
||||
"strongest_priority": "P3",
|
||||
"strongest_tier": "C3"
|
||||
},
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"category_id": "security_evidence_tooling",
|
||||
"control_tier": "C3",
|
||||
"label": "Security evidence / snapshot / guard tooling",
|
||||
"priority": "P3",
|
||||
"required_gate": "security_evidence_owner_review_required",
|
||||
"required_validation": [
|
||||
"snapshot_parse",
|
||||
"guard_smoke",
|
||||
"doc_secret_sanity",
|
||||
"no_runtime_gate_increase"
|
||||
]
|
||||
}
|
||||
],
|
||||
"matched": true,
|
||||
"path": "docs/security/HIGH-VALUE-CONFIG-CHANGE-GATE.md",
|
||||
"strongest_priority": "P3",
|
||||
"strongest_tier": "C3"
|
||||
},
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"category_id": "security_evidence_tooling",
|
||||
"control_tier": "C3",
|
||||
"label": "Security evidence / snapshot / guard tooling",
|
||||
"priority": "P3",
|
||||
"required_gate": "security_evidence_owner_review_required",
|
||||
"required_validation": [
|
||||
"snapshot_parse",
|
||||
"guard_smoke",
|
||||
"doc_secret_sanity",
|
||||
"no_runtime_gate_increase"
|
||||
]
|
||||
}
|
||||
],
|
||||
"matched": true,
|
||||
"path": "docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md",
|
||||
"strongest_priority": "P3",
|
||||
"strongest_tier": "C3"
|
||||
},
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"category_id": "security_evidence_tooling",
|
||||
"control_tier": "C3",
|
||||
"label": "Security evidence / snapshot / guard tooling",
|
||||
"priority": "P3",
|
||||
"required_gate": "security_evidence_owner_review_required",
|
||||
"required_validation": [
|
||||
"snapshot_parse",
|
||||
"guard_smoke",
|
||||
"doc_secret_sanity",
|
||||
"no_runtime_gate_increase"
|
||||
]
|
||||
}
|
||||
],
|
||||
"matched": true,
|
||||
"path": "docs/security/high-value-config-change-gate.snapshot.json",
|
||||
"strongest_priority": "P3",
|
||||
"strongest_tier": "C3"
|
||||
},
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"category_id": "security_evidence_tooling",
|
||||
"control_tier": "C3",
|
||||
"label": "Security evidence / snapshot / guard tooling",
|
||||
"priority": "P3",
|
||||
"required_gate": "security_evidence_owner_review_required",
|
||||
"required_validation": [
|
||||
"snapshot_parse",
|
||||
"guard_smoke",
|
||||
"doc_secret_sanity",
|
||||
"no_runtime_gate_increase"
|
||||
]
|
||||
}
|
||||
],
|
||||
"matched": true,
|
||||
"path": "scripts/security/high-value-config-change-gate.py",
|
||||
"strongest_priority": "P3",
|
||||
"strongest_tier": "C3"
|
||||
}
|
||||
],
|
||||
"control_category_inventory": [
|
||||
{
|
||||
"category_id": "nginx_public_gateway",
|
||||
"control_tier": "C0",
|
||||
"label": "Nginx / reverse proxy / public route",
|
||||
"path_patterns": [
|
||||
"infra/ansible/roles/nginx/templates/*.j2",
|
||||
"infra/ansible/playbooks/nginx-sync.yml",
|
||||
"ops/nginx/**",
|
||||
"docs/runbooks/disaster-recovery/DR-Nginx.md"
|
||||
],
|
||||
"priority": "P0",
|
||||
"required_gate": "public_gateway_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"rendered_diff",
|
||||
"nginx_t",
|
||||
"affected_route_smoke",
|
||||
"admin_route_smoke_if_affected",
|
||||
"acme_path_smoke_if_affected",
|
||||
"rollback_ref"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "dns_tls_certbot",
|
||||
"control_tier": "C0",
|
||||
"label": "DNS / TLS / certbot / certificate path",
|
||||
"path_patterns": [
|
||||
"docs/runbooks/REGISTRY-CERTBOT-188.md",
|
||||
"docs/runbooks/**/*CERTBOT*.md",
|
||||
"docs/runbooks/**/*TLS*.md",
|
||||
"ops/**/*cert*",
|
||||
"ops/**/*tls*",
|
||||
"infra/**/*cert*",
|
||||
"infra/**/*tls*",
|
||||
"k8s/**/*tls*"
|
||||
],
|
||||
"priority": "P0",
|
||||
"required_gate": "domain_tls_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"domain_inventory",
|
||||
"certificate_path_check",
|
||||
"renewal_window",
|
||||
"acme_path_smoke",
|
||||
"public_https_smoke",
|
||||
"rollback_ref"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "k8s_production_gitops",
|
||||
"control_tier": "C0",
|
||||
"label": "K8s / ArgoCD / production manifests",
|
||||
"path_patterns": [
|
||||
"k8s/awoooi-prod/**",
|
||||
"k8s/argocd/**",
|
||||
"k8s/velero/**",
|
||||
"k8s/monitoring/**"
|
||||
],
|
||||
"priority": "P0",
|
||||
"required_gate": "gitops_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"gitops_diff",
|
||||
"argocd_health_readback",
|
||||
"sync_authorization_check",
|
||||
"rollback_revision",
|
||||
"post_deploy_health_if_executed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "secret_metadata",
|
||||
"control_tier": "C0",
|
||||
"label": "Secret metadata / injection / redaction",
|
||||
"path_patterns": [
|
||||
"k8s/**/*secret*",
|
||||
"k8s/**/*Secret*",
|
||||
".gitea/workflows/*.yml",
|
||||
".gitea/workflows/*.yaml",
|
||||
".github/workflows/*.yml",
|
||||
".github/workflows/*.yaml",
|
||||
"docs/runbooks/SECRETS-MANAGEMENT.md",
|
||||
"docs/security/SECRETS_REFERENCE.md"
|
||||
],
|
||||
"priority": "P0",
|
||||
"required_gate": "secret_metadata_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"secret_name_parity",
|
||||
"metadata_only_check",
|
||||
"no_secret_value_check",
|
||||
"rotation_owner",
|
||||
"injection_readback_if_deployed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "gitea_workflow_runner_source_control",
|
||||
"control_tier": "C0",
|
||||
"label": "Gitea workflow / runner / deploy key / webhook / branch protection",
|
||||
"path_patterns": [
|
||||
".gitea/workflows/**",
|
||||
".github/workflows/**",
|
||||
"ops/runner/**",
|
||||
"scripts/setup-runner*.sh",
|
||||
"scripts/**/*runner*",
|
||||
"docs/security/SOURCE-CONTROL-*",
|
||||
"docs/security/GITEA-*",
|
||||
"docs/security/GITHUB-*"
|
||||
],
|
||||
"priority": "P0",
|
||||
"required_gate": "workflow_source_control_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"workflow_diff",
|
||||
"runner_label_owner",
|
||||
"deploy_key_metadata_only",
|
||||
"webhook_metadata_only",
|
||||
"branch_protection_metadata",
|
||||
"no_token_value_check"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "public_admin_api_runtime_config",
|
||||
"control_tier": "C0",
|
||||
"label": "Public / admin / API / frontend runtime config",
|
||||
"path_patterns": [
|
||||
"apps/web/next.config.*",
|
||||
"apps/web/src/lib/config.*",
|
||||
"apps/api/src/core/config.py",
|
||||
"apps/api/src/api/v1/monitoring.py",
|
||||
"apps/api/src/middleware/**",
|
||||
"apps/web/src/middleware.*"
|
||||
],
|
||||
"priority": "P0",
|
||||
"required_gate": "public_runtime_config_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"public_url_check",
|
||||
"frontend_internal_ip_ban",
|
||||
"cors_boundary_check",
|
||||
"admin_auth_boundary_check",
|
||||
"desktop_mobile_smoke_if_frontend"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "backup_restore_credential",
|
||||
"control_tier": "C0",
|
||||
"label": "Backup / restore / escrow / retention",
|
||||
"path_patterns": [
|
||||
"scripts/backup/**",
|
||||
"k8s/velero/**",
|
||||
"docs/runbooks/disaster-recovery/**",
|
||||
"docs/runbooks/**/*RESTORE*.md",
|
||||
"docs/runbooks/**/*BACKUP*.md"
|
||||
],
|
||||
"priority": "P0",
|
||||
"required_gate": "backup_restore_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"credential_absence_check",
|
||||
"restore_drill_gate",
|
||||
"retention_policy",
|
||||
"escrow_owner",
|
||||
"rollback_ref"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "agent_bounty_protocol_runtime",
|
||||
"control_tier": "C0",
|
||||
"label": "agent-bounty-protocol runtime / MCP / A2A / treasury boundary",
|
||||
"path_patterns": [
|
||||
"docs/security/AGENT-BOUNTY-IWOOOS-ONBOARDING-HANDOFF.md",
|
||||
"docs/security/agent-bounty-iwooos-onboarding-handoff.snapshot.json",
|
||||
"docs/schemas/agent_bounty_iwooos_onboarding_handoff_v1.schema.json",
|
||||
"agent-bounty-protocol/**"
|
||||
],
|
||||
"priority": "P0",
|
||||
"required_gate": "agent_bounty_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"repo_owner_scope",
|
||||
"runtime_gate_false",
|
||||
"no_payout_or_treasury_execution",
|
||||
"no_mcp_a2a_runtime_execution",
|
||||
"redacted_evidence_refs_only"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "monitoring_alerting_observability",
|
||||
"control_tier": "C1",
|
||||
"label": "Prometheus / Alertmanager / Grafana / SigNoz / Sentry / Langfuse",
|
||||
"path_patterns": [
|
||||
"ops/monitoring/**",
|
||||
"ops/alertmanager/**",
|
||||
"ops/grafana/**",
|
||||
"ops/signoz/**",
|
||||
"ops/sentry-self-hosted/**",
|
||||
"infra/langfuse/**",
|
||||
"k8s/monitoring/**"
|
||||
],
|
||||
"priority": "P1",
|
||||
"required_gate": "monitoring_observability_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"rule_diff",
|
||||
"receiver_diff",
|
||||
"reload_gate",
|
||||
"failure_notification_policy",
|
||||
"public_route_smoke_if_affected"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "docker_compose_systemd_host_config",
|
||||
"control_tier": "C1",
|
||||
"label": "Docker Compose / systemd / host service config",
|
||||
"path_patterns": [
|
||||
"docker-compose*.yml",
|
||||
"docker-compose*.yaml",
|
||||
"ops/**/docker-compose*.yml",
|
||||
"ops/**/docker-compose*.yaml",
|
||||
"scripts/reboot-recovery/**",
|
||||
"scripts/**/*.service",
|
||||
"ops/**/*.service"
|
||||
],
|
||||
"priority": "P1",
|
||||
"required_gate": "host_service_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"port_conflict_check",
|
||||
"volume_diff",
|
||||
"env_name_diff",
|
||||
"restart_window",
|
||||
"rollback_owner"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "ssh_firewall_network_access",
|
||||
"control_tier": "C1",
|
||||
"label": "SSH / sudoers / known_hosts / firewall / WireGuard / NodePort",
|
||||
"path_patterns": [
|
||||
"infra/ansible/inventory/**",
|
||||
"infra/ansible/**/*known_hosts*",
|
||||
"infra/ansible/**/*ssh*",
|
||||
"scripts/**/*ssh*",
|
||||
"scripts/**/*known_hosts*",
|
||||
"ops/**/*wireguard*",
|
||||
"ops/**/*firewall*",
|
||||
"k8s/**/*network*",
|
||||
"k8s/**/*Network*"
|
||||
],
|
||||
"priority": "P1",
|
||||
"required_gate": "network_access_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"target_whitelist",
|
||||
"host_key_policy",
|
||||
"ingress_egress_matrix",
|
||||
"rollback_owner",
|
||||
"maintenance_window"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "ai_provider_model_routing",
|
||||
"control_tier": "C1",
|
||||
"label": "AI provider / model routing / Ollama proxy / cost and privacy",
|
||||
"path_patterns": [
|
||||
"apps/api/src/services/ai_providers/**",
|
||||
"apps/api/src/services/**/*model*",
|
||||
"apps/api/src/services/**/*provider*",
|
||||
"infra/ansible/roles/nginx/templates/110-ollama-proxy.conf.j2",
|
||||
"docs/ai/**",
|
||||
"docs/**/*Ollama*"
|
||||
],
|
||||
"priority": "P1",
|
||||
"required_gate": "ai_provider_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"dry_run",
|
||||
"benchmark",
|
||||
"cost_review",
|
||||
"privacy_review",
|
||||
"fallback_order_check"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "product_surface_runtime_routes",
|
||||
"control_tier": "C2",
|
||||
"label": "AWOOOI / AwoooP / IwoooS / VibeWork / other product runtime routes",
|
||||
"path_patterns": [
|
||||
"apps/web/src/app/**",
|
||||
"apps/web/messages/*.json",
|
||||
"docs/security/VIBEWORK-IWOOOS-ONBOARDING-HANDOFF.md",
|
||||
"docs/security/vibework-iwooos-onboarding-handoff.snapshot.json"
|
||||
],
|
||||
"priority": "P2",
|
||||
"required_gate": "product_surface_owner_response_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"product_boundary_check",
|
||||
"i18n_traditional_chinese_check",
|
||||
"no_internal_transcript_check",
|
||||
"desktop_mobile_smoke_if_frontend"
|
||||
]
|
||||
},
|
||||
{
|
||||
"category_id": "security_evidence_tooling",
|
||||
"control_tier": "C3",
|
||||
"label": "Security evidence / snapshot / guard tooling",
|
||||
"path_patterns": [
|
||||
"docs/security/**",
|
||||
"docs/schemas/**",
|
||||
"scripts/security/**",
|
||||
"docs/LOGBOOK.md"
|
||||
],
|
||||
"priority": "P3",
|
||||
"required_gate": "security_evidence_owner_review_required",
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"required_validation": [
|
||||
"snapshot_parse",
|
||||
"guard_smoke",
|
||||
"doc_secret_sanity",
|
||||
"no_runtime_gate_increase"
|
||||
]
|
||||
}
|
||||
],
|
||||
"diff": {
|
||||
"base": null,
|
||||
"changed_file_count": 5,
|
||||
"head": "HEAD"
|
||||
},
|
||||
"execution_boundaries": {
|
||||
"active_scan_executed": false,
|
||||
"dns_tls_modified": false,
|
||||
"host_write_executed": false,
|
||||
"nginx_reload_executed": false,
|
||||
"runtime_deploy_executed": false,
|
||||
"runtime_gate_opened": false,
|
||||
"secret_value_collected": false,
|
||||
"ssh_executed": false,
|
||||
"workflow_modified": false
|
||||
},
|
||||
"generated_at": "2026-06-11T12:30:00+08:00",
|
||||
"git_commit": "e1cacdf3",
|
||||
"impacted_categories": [
|
||||
{
|
||||
"category_id": "security_evidence_tooling",
|
||||
"control_tier": "C3",
|
||||
"label": "Security evidence / snapshot / guard tooling",
|
||||
"priority": "P3",
|
||||
"required_gate": "security_evidence_owner_review_required",
|
||||
"required_validation": [
|
||||
"snapshot_parse",
|
||||
"guard_smoke",
|
||||
"doc_secret_sanity",
|
||||
"no_runtime_gate_increase"
|
||||
]
|
||||
}
|
||||
],
|
||||
"mode": "classification_only",
|
||||
"next_steps": [
|
||||
"若 impacted_c0_category_count > 0,先建立 owner response packet,不得直接 reload、deploy、sync 或修改主機。",
|
||||
"owner response 必須包含 owner role / team、decision、decision reason、affected scope、redacted evidence refs、followup owner、rollback owner、maintenance window 與 validation plan。",
|
||||
"若只有 C3 security evidence / tooling,仍需跑 guard 與 doc secret sanity,但不得藉此提高 runtime gate。"
|
||||
],
|
||||
"owner_evidence_validation": {
|
||||
"complete": false,
|
||||
"invalid_false_flags": [],
|
||||
"missing_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"note": "未提供 owner response evidence;本階段只能分類,不得執行 runtime 變更。",
|
||||
"provided": false
|
||||
},
|
||||
"required_false_flags": [
|
||||
"runtime_execution_authorized",
|
||||
"host_write_authorized",
|
||||
"secret_value_collection_allowed",
|
||||
"workflow_modification_authorized",
|
||||
"runner_change_authorized",
|
||||
"refs_sync_authorized",
|
||||
"force_push_authorized",
|
||||
"active_scan_authorized",
|
||||
"action_buttons_allowed"
|
||||
],
|
||||
"required_owner_fields": [
|
||||
"owner_role_team",
|
||||
"decision",
|
||||
"decision_reason",
|
||||
"affected_scope",
|
||||
"redacted_evidence_refs",
|
||||
"followup_owner",
|
||||
"rollback_owner",
|
||||
"maintenance_window",
|
||||
"validation_plan"
|
||||
],
|
||||
"schema_version": "high_value_config_change_gate_v1",
|
||||
"summary": {
|
||||
"changed_file_count": 5,
|
||||
"impacted_c0_category_count": 0,
|
||||
"impacted_c1_category_count": 0,
|
||||
"impacted_category_count": 1,
|
||||
"matched_high_value_file_count": 5,
|
||||
"owner_evidence_complete": false,
|
||||
"owner_evidence_provided": false,
|
||||
"runtime_execution_authorized": false,
|
||||
"strongest_priority": "P3",
|
||||
"strongest_tier": "C3"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user