# ADR-001：统一认证与三级权限

- 状态：Accepted
- 日期：2026-07-16

## 背景

当前认证兼容旧 `users` 表和测试管理员，密码字段存在可逆编码，路由权限边界不完整。产品确认暂不开放自助注册，由管理员创建用户，并建立管理员、编辑者、查看者三级权限。

## 决策

1. 采用服务端用户表、不可逆密码哈希（优先 Argon2id）和短时 JWT Access Token；为后续刷新令牌保留会话表扩展点。
2. 角色固定为 `admin`、`editor`、`viewer`：管理员管理用户和系统配置；编辑者维护治理对象与流程；查看者只读检索、问答和授权数据产品。
3. 不提供公开注册路由。`POST /api/system/users` 仅管理员可调用。
4. 初始化第一个管理员由一次性 CLI/启动命令完成；若系统已有管理员则拒绝再次初始化。
5. 默认拒绝：新路由若未声明权限则测试失败。资源级访问范围在知识库检索前过滤，而不是回答后脱敏。
6. 审计记录登录失败、用户创建/禁用、角色变更和高权限操作，不记录密码、Token 或模型密钥。

## 接口边界

- `POST /api/system/auth/login`
- `GET /api/system/auth/me`
- `POST /api/system/users`（管理员）
- `GET /api/system/users`（管理员）
- `PUT /api/system/users/{id}`（管理员）
- `PUT /api/system/users/{id}/roles`（管理员）
- `POST /api/system/bootstrap-admin` 不作为 HTTP 公网接口；使用 CLI。

## 迁移

旧本地验收账号只用于本轮 Docker 冒烟。正式迁移新增 `password_hash` 后，由管理员重置真实用户密码，不迁移可逆密码值。迁移完成后删除旧 `password` 和 `is_admin` 语义，但生产删列需单独备份和审批。

## 结果

认证代码集中到 `app/core/system/`，路由通过统一装饰器表达角色；前端路由和按钮权限只改善体验，后端权限检查才是安全边界。
