# FR-039 Agent 認證 v2 — 任務分解（可接手 / 可多 session 平行）

> 依據：`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 都是新增,不移除既有功能)。未來再決定是否退場。

---

## 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 都能照著刻。

---

## 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 觸發 + 結果回饋。

---

## 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。

---

## 總覽 / 平行計畫

- **總任務數：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 收尾合做。
