docs: 完成任务 #45 待验收归档

ila
2026-08-25 09:58:31 +08:00
parent 875916f517
commit 6ab75e6d40
@@ -1,44 +1,62 @@
# 45 实现 API 安全审计与管理端 API
> 历史兼容模板:标准任务以 Gitea 工单保存实现、测试、提交和验收证据,不再创建 Wiki 任务归档。仅在用户明确要求专项历史快照时使用本模板。
- 类型:需求 / 缺陷 / 重构
- 所属 Epic:#
- 所属 MVP / 版本:#
- 状态:待验收 / 已完成
- 类型:需求
- 所属 Epic:#3
- 所属 MVP / 版本:#35 / MVP-2
- 状态:待验收
- 日期:2026-08-25
- Gitea 工单:https://git.ilapage.cn/OPC/chorus/issues/45
- Wiki 页面:Task-45-实现-API-安全审计与管理端-API
- Wiki revision:见本地镜像头
- 实现提交:`b1f8bcb`
## 背景与目标
<!-- 原来有什么问题,这次达到什么结果。 -->
在已完成的用户 API Key 和 OpenAPI 生成链路上补齐安全审计,并提供仅面向管理员的 API Key 元数据查询、详情与幂等撤销接口。审计不得泄露完整 Key、Prompt、文件、认证头、Cookie、响应正文或原始 IP;未知 Key 的认证失败不写数据库,避免形成无界写放大入口。
## 最终方案
<!-- 说明实际实现。与建单方案不同之处必须写清原因。 -->
- 新增共享 `internal/core/apiaudit` 仓储,动作、结果和摘要字段均采用固定白名单。
- 用户创建、改名、撤销 API Key 时,在同一数据库事务写入审计;重复撤销保持幂等并记录结果。
- 已认证的 OpenAPI 文生图、图生图提交及限流拒绝写入 API 审计;未知、缺失、过期和撤销 Key 在认证阶段拒绝,不产生数据库审计行。
- API Key 的 `last_used_at` 按一分钟窗口节流更新。
- 管理端新增 API Key 元数据列表、详情和撤销接口,沿用 JWT 与 Casbin;列表和详情不返回完整 Key、public_id 或 secret_hash,并禁止缓存。
- 管理员撤销同时写入 `admin_audit_events` 和 `api_audit_events`;客户端请求 ID 仅接受 UUID,否则改用服务端生成值。
- 未增加管理端创建或读取完整用户 Key 的能力,管理界面留给 #46。
## 修改文件
## 修改范围
- `<文件>`:<改动说明>
- `internal/core/apiaudit/`:共享安全审计仓储和字段白名单测试。
- `portal/service/`、`portal/handler/`:Key 生命周期、OpenAPI 提交、限流拒绝审计及 last_used_at 验证。
- `admin/app/chorus/`:管理员 API Key 元数据列表、详情、幂等撤销和双审计。
- 核心 Wiki 及 `docs/02`、`docs/03`、`docs/04`、`docs/06` 镜像:补充架构、规则、验证和排错说明。
## 验收结果
| 验收标准 | 结果 |
|---|---|
| | 通过 / 未通过 |
| 审计事件覆盖设计动作且摘要脱敏 | 通过自动化测试 |
| 未知 Key 失败不制造数据库审计行 | 通过 MySQL 集成测试 |
| 管理员只查看元数据、可检索并幂等撤销,权限负向测试通过 | 通过 |
| 管理撤销同时写管理员与 API 安全审计且不泄露完整 Key | 通过 |
| 管理 API、审计字段和排错文档已更新 | 通过 |
| 人工验收 | 待用户确认 |
## 测试
- 执行命令:`<命令>`
- 结果:
- **未验证部分**:<!-- 必填;没有就写“无”。 -->
- `go test ./...`:通过。
- `go vet ./...`:通过。
- `go -C admin test ./...`:通过。
- `go test -race -count=1 ./internal/core/apiaudit ./portal/service ./portal/handler`:通过。
- `go -C admin test -race -count=1 ./app/chorus`:通过。
- Portal 与 Admin API 的 MySQL 定向集成测试:通过。
- `python dev_scripts/harness.py sync --check`:通过。
- `python dev_scripts/harness.py check --strict`:通过。
- Supervisor 中用户端与管理 API 已重新构建、启动并完成未认证冒烟检查。
- 未验证部分:未调用真实 Provider,未执行管理页面验证(属于 #46)。
## 遗留问题
## 说明
<!-- 没有就删除本节。 -->
go-admin 对部分认证失败会以 HTTP 200 包装 JSON 业务码 401;权限仍被拒绝,排错时需同时检查响应 JSON 的 `code`。
## 相关提交
- `<提交哈希>` <提交说明>
- `b1f8bcb` feat: 实现 API 安全审计与管理端 API (#45)