Files
awoooi/docs/awooop/inventory/INV-4-hardcoded-namespace-ip.md
Your Name 8629ac709b
Some checks failed
run-migration / migrate (push) Failing after 59s
Code Review / ai-code-review (push) Successful in 1m8s
Type Sync Check / check-type-sync (push) Successful in 2m27s
feat(awooop): Phase 1-8 完整實作 — AwoooP Agent Platform 六平面架構
## Phase 1-3: Control Plane + Contract System
- awooop_phase1_control_plane_2026-05-04.sql: 12 張核心表 + RLS
- awooop_phase1_batch1_rls_2026-05-04.sql: 全部 FORCE RLS + GRANT
- packages/awooop-contracts/: 六合約 JSON Schema + golden fixtures
- src/models/awooop_contracts.py: Pydantic v2 contract models(extra=forbid)
- src/repositories/contract_repository.py: contract lifecycle(draft→published→active)
- src/services/contract_service.py: HMAC publish sig + Redis multi-sig activate
- src/services/schema_validator.py: LLM output validator(retry×3, E-SCHEMA-001)

## Phase 2: Tenant Isolation
- awooop_phase2_budget_ledger_2026-05-04.sql: budget_ledger + RLS
- src/services/budget_service.py: Token Budget Hard Kill 三層防線
- src/core/context.py: PROJECT_ID ContextVar(31 background loop 自動繼承)
- src/db/base.py + models.py: project_id 欄位 + RLS set_config 注入
- src/hermes/nl_gateway.py: project_id Redis key 前綴(Phase A 雙寫)
- src/services/anomaly_counter.py: per-project 改造(Phase A fallback)

## Phase 4: Platform Shell in Shadow Mode
- awooop_phase4_run_state_2026-05-04.sql: run_state + step_journal + idempotency
- src/services/run_state_machine.py: 8-state FSM + SKIP LOCKED + stale reaper
- src/services/platform_runtime.py: UUID v7 + W3C trace_id + shadow_execute
- src/services/audit_sink.py: PII/secret redaction 9 patterns
- src/api/v1/platform/runs.py: POST/GET /v1/platform/runs(Router→Service 架構)
- src/workers/platform_worker.py: SKIP LOCKED worker + heartbeat + reaper loop
- src/main.py: platform router + lifespan worker start/stop

## Phase 5: MCP Gateway 五閘門
- awooop_phase5_mcp_gateway_2026-05-04.sql: 4 表 + RLS
- src/plugins/mcp/gateway.py: McpGateway(Gate 1~5, E-MCP-GATE-001~009)
- src/plugins/mcp/redaction_middleware.py: 雙層 redaction + 16K 截斷
- src/plugins/mcp/registry.py: __provider name mangling(ADR-116)
- src/plugins/mcp/credential_resolver.py: k8s secret ref 解析
- tests/test_mcp_credential_isolation.py: 10 個迴歸測試(secret leak 防再現)

## Phase 6-8: EwoooC + Channel Hub + Approval Token
- awooop_phase6_ewoooc_onboarding_2026-05-04.sql: ewoooc tenant + 4 read-only MCP tools
- awooop_phase7_channel_hub_2026-05-04.sql: conversation_event + outbound_message
- src/services/provider_proxy.py: ProviderProxy + PlatformEnvelope(ADR-115)
- src/services/channel_hub.py: Telegram inbound mirror + Progressive Feedback(30s)
- src/services/awooop_approval_token.py: HS256 + jti NX replay 防護 + suggest mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:53 +08:00

5.2 KiB
Raw Blame History

INV-4: Hardcoded Namespace & IP Inventory

版本v1.0 初稿 日期2026-05-03台北 範圍apps/api/src/ 全 codebase + k8s/ 用途Phase 2 多租戶改造 + EwoooC onboarding 前必須清理的硬碼


1. Hardcoded K8s Namespace

位置 行號 內容 影響 修補方式
apps/api/src/plugins/mcp/providers/k8s_provider.py 40-41 ALLOWED_NAMESPACES = {"awoooi-prod"} / DEFAULT_NAMESPACE = "awoooi-prod" 🔴 P0-13EwoooC K8s tool 無法操作自己的 namespace 改為 config-driven從 EffectivePolicy 或 project contract 讀 allowed namespaces
apps/api/src/plugins/mcp/mcp_bridge.py 592, 602, 631, 647, 681 namespace = parameters.get("namespace", "awoooi-prod") 🔴 P0-135 處預設值都寫死 改為 namespace = parameters.get("namespace", get_project_default_namespace(project_id))
apps/api/src/plugins/mcp/providers/signoz_provider.py 169 namespace = parameters.get("namespace", "awoooi-prod") 🟠 SignOz query 預設 namespace 錯誤 同上
apps/api/src/main.py 175 sentry_sdk.set_tag("host", "k8s-awoooi-prod") 🔵 Sentry tag 寫死EwoooC 看到錯誤 host tag 改為 settings.SENTRY_HOST_TAG
apps/api/src/core/prompts.py 120, 178, 192 系統 prompt 中出現 awoooi-prod 🔵 LLM 可能在其他 tenant 錯誤建議 awoooi-prod namespace 改為 {tenant_namespace} template variable

2. Hardcoded IP Addresses

內網 IP已知用途

IP 用途 位置 改法
192.168.0.110 Gitea / Prometheus / Loki / MinIO config.py:226,413,460,813 已在 config 以 default 存在OKK8s 覆蓋)
192.168.0.111 Ollama Local Fallback config.py + feedback_ollama_111_only.md(已更新) ADR-110 已改為第三層 fallbackconfig 需更新
192.168.0.112 ArgoCD config.py:396 OKconfig default
192.168.0.120 K3s API Server config.py:531 OKconfig default
192.168.0.121 K3s ingress config.py:837 確認用途
192.168.0.188 PostgreSQL / Redis / SigNoz / Grafana / ClickHouse config.py 多處 OKconfig defaultK8s 以 env 覆蓋)

🔴 問題telemetry.py IP Assertion

位置 行號 內容 問題
apps/api/src/core/telemetry.py 71 if "192.168.0.188" not in endpoint: raise 🔴 P0-08EwoooC 啟動必失敗EwoooC SigNoz 可能是不同 endpoint
修補方式 移除硬碼 assert改為 if endpoint not in settings.ALLOWED_TELEMETRY_ENDPOINTS:

GCP IP新增ADR-1102026-05-03 生效)

IP 用途 位置
34.143.170.20 Ollama GCP-A PrimarySSD config.pyADR-110 已加入 _ALLOWED_PUBLIC_IPS
34.21.145.224 Ollama GCP-B SecondarySSD config.pyADR-110 已加入 _ALLOWED_PUBLIC_IPS

注意

  • K8s NetworkPolicy egress已新增 GCP-A/GCP-B /32 出口規則ADR-110
  • INV-4 確認GCP IP 已在 config.py._ALLOWED_PUBLIC_IPS 白名單,非新增需求
  • telemetry.py:71 assertGCP IP 不影響assert 是針對 OTEL endpoint非 Ollama endpoint

3. SSH Host Hardcodes

位置 內容 問題 修補
reference_four_hosts.md 110/120/121/188 四主機清單 文件不是程式碼OK
apps/api/src/plugins/mcp/providers/ssh_provider.py(若有) SSH 目標主機 需 grep 確認是否硬碼 改為 config-driven 白名單

4. 其他硬碼字串

位置 內容 問題 修補
apps/api/src/core/config.py:625 default="192.168.0.188=ollama" Ollama-to-host mappingADR-110 後需更新 改為 192.168.0.188=ollama_old(僅 fallback 相關)
apps/api/src/core/config.py:828 default="192.168.0.188,192.168.0.110,192.168.0.111" 主機清單 確認用途,若是 monitoring target 需加 GCP IP

5. 改造策略Phase 2

K8s Namespace優先

# 方案project contract 中定義允許的 K8s namespaces
# awooop_projects.k8s_namespaces: ["awoooi-prod"]AWOOOI/ ["ewoooc-prod"]EwoooC
# k8s_provider.py 從 project contract 讀,而非硬碼

def get_allowed_namespaces(project_id: str) -> set[str]:
    contract = get_active_project_contract(project_id)
    return set(contract.allowed_k8s_namespaces)

Telemetry Endpoint AssertP0-08PR-01 優先)

# 修改前telemetry.py:71
if "192.168.0.188" not in endpoint:
    raise ValueError(f"Forbidden OTEL endpoint: {endpoint}")

# 修改後
allowed_endpoints = settings.ALLOWED_TELEMETRY_ENDPOINTS.split(",")
if not any(allowed in endpoint for allowed in allowed_endpoints):
    raise ValueError(f"Forbidden OTEL endpoint: {endpoint}")

6. 驗收標準

  • grep -r "192.168.0.188" apps/api/src/telemetry.py 的 assert 行消失
  • grep -r '"awoooi-prod"' apps/api/src/ 中的程式碼路徑(非 prompt 文字、非 comment結果為 0
  • k8s_provider.py ALLOWED_NAMESPACES 改為 config-driven
  • INV-4 中標記 GCP IP 已確認加入 NetworkPolicyADR-110 完成)

最後更新2026-05-03台北