依 autoflow-agent workspace v2 設計把 PRD / 設計 / 架構 / 交付類 共享文件從個人層 .autoflow/(ignored)搬到 docs/autoflow/(進 git), 讓團隊可共享產品與架構文件,個人層只留 progress / review / testing 等 per-branch 筆記。 - 02-prd/ 21 個檔(PRD、features、market-analysis 等) - 03-design/ 18 個檔(design-spec、wireframes、flows 等) - 04-architecture/ 31 個檔(TDD、design-doc、ADR×14、API 規格等) - 07-delivery/ 3 個檔(project-summary、phase-0.6-handover、stage-deployment-setup) 合計 73 檔。原檔已從 .autoflow/ 移除(migration 工具執行 git mv, 但因 .autoflow/ 在 .gitignore 中、git 將此操作視為新增、無 rename history)。
7.0 KiB
7.0 KiB
Feature:Pairing 流程(P0,雛形必做)
父文件:PRD.md | 對應 User Stories:US-04、US-05、US-06、US-18、US-19
概述
Pairing 是 visionA Cloud 獨有的流程(local-tool 沒有):把使用者筆電上的 local agent 連到 visionA Cloud 的 remote-proxy,讓雲端能代管該裝置。
這個流程替代了 POC 中「Token = SHA256(MAC)[:16]」的硬編碼方式,改為雲端發 token、綁 user + device、有 expiry、可撤銷的產品化版本。
使用者行為
正向流程(Happy Path)
- 使用者在瀏覽器登入 visionA Cloud
- 在「裝置」頁面點「配對新裝置」
- 彈出對話框,顯示:
- 一組 Pairing Token(例如
vAc_7f3c8e2a9b1d0f5e...) - QR code(方便手機掃或直接貼)
- 說明文字:「在你的 local agent 貼上這個 token」
- 倒數計時:「15 分鐘內要完成配對」
- 一組 Pairing Token(例如
- 使用者打開筆電上的 local-tool
- (Phase 0 妥協)手動編輯 local-tool 的設定檔,填入:
VISIONA_RELAY_URL=wss://relay.visiona.cloudVISIONA_PAIRING_TOKEN=vAc_7f3c8e2a9b1d0f5e...- 重啟 local-tool
- local-tool 的 tunnel client 啟動,連到 remote-proxy
- remote-proxy 驗證 token → 找到對應 user → 記錄 device 已配對
- 雲端前端透過 WebSocket 收到「裝置上線」事件 → 即時更新裝置列表
- 使用者看到新裝置出現,完成配對
異常流程
A. Token 過期
- 超過 15 分鐘未完成配對 → local-tool 連線時 remote-proxy 回 403
- local-tool 顯示「Pairing Token 已過期,請重新取得」
- 使用者回雲端重新產生
B. Token 已被使用
- Token 預設為一次性。配對成功後不能再用
- 再次用同一 token → 回 409 Conflict
- 雲端 UI 提示「此 token 已使用」
C. Token 無效
- 亂打 token → 401 Unauthorized
D. 網路中斷後重連
- local-tool 已配對的裝置,tunnel 斷線後自動重連
- 重連時用的是 Session Token(長期),不是 Pairing Token(一次性)
- Session Token 在首次配對成功後由 remote-proxy 發給 local-tool,local-tool 存到本機 config
Token 設計
Pairing Token(一次性、短期)
| 屬性 | 值 |
|---|---|
| 格式 | vAc_ + 32 字元 hex(範例:vAc_7f3c8e2a9b1d0f5e...) |
| 產生者 | api-server |
| 儲存 | Phase 0:in-memory map;Phase 1:DB |
| TTL | 預設 15 分鐘(可調整) |
| 使用次數 | 1 次 |
| 綁定 | user_id(產生者) |
Session Token(長期、可撤銷)
| 屬性 | 值 |
|---|---|
| 格式 | vAs_ + 64 字元 hex |
| 產生者 | remote-proxy(首次 pairing 成功後發) |
| 儲存 | Phase 0:in-memory map;Phase 1:DB local-tool 端:寫入 config 檔 |
| TTL | 90 天(到期或使用者主動撤銷時失效) |
| 使用次數 | 無限(TTL 內每次重連共用) |
| 綁定 | user_id + device_id |
兩階段 TTL 設計:
- Pairing Token 階段:使用者在雲端產 token、貼到 local agent,15 分鐘內要完成首次連線,一次性使用
- Session Token 階段:local agent 首次連上 remote-proxy 後,由 remote-proxy 發 Session Token 寫入 local config;之後 tunnel 斷線重連、跨 session 維持長連線都用這把 token,90 天內有效
Phase 0 先做固定 90 天 TTL;Phase 1 加 rotation(到期前一段時間自動換新 token,避免使用者介入)。
為什麼分兩種 Token
- Pairing Token 一次性、短期 → 防止 token 洩漏的危害被放大(最壞情況只影響 15 分鐘)
- Session Token 長期 → 避免每次重連都要使用者介入,但 90 天 TTL 限制洩漏風險
- 兩階段模式類似 OAuth 的 authorization code + refresh token
介面契約(API 層面)
完整 API spec 由 Architect Agent 寫入 TDD,本文件只列出關鍵端點:
POST /api/pairing/generate
Request (需登入):
{}
Response 200:
{
"pairing_token": "vAc_7f3c8e2a9b1d0f5e...",
"expires_at": "2026-04-21T10:30:00Z",
"relay_url": "wss://relay.visiona.cloud/tunnel/connect"
}
WebSocket wss://relay.visiona.cloud/tunnel/connect?token={token}
流程:
- local-tool 發起 WebSocket 連線,帶 token(可能是 Pairing Token 或 Session Token)
- remote-proxy 驗證:
- 若是 Pairing Token:檢查未過期、未使用 → 發 Session Token(透過 WebSocket 首個 message 傳給 local-tool)→ 標記 Pairing Token 已使用
- 若是 Session Token:檢查未撤銷 → 接受連線
- 建立 yamux session(沿用 POC 的設計)
- 後續所有 HTTP/WebSocket 請求透過 yamux stream 轉發到 local agent
POST /api/devices/{device_id}/revoke (Phase 1)
功能:撤銷某 Session Token,強制該裝置斷線。
驗收條件(Phase 0)
- 登入後,裝置頁面的「配對新裝置」按鈕可點
- 點擊後彈出對話框,顯示 Pairing Token(明文 + QR code)
- Pairing Token 格式符合規範(
vAc_+ 32 hex) - Pairing Token TTL = 15 分鐘,過期後 local-tool 連不上
- local-tool 用正確 token 連線 → 成功建立 tunnel
- local-tool 用錯誤 / 過期 / 已使用的 token 連線 → 收到明確錯誤
- 配對成功後,雲端裝置列表 5 秒內顯示新裝置
- local-tool 收到 Session Token 並寫入本機 config
- Session Token 格式符合規範(
vAs_+ 64 hex) - Session Token TTL = 90 天,到期後 local-tool 連線被拒,需重新 pairing
- tunnel 斷線後,local-tool 用 Session Token 自動重連(TTL 內)
- 全流程繁體中文 UI
- TODO:Phase 0 不實作「撤銷」功能,但要在 UI 留按鈕(disabled)
Phase 0 的 TODO
- TODO 1:local-tool 端的整合 — Phase 0 先讓使用者手動編輯 config 檔;Phase 1 要在 local-tool 內建 UI「配對到 visionA Cloud」
- TODO 2:QR code 產生 — 可用前端套件(例如
qrcode.react),但優先級低,可先只顯示明文 token - TODO 3:Token 撤銷 — 介面留著,實作留到 Phase 1
- TODO 4:多 local agent 同時配對 — Phase 0 每個 user 最多 1 台 agent 同時連線,Phase 1 支援多台
- TODO 5:Session Token rotation — Phase 0 採固定 90 天 TTL(到期需重新 pairing);Phase 1 做到期前自動 rotation,無需使用者介入
- TODO 6:Pairing 流程的使用者引導(tutorial) — Phase 0 不做,Phase 1 加 onboarding
安全考量
Phase 0 最小要求:
- Token 必須透過 TLS(
wss://)傳輸,不能走明文 - Token 儲存在記憶體不要 log 出來
- Pairing Token 產生後不要再可讀取(只有產生當下顯示給使用者)
Phase 1 要加的:
- Token 在 DB 以 hash 儲存(不存明文)
- Rate limiting(防暴力破解)
- IP 地址記錄(配對時、連線時)
- 異常偵測(同一 token 從不同 IP 嘗試連線)