依據:design-agent-auth.md v2 + agent-auth-spec.html v2(以 CLIENT_SERVER_REGISTRATION.txt 為準)。 已完成:Phase 1(remote_agents 加 device_fingerprint + status,commit 1221c25f)。 平行策略:Wave 0 先做(共用契約,擋所有人)→ Wave 1 三 repo track 可不同 session 同步 → Wave 2 整合。 每個任務含「範圍 / 關鍵檔 / 依賴 / 驗收」,可單獨接手。全程 AGENT_AUTH_MODE=none 包覆,不破壞現有 demo。
⏸️ 退場先保留:現有「UI 手動新增 agent」+「測試連線 / 對帳」全部留著不動,v2 自我註冊加在旁邊並存(F1/F2/F3 都是新增,不移除既有功能)。未來再決定是否退場。
§1
Wave 0 — 共用契約(serial,1 任務,先做)
A0 · DB migration + API/憑證契約凍結
- 範圍:① migration:
remote_agents 加 last_seen_at TIMESTAMP、agent_version VARCHAR(50)、hardware_info JSONB;新表 compliance.remote_agent_enroll_tokens(tenant_id, token_hash, label, enabled, 審計)。② 寫死 API 契約(request/response JSON schema):POST /agents/register、POST /agents/heartbeat、cert 簽發(CSR→cert)、資料面 header(Authorization: Bearer <JWT> claims、X-Agent-Fingerprint)。
- 關鍵檔:
scripts/sql/2026-06-19-fr039-agent-enroll.sql、契約寫進 design 文件 §或一份 agent-auth-contracts.md。
- 依賴:無。這是大家 code 的介面,必須最先定。
- 驗收:migration 套 dev 成功;契約文件三 repo 都能照著刻。
§2
Wave 1 — 三 repo 平行(各 track 可獨立 session)
🟦 BE track(cloud,compliance-manager-be)
B1 · 憑證 / JWT 基礎 util
- 範圍:內部 CA + CSR 簽發 util(簽 agent server cert);JWT(RS256) mint/verify;key/CA 路徑設定(走 secret/env);
AGENT_AUTH_MODE(none|full)。
- 關鍵檔:
common/util/agent_auth/(新)、config。
- 依賴:A0。 驗收:能簽一張測試 cert、mint+verify JWT 單測過。
B2 · 註冊 token 管理
- 範圍:
remote_agent_enroll_tokens model/entity/mapper/repo + service(產生/重生/撤銷,存 hash)+ endpoints。
- 關鍵檔:
domain|infra|app|api/remote_agent/...(token 子模組)。
- 依賴:A0。 驗收:建/重生/撤銷 token;token 驗證回對應 tenant。
B3 · /agents/register(enrollment)
- 範圍:驗 token(B2) → upsert
remote_agents by (tenant_id, device_fingerprint)(含 base_url/hardware_info/agent_version)→ 簽發憑證(B1)回傳。
- 關鍵檔:
api/remote_agent/routes/...、app service。
- 依賴:A0 + B1 + B2。 驗收:帶 token POST register → DB upsert + 回 cert。
B4 · /agents/heartbeat + online/offline
- 範圍:更新
last_seen_at、status;online/offline 推算 helper(last_seen vs 門檻)。
- 依賴:A0。 驗收:heartbeat 更新 last_seen;清單能算出 online/offline。
B5 · 資料面認證(RemoteAgentAdapter)
- 範圍:mode=full 時 httpx 帶 client cert + verify CA + mint JWT(帶 bound device_uuid) + 驗回應
X-Agent-Fingerprint + status != revoked 檢查;mode=none 維持現狀。
- 關鍵檔:
infra/upload_file/remote_agent_adapter.py。
- 依賴:A0 + B1。 驗收:mode=full 對測試 agent 全鏈通;mode=none 不變。
B6 · 撤銷 / 重新綁定
- 範圍:
revoke/unrevoke(status)、rebind(更新 device_fingerprint) service + endpoint,manager 權限。
- 依賴:A0。 驗收:撤銷後雲端拒呼叫;重新綁定更新指紋。
🟩 Agent track(evidence-agent)
G1 · device_uuid 模組 + config
- 範圍:讀
/host/product_uuid+/host/machine-id+/host/mac → sha256 = device_uuid(快取);config 讀 token/endpoint/cert 路徑。
- 依賴:A0。 驗收:算出穩定 device_uuid;缺某來源 graceful。
G2 · 自我註冊 + 心跳迴圈
- 範圍:開機 → 產 keypair + CSR → POST register → 存雲端回傳憑證 → 定期 heartbeat。
- 依賴:A0 + G1。 驗收:對測試雲端 register 成功拿到 cert;定期 heartbeat。
G3 · 資料面認證 + TLS
- 範圍:before_request 驗 JWT(公鑰/exp/aud) + 指紋 self-check;回應加
X-Agent-Fingerprint;GET /agent-info;nginx sidecar 收 mTLS + compose 掛 certs/host 識別碼 + deploy/collect-host-id.sh。
- 依賴:A0 + G1。 驗收:無/錯 JWT 被擋;指紋不符被擋;mTLS 握手成功。
🟪 FE track(compliance-manager-fe)
F1 · 設備清單頁改版
- 範圍:設備自動出現(重新整理)、狀態欄 online/offline(由 last_seen)、active/revoked、指紋已綁定顯示。
- 依賴:A0(契約)。可先對 mock 開發。 驗收:清單顯示狀態 + 綁定。
F2 · 註冊 token 管理頁
- 範圍:檢視 / 重新產生 / 撤銷 per-tenant token(接 B2)。
- 依賴:A0。 驗收:UI 能管理 token。
F3 · 重新綁定 / 撤銷 鈕
- 範圍:管理頁加重新綁定 / 撤銷 / 復用 鈕(manager,接 B6)。
- 依賴:A0。 驗收:UI 觸發 + 結果回饋。
§3
Wave 2 — 整合驗證(serial,等三 track)
I1 · dev PKI 產生腳本
- 範圍:
scripts/agent-auth/gen-dev-pki.sh 產 CA / cloud client cert / JWT keypair(dev secret,不入版控)。
- 依賴:B1。 驗收:產物可被 BE+agent 載入。
I2 · 端到端驗證
- 範圍:build agent image + 部署 + 切
AGENT_AUTH_MODE=full → 驗:register→拿 cert→heartbeat→上傳/下載(mTLS+JWT+指紋)→撤銷即拒→重灌模擬指紋變被擋→重新綁定。
- 依賴:全部。 驗收:六情境全綠;測完還原 demo。
§4
總覽 / 平行計畫
- 總任務數:15(Wave0:1 / BE:6 / Agent:3 / FE:3 / Wave2:2)。
- 關鍵路徑:A0 → (B1,B2) → B3 → I1 → I2。
- 可平行:A0 完成後,BE / Agent / FE 三條 track 可分三個 session 同步開工(各自對 A0 契約刻)。BE 內 B1//B2 可平行,B4//B5//B6 多半獨立。
- 建議分配:Session-1=BE track、Session-2=Agent track、Session-3=FE track;A0 由其中一個 session 先做完再三方開工;I1/I2 收尾合做。