83 lines
2.6 KiB
Markdown
83 lines
2.6 KiB
Markdown
实现密钥批量管理(P0-5)。后端 .env 读写 + API + 前端页面。
|
|
|
|
## 后端: Key Manager 服务
|
|
|
|
创建 backend/app/services/key_manager.py:
|
|
|
|
核心功能:
|
|
- 读取 Profile 的 .env 文件中指定密钥字段
|
|
- 脱敏显示: 前3字符 + "**...**" + 后4字符 (如 "sk-**...**b12c")
|
|
- 白名单字段: DEEPSEEK_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY, FEISHU_APP_ID, FEISHU_APP_SECRET
|
|
- 批量覆盖: 写入新值到 .env 文件 (操作前自动备份 .env → .env.bak)
|
|
- 批量检查: 扫描全部 Profile 的 .env, 返回缺失字段列表
|
|
- 差异视图: 对比各 Profile 同一字段的值 (只显示有无和长度, 不显示原文)
|
|
- 不写入审计日志原文(只记录 action + profile 名 + 字段名)
|
|
|
|
## 后端: Keys API
|
|
|
|
创建 backend/app/api/keys.py, 全部 require_role("owner","operator")
|
|
|
|
### GET /api/v1/keys
|
|
返回密钥字段列表:
|
|
```json
|
|
[{"profile": "hebo", "fields": {"DEEPSEEK_API_KEY": "sk-**...**b12c", ...}, "missing": 0}]
|
|
```
|
|
|
|
### POST /api/v1/keys/batch-overwrite
|
|
批量覆盖密钥:
|
|
- body: {profile_names: [...], key_name: "DEEPSEEK_API_KEY", new_value: "sk-xxx", confirmation: "我确认覆盖 N 个 Profile"}
|
|
- 验证 confirmation 短语精确匹配
|
|
- 逐 Profile 写入 + 返回成功/失败列表
|
|
|
|
### POST /api/v1/keys/batch-scan
|
|
批量检查缺失:
|
|
- body: {profile_names: [...]} 或全部 Profile
|
|
- 返回缺失统计 + 详情
|
|
|
|
### GET /api/v1/keys/diff
|
|
差异视图:
|
|
- query: ?profiles=hebo,ops-engineer
|
|
- 返回对比表: 横向 Profile, 纵向字段, 值状态(有/无/长度)
|
|
|
|
### GET /api/v1/keys/export
|
|
CSV 导出批量检查结果
|
|
|
|
## 前端: Keys 页面
|
|
|
|
修改 frontend/src/pages/KeysPage.tsx:
|
|
|
|
### 操作栏
|
|
- [批量覆盖] 按钮 → Modal
|
|
- [批量检查] 按钮 → 扫描结果展示
|
|
- Profile 筛选下拉
|
|
- 搜索密钥字段
|
|
|
|
### 密钥列表
|
|
- Table 组件
|
|
- 列: ☐复选框, Profile名, 各密钥字段(脱敏显示), 缺失计数
|
|
- 缺失字段标红 ❌
|
|
- 差异视图切换
|
|
|
|
### 批量覆盖 Modal
|
|
- 下拉选择密钥字段
|
|
- 输入新值(密码框, 可切换明文)
|
|
- 预览: "将覆盖 N 个 Profile 的 {KEY_NAME}"
|
|
- 当前值脱敏预览
|
|
- 输入确认短语: "我确认覆盖 N 个 Profile"
|
|
- 确认后执行 → 进度提示 → 成功/失败列表
|
|
|
|
### 批量检查结果
|
|
- 显示扫描结果表: Profile, 缺失字段列表, 缺失数
|
|
- 支持导出 CSV (下载按钮)
|
|
- 缺失行标红
|
|
|
|
### 差异视图
|
|
- 勾选 2+ Profile → "查看差异"
|
|
- 对比表: 横向 Profile, 纵向字段, ✅有/❌无
|
|
- 差异行黄色高亮
|
|
- "只看差异" 切换
|
|
|
|
### 四态覆盖 + 审计日志
|
|
|
|
注册路由, 完成后提交。
|