visionA/.env.dev.example
jim800121chen 86b7175649 feat(visionA-backend): Phase 0.8b 步驟 2 — visionA → converter / FAA 改 API key 認證
對齊 ADR-015:visionA backend 從 OAuth client_credentials 改 pre-shared API key 服務間認證。Phase 0.8 stage e2e 撞 4 個 blocker(MC scope 沒註冊 / converter image 舊版 / converter 缺 env / FAA 不確定)後,使用者拍板 1:1 internal trust 用 OAuth 過度設計,改 API key。

實作(5 個增量 task,T1-T5 全綠 + Reviewer 5 輪 + final cross-task review):

T1 config + env:
- ConversionConfig 新增 ConverterAPIKey / FAAAPIKey 欄位
- Enabled() 改判定 4 欄位齊全(含兩個 API key)
- .env*.example 移除 OIDC service client / OIDC tenant / FAA delegated TTL env、新增 API key env
- TenantID / DelegatedTTLSeconds T1 暫留、T5 整批清

T2 client 改造:
- converter_client / faa_client 移除 MCTokenClient 依賴
- 直接讀 cfg.Conversion.{Converter,FAA}APIKey、set Authorization: Bearer <key>
- NewConverterClient / NewFAAClient APIKey 為空時 panic(fail-fast,對齊 ADR-015 §3.5.3 #1)
- 新增 ErrConverterAuthFailed / ErrFAAAuthFailed sentinel
- 對外 mask 成 converter_unavailable / faa_unavailable(不洩漏 401 細節,對齊 ADR-015 §3.5.3 #3)

T3 砍 mc_token_client:
- mc_token_client.go (624 行) + mc_token_client_test.go (864 行) 整檔砍
- 砍 5 個僅 mc_token_client 用的 sentinel(ErrServiceClientUnauthorized / ErrMCTokenUnavailable / ErrIDPMisconfigured / ErrIDPUnavailable / ErrDownloadTokenFailed)
- helper(truncate / silentLogger)搬到 util.go / testing_helpers_test.go

T4 flow + handler stream proxy:
- Service interface DownloadRedirectURL → DownloadStream(ctx) (io.ReadCloser, *DownloadMetadata, error)
- flow.DownloadStream 用 faa.GetFile 直接 stream NEF binary(取代 MC delegated token + 302)
- handler conversionDownloadHandler 改 io.Copy + Content-Type/Disposition/Cache-Control header
- 新增 sanitizeDownloadFilename helper 防 HTTP header injection
- 跨 package handler test (conversion_test.go) 改測 ErrFAAUnavailable + 補 *_AuthFailed 對稱 test

T5 wire 切換 + cleanup:
- main.go 砍 mcTokenClient wire、改 APIKey 注入、startup log 用 *_api_key_set boolean(不印 key)
- ConverterClient/FAAClient struct Tokens 欄位移除
- mc_token_stub.go (T4 過渡期) 整檔砍
- ConversionConfig TenantID / DelegatedTTLSeconds 欄位移除
- e2e_test.go TestConversionE2E_Download302Redirect 改寫為 TestConversionE2E_DownloadStream
- 補 MaxDownloadStreamBytes = 1 GiB size cap(io.CopyN,T4 reviewer Minor M-1)
- escapeObjectKeyPath Phase 1+ 預留 godoc + //nolint:unused(T4 reviewer Minor M-2)
- conversion.md §4.1 line 502 filename 來源描述歧義修訂(T4 reviewer Minor M-3,由 architect 處理)
- conversion_e2e_test.go 檔頭 docstring 更新(final reviewer Minor #1)

驗證:
- go build ./... exit 0
- go test -race -count=3 ./... 17 packages 全綠
- ADR-015 §6 砍除清單 100% cover(reviewer 獨立 grep 確認 MC chain / TenantID / DelegatedTTLSeconds 全清)
- ADR-015 §3.5.3 部署檢查清單 visionA 範圍 4/4 達成(fail-fast / mask / 不印 token / placeholder env)

不動:
- OIDCConfig.ServiceClientID/Secret 欄位保留(使用者拍板 backward compat)
- user login OIDC 完全不動

下一步:
- 步驟 4 — converter scheduler middleware 改 API key(jimchen 跨 repo,ADR-015 §3.5.1 Go snippet)
- 步驟 5 — FAA middleware 改 API key(warrenchen 跨 repo,ADR-015 §3.5.2 C# snippet)
- 步驟 6 — stage redeploy + e2e 完整測試

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 09:45:45 +08:00

98 lines
4.1 KiB
Plaintext
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.

# visionA dev 環境變數範本
#
# 使用方式:
# cp .env.dev.example .env.dev
# # 編輯 .env.dev填入 OAuth client_id / client_secret手動 seed 後產生)
# docker compose -f docker-compose.dev.yml --env-file .env.dev up -d
#
# 詳細步驟:見 docs/DEV-SETUP.md
#
# ⚠️ 不要 commit .env.dev已在 .gitignore 中排除)
# ============================================================
# Member Center
# ============================================================
# 預設用 ../member_center 路徑 build。如果你的 member_center 在別處,改這個。
# 例MEMBER_CENTER_PATH=/Users/me/code/member_center
MEMBER_CENTER_PATH=../member_center
# Member Center admin 帳號installer init 會建立)
# 之後可用這組帳密登入 MC admin UI / 拿 admin API token
MC_ADMIN_EMAIL=admin@visiona.local
MC_ADMIN_PASSWORD=Admin12345!
# ============================================================
# visionA OIDC client必須先在 MC 註冊,詳見 docs/DEV-SETUP.md
# ============================================================
# 第一次起來時這兩個值還沒有 → 先用 static auth 跑VISIONA_AUTH_TYPE=static
# OAuth client 註冊完後填入這兩個值 + 改 VISIONA_AUTH_TYPE=oidc → docker compose up -d 重啟
VISIONA_OIDC_CLIENT_ID=CHANGE_ME
VISIONA_OIDC_CLIENT_SECRET=CHANGE_ME
# Phase 0.8b 移除VISIONA_OIDC_SERVICE_CLIENT_ID / _SECRET
# 服務間認證visionA → converter / FAA改 pre-shared API keyADR-015
# 不再走 OAuth client_credentials grant所以 dev 也不需要 service client。
# 取代設定見下方 Phase 0.8 / 0.8b conversion 區塊。
# auth mode 切換static雛形預設/ oidc接 MC
VISIONA_AUTH_TYPE=static
# OIDC issuer / redirect — 預設值已對齊 MC 的 dev port
# ⚠️ trailing slash 不可省MC discovery 回的 issuer 帶 slash否則 client init 會 reject
VISIONA_OIDC_ISSUER_URL=http://localhost:5050/
VISIONA_OIDC_REDIRECT_URL=http://localhost:3721/api/auth/callback
# ============================================================
# Cookie / session
# ============================================================
# 至少 32 byte 隨機字串建議openssl rand -hex 32
VISIONA_SESSION_SECRET=please-change-me-32-bytes-random-dev-secret
# Frontend URLOIDC callback 完成後 redirect 回的目標)
VISIONA_FRONTEND_URL=http://localhost:3000
# ============================================================
# 既有 visionA-backend 環境變數(與 visionA-backend/.env.example 一致)
# ============================================================
VISIONA_LOG_LEVEL=info
VISIONA_API_PORT=3721
VISIONA_TUNNEL_PORT=3800
# Phase 0.7 security audit (2026-05-01) 後僅供 dev seed (VISIONA_SEED_DEMO_DATA=true) 與 unit test fixture 用;
# 已從 api.Deps 移除(見 .autoflow/05-implementation/review/phase-0.7-security-audit.md C1
# stage / prod 不需設定。
VISIONA_STATIC_USER_ID=demo-user
VISIONA_CORS_ALLOWED_ORIGINS=http://localhost:3000
VISIONA_SEED_DEMO_DATA=true
VISIONA_STORAGE_BASE_URL=http://localhost:3721/storage
# ⚠️ 生產必改openssl rand -hex 32
VISIONA_STORAGE_SIGNING_SECRET=dev-signing-secret-change-me-32-bytes
# Pairing token雛形仍用 static留空則動態配發
VISIONA_PAIRING_TOKEN=
# ============================================================
# Phase 0.8 / 0.8b — 轉檔功能整合dev 通常不啟用,留空即可)
# ============================================================
# 對齊 .autoflow/04-architecture/conversion.md §3 + ADR-015。
#
# 4 個欄位全部非空才會啟用 conversion 模組dev 全空 = sidebar tab 顯示但 endpoint 不註冊。
# 若要在 dev 連 stage 的 converter / FAA 測整合,依 .env.stage.example 模板填入。
#
# 產生 API keyopenssl rand -hex 32
# VISIONA_CONVERTER_BASE_URL=http://192.168.0.130:9501
# VISIONA_FAA_BASE_URL=http://192.168.0.130:5081
# VISIONA_CONVERTER_API_KEY=
# VISIONA_FAA_API_KEY=
# ============================================================
# 進階port 衝突時可改
# ============================================================
# POSTGRES_PORT=5432
# MEMBER_CENTER_PORT=5050