# 风险接受记录 — 单人运维场景（2026-06-04）

## 背景

Nexus 全量 Code Review（批次 1～3）完成后，有两项被标记为「刻意未纳入」，需更大协议变更或 Agent 全站迁移：

1. WebSocket JWT 仍通过 query 传递（ADR-011）
2. Agent 认证保留 global `API_KEY` 对未分配 `agent_api_key` 服务器的 legacy 回退

**运营事实（2026-06-04 确认）**：后台仅 **一名** 操作员自用，无多人共享账号、无外包运维、无多租户。操作员即系统 owner，管理员身份视为完全可信。

本文档记录在该威胁模型下的**正式风险接受**与重评条件，避免后续审计或接续开发误将两项抬为 P0。

---

## 威胁模型（单人运维）

| 维度 | 假设 |
|------|------|
| 后台用户 | 仅 1 人，可信 |
| 内鬼 / 权限滥用 | 不适用 |
| 主要防护目标 | 外网未授权访问、安装/认证漏洞、多 worker 竞态、子机 Agent M2M 密钥管理 |
| 日志访问 | Nginx/宝塔等 access log 仅 operator 可阅，不外发第三方 |

---

## 接受项 1：WebSocket JWT query（ADR-011）

### 现状

- `/ws/alerts`、`/ws/sync`、`/ws/terminal/{id}` 均在握手 URL 使用 `?token=...`
- 设计依据：ADR-011；浏览器 WebSocket 无法自定义 Authorization Header
- 批次 3 已统一：缺失 token → **4001**；无效/过期 JWT → **4401**

### 接受理由

- Token 仅在 operator 登录后由其浏览器持有，无「不可信管理员」场景
- 改首帧鉴权 / WS ticket / 子协议需前后端同发、三条通道联测，**单人自用 ROI 极低**
- 残余风险（access log 留存 JWT、DevTools 可见）在「仅 operator 可读日志」前提下可接受

### 残余风险

- 本机恶意软件可窃取 session（与 token 在 query 或 Header 无本质差别）
- 若未来日志外发 SIEM/第三方，URL 中的 JWT 成为额外泄露面

### 重评触发条件

- 新增第二管理员或外包运维
- 等保/客户安全审计要求「凭证不得出现在 URL」
- access log 外发或多人可读
- 后台改为多租户或 SaaS 形态

### 决定

**维持 ADR-011，不排 WS 协议改造。**

---

## 接受项 2：Agent global API_KEY legacy 回退

### 现状

- 子机 Agent 通过 `X-API-Key` 调用 `/api/agent/heartbeat`（无 JWT、无后台登录）
- 认证逻辑（`server/api/agent.py`）：
  1. 服务器必须存在
  2. 若已分配 `agent_api_key` → 必须匹配 per-server key
  3. **Legacy**：未分配 per-server key → 仍接受 global `API_KEY`（写 warning 日志）
- 批次 3 已收紧：未知 `server_id` 拒绝；DB 查服异常 fail-closed

### 接受理由

- 与「后台几人用」无关，但单人运维下 global key 分发面可控（`.env`、安装脚本、子机 `config.json`）
- 硬禁用 global 回退可能导致大量 legacy Agent 心跳 401，**可用性风险大于当前威胁**
- 已有 per-server key 的服务器已与 global 隔离

### 残余风险

- global `API_KEY` 若从备份、误提交、子机配置泄露，攻击者可对 **尚未分配 `agent_api_key`** 的服务器伪造心跳（污染在线状态/监控数据，非 RCE）
- 攻击者需同时能访问中心 API 地址并持有 key

### 缓解（已实施）

- 未知 server_id 不再接受 global 冒充
- 新装/生成 key 流程优先 per-server（`POST /servers/{id}/agent-key`）
- legacy 使用 global 时服务器日志告警，便于逐步迁移

### 重评触发条件

- global key 疑似或确认泄露
- 计划轮换 `API_KEY`
- 新装 Agent 100% per-server 且存量迁移完成
- 监控/告警数据完整性成为合规要求

### 决定

**保留 legacy global 回退；不排硬禁用。** 有空时可做摸底（`agent_api_key IS NULL` 数量）与渐进迁移，非阻塞项。

---

## 仍须保持的修复（与单人场景无关）

以下项已在 Code Review 批次 1～3 修复，属于**稳定性/外网暴露**问题，不因单人运维而降级：

- Sync/脚本并行任务 AsyncSession 竞态
- 安装向导 create-admin 鉴权窗口
- schedule/retry 多 worker 重复执行
- 登录开放重定向、推送 WS 断线与 logout 码
- Settings 敏感项脱敏、Agent unknown server 拒绝等

---

## 变更记录

| 日期 | 说明 |
|------|------|
| 2026-06-04 | 初始记录；operator 确认单人自用后台 |

---

## 引用

- ADR-011：`docs/project/roadmap.md`（WebSocket JWT query）
- Code Review 批次 3：`docs/changelog/2026-06-04-code-review-p1-p2-batch3.md`
- 本记录 changelog：`docs/changelog/2026-06-04-risk-acceptance-single-operator.md`
- AI 接续：`docs/project/AI-HANDOFF-2026-05-23.md` §7b · `docs/project/AI-HANDOFF-2026-06-03.md` §Code Review 收尾
- Agent 认证实现：`server/api/agent.py` — `_verify_server_api_key`
