Files

70 lines
2.8 KiB
Markdown
Raw Permalink Normal View History

# 审计 — 2026-06-07 BL-06 Agent per-server key 强制
## 范围
移除 Agent 认证 global `API_KEY` legacy 回退;涉及 3 个后端文件 + 1 个新测试文件。
| 文件 | 行数 | Read 范围 |
|------|------|-----------|
| `server/api/agent.py` | 379 | L40-93(认证函数) |
| `server/api/servers.py` | 2056 | L619-636, L1625-1640(安装链路) |
| `server/application/services/script_service.py` | 735 | L44-50(回调 key |
| `tests/test_agent_per_server_key.py` | 88 | 全文 |
| `tests/load_test.py` | 202 | 顶部 docstring |
| `tests/quick_load.py` | 87 | 顶部 docstring |
## Step 3 规则扫描
| H | 规则 | 结论 |
|---|------|------|
| H1 | Agent 认证 fail-closed | FIXED 移除 global 回退;无 per-server key → False |
| H2 | 安装链路静默降级 | FIXED 无 key 明确 400/批量错误项 |
| H3 | 长任务回调 key 泄露面 | FIXED 仅用 per-server key,无 global 回退 |
| H4 | compare_digest 时序安全 | SAFE 保留 `secrets.compare_digest` |
| H5 | DB 查服异常 | SAFE 保持 fail-closed return False |
## Closure
| H | 判定 | 依据 |
|---|------|------|
| H1 | FIXED | `agent.py:60-82``agent_api_key` 匹配 |
| H2 | FIXED | `servers.py:627-633`, `servers.py:1635-1637` |
| H3 | FIXED | `script_service.py:44-50` ValueError |
| H4 | SAFE | `agent.py:82` compare_digest |
| H5 | SAFE | `agent.py:68-76` except → False |
## 入口表(agent.py 受影响路由)
| 方法 | 路径 | 鉴权 |
|------|------|------|
| POST | `/api/agent/heartbeat` | X-API-Key + per-server `agent_api_key` |
| POST | `/api/agent/script-callback` | 同上 + job secret |
## 巡检补修(同日)
| 项 | 原问题 | 修复 |
|----|--------|------|
| H6 | `receive_heartbeat` 认证后再次 `get_server`(重复查库) | `_verify_server_api_key` 返回 `Optional[Server]`handler 复用 |
| H7 | 验 key 通过后 `unknown_server` discarded 分支为死代码 | 删除;不存在/无 key/错 key 统一 401 |
| H8 | `script-callback` docstring 仍写「per-server or global」 | 改为仅 per-server |
| H9 | 无回归测试约束 `get_server` 调用次数 | `test_verify_server_key_single_get_server_per_auth_check` + `assert_called_once_with` |
## 生产只读探测(2026-06-07
| 探测 | 结果 |
|------|------|
| `GET /health` | 200 |
| `POST /api/agent/heartbeat` 假 key | 401 |
| `security_probe_external.sh` heartbeat/WS | PASS |
注:BL-06 完整语义(global key 不可冒充)需部署本地改动后生产才生效;当前生产假 key 已 401。
## DoD
- [x] ruff 零错误(改动文件)
- [x] import server.main
- [x] pytest `test_agent_per_server_key.py` 9 passed(含 `assert_called_once`
- [x] changelog ≥10 行
- [x] 无静默吞错;无 global key 降级
- [x] 心跳路径单次 `get_server`(巡检补修)