# FR-039 Agent 認證 v2 — BE track 收尾 SUMMARY（2026-06-19）

> 範圍：BE 主導，跨 evidence-agent / FE。把 cloud↔agent 從 demo 無認證升級成
> 自我註冊 + 憑證簽發 + mTLS + 短效 JWT + 設備指紋，全程 `AGENT_AUTH_MODE` 包覆。
> **I2 端到端對真實 agent 驗證通過，本期完成。**

## 1. 完成範圍
| Track | 項目 | 狀態 |
|-------|------|:----:|
| BE | A0 migration / B1 util / B2~B4·B6 端點 / B5 資料面 / I1 PKI 腳本 | ✅ |
| BE | 身分模型 v3(決策 B):身分鍵 device_fingerprint → 伺服器發的 agent_uid | ✅ |
| Agent | G1~G3(指紋/註冊/心跳/資料面) + v3(心跳帶 uid、404 自動重註冊、空憑證防呆) | ✅ |
| FE | F1~F3(設備清單/token 管理/撤銷) + 移除 rebind + 對齊錯誤碼 | ✅ |
| 整合 | I2 六情境端到端(真實 agent + nginx mTLS) | ✅ |

## 2. commits（BE，本 session 主要）
- 功能：`ace55e01`(B1) `45406104`(B2~B4/B6) `7228c419`(B5) `4f5c9525`(I1) `3b6ffde3`(v3) `605d38d4`(v3 決策紀錄)
- 權限：`69c71abc`(改 RBAC，移除 is_admin 硬檢查)
- I2 修正：`fa0ef1cd`→`c0fbde9e`(mTLS client 憑證 SSLContext) `23dabbb4`(診斷 log) `ff1fd6b5`(下載走檔案自己的 agent)
- 跨 repo：Agent `a3c076f`/`d71af4e`/`0207734`；FE `ae128b7`/`16c662b`/`137f203`

## 3. 行為差異（demo → full）
- **控制面**：agent 開機算 device_uuid → POST /agents/register(token+CSR) → 拿 server 憑證 + agent_uid → 每 N 秒 heartbeat（mTLS）。
- **資料面**：cloud→agent /blob 走 https + mTLS（雲端 client cert）+ 綁定短效 JWT + agent 驗 `X-Agent-Fingerprint` + 擋 revoked。
- **身分**：用 agent_uid（穩定），換硬體指紋自動更新、不冒新列、不需 rebind；平台刪該列 → agent 自動重註冊。
- **mode=none**：以上全部略過，維持現狀 demo。

## 4. 規範文件
- changelog：`docs/changelog/2026-06-19-fr039-agent-auth-v2-be.md`（feat）、`...-dataplane-mtls-download-i2-fixes.md`（fix）
- analysis：`docs/analysis/2026-06-19-fr039-agent-identity-v3-uid-vs-fingerprint.md`（v3 取捨）
- 設計：`design-agent-auth.md`（§5(6) 標 v3 修訂）；契約 + I2 Log 在本資料夾 TRACKER

## 5. 部署 handover（一律 mode=full / mTLS）
> **完整操作手冊：[`evidence-agent/deploy/README.md`](../../../../../evidence-agent/deploy/README.md)**（架構/PKI/註冊/啟動順序/驗證/維運/錯誤對照）。下為摘要。
- **BE**：`scripts/gen_agent_dev_pki.py` 產 PKI → `.env` 填 `AGENT_*` + `AGENT_AUTH_MODE=full` → 重啟。
- **Agent**：`evidence-agent/deploy/`（Linux）—— build image、填 `.env`（CLOUD_ENDPOINT/REGISTRATION_TOKEN/AGENT_BASE_URL=https://<ip>:8443）、`collect-host-id.sh`、`docker compose up -d file-agent agent-db` →（enroll 後）`--profile full up -d nginx`。
- ⚠️ **agent 重新註冊後一定要 `docker compose restart nginx`**（nginx 啟動時讀憑證，不會自動重讀）。
- **心跳間隔由 BE `AGENT_HEARTBEAT_INTERVAL_SEC` 決定**（register 時回傳），不是 agent 端。
- **同一個 tenant 內做完整流程**：上傳/下載要在同 tenant（storage-config per-tenant）。

## 6. 驗證（I2）
三層認證以反例實測擋下：無 client 憑證→400；mTLS 無 JWT→401(401001)；JWT 垃圾→401(401002)；指紋綁錯→401(401003)；全對→200。上傳/下載/預覽/刪除/撤銷/重新註冊/指紋自動更新皆通。

## 7. 已知 follow-up（非阻塞，另案）
1. **`_to_https` 脆弱點**：無腦 http→https 不換 port，指到純 http agent 會變看不懂的 SSL 錯 → 應明確報設定錯。
2. **MinIO 持久化**：測試中 bucket 舊物件消失（agent ↔ 客戶 MinIO 環境，非本 code）。
3. **agent 心跳 client 憑證**也用 httpx 0.28 `Client(cert=)`（同 BE bug），目前控制面走 http 不受影響；若控制面改 mTLS https 需比照改 SSLContext。
