Files
sub2api-cn-relay-manager/docs/2026-06-04-KEY_SELF_SERVICE_API.md
phamnazage-jpg 492f33a129
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
feat(vnext): complete vNext.1 release gate — default chain admission, idempotent init, user key skeleton
- DEFAULT_CHAIN_ADMISSION.md: reviewed and approved, real artifact refs added
- DEFAULT_DATA_IDEMPOTENT_RELEASE_GATE.md: reviewed and approved
- scripts/setup_default_data.sh: idempotent init with --dry-run/--apply/artifact
- scripts/test/test_default_data.sh: 4 test cases all pass
- scripts/acceptance/verify_user_key_self_service.sh: Phase 0 skeleton
- .gitignore: add generated artifact directories
2026-06-05 11:07:50 +08:00

227 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Key Self-Service API
日期2026-06-04
状态:待审核
适用版本vNext.2
## 目的
定义用户 key 自助申请流程中的 API 契约,包括 key 的创建、展示、重置、暂停、恢复、查询。当前版本仅做设计,不实现。
## 实体与状态
### KeyRecord
| field | type | 说明 |
| ---------------- | -------- | ------------------------------------ |
| key_id | string | 唯一 ID |
| owner_subject_id | string | 属主 |
| key_fingerprint | string | 生成时对完整 key 取 sha256 |
| masked_preview | string | 最后 4 位或 `sk-****....abcd` |
| display_name | string | 用户可编辑名称 |
| logical_group_id | string | 对应逻辑分组 |
| allowed_models | []string | 该 key 可调用的模型列表 |
| admin_status | string | active / paused / disabled / retired |
| quota_status | string | ok / exhausted / limited / unknown |
| last_used_at | datetime | 空表示从未使用 |
| created_at | datetime | 创建时间 |
| expires_at | datetime | 可选失效时间 |
### 审计事件
| field | type | 说明 |
| ---------------- | -------- | ---------------------------------------- |
| event_id | string | 唯一 ID |
| actor_subject_id | string | 操作者 |
| actor_role | string | admin / user |
| target_key_id | string | 受影响的 key |
| action | string | create / reset / pause / resume / delete |
| result | string | success / denied / failed |
| reason | string | 操作说明 |
| created_at | datetime | 事件时间 |
## REST API 契约
### POST /api/keys
创建 key。明文 key 在返回的 `plaintext_key` 字段返回一次。
请求体:
```json
{
"logical_group_id": "gpt-shared",
"display_name": "test key",
"allowed_models": ["gpt-5.4"]
}
```
响应 201
```json
{
"key": {
"key_id": "key_abc123",
"plaintext_key": "sk-...full-key...",
"masked_preview": "sk-****abcd",
"display_name": "test key",
"logical_group_id": "gpt-shared",
"allowed_models": ["gpt-5.4"],
"admin_status": "active",
"quota_status": "ok",
"created_at": "2026-06-04T..."
}
}
```
说明:
- `plaintext_key` 只在本响应返回
- 后续所有列表/详情接口都不包含 `plaintext_key`
### GET /api/keys
获取当前用户自己的 key 列表。
响应 200
```json
{
"keys": [
{
"key_id": "key_abc123",
"masked_preview": "sk-****abcd",
"display_name": "test key",
"logical_group_id": "gpt-shared",
"allowed_models": ["gpt-5.4"],
"admin_status": "active",
"quota_status": "ok",
"last_used_at": null,
"created_at": "2026-06-04T..."
}
]
}
```
约束:
- 只返回当前 subject 的 key
- 不返回 `plaintext_key`
- 不返回 `route_id``shadow_group_id``host_account_id`
### GET /api/keys/:id
获取单个 key 元数据。校验属主或管理员权限。
响应 200同上`plaintext_key`)。
### POST /api/keys/:id/reset
重置 key。旧 key 失效,新明文 key 在响应中返回一次。
响应 200
```json
{
"plaintext_key": "sk-...new-full-key...",
"masked_preview": "sk-****wxyz",
"admin_status": "active"
}
```
约束:
- 写入审计事件
-`plaintext_key` 立即失效
- 重置后当前 subject 的 sticky binding 应重新评估
### POST /api/keys/:id/pause
暂停 key。请求体可选 `reason`
响应 200
```json
{
"key_id": "key_abc123",
"admin_status": "paused",
"reason": "admin initiated"
}
```
约束:
- 暂停后用户调用应失败
- 暂停原因应对用户可见
- 写入审计事件
### POST /api/keys/:id/resume
恢复暂停的 key。
响应 200
```json
{
"key_id": "key_abc123",
"admin_status": "active"
}
```
约束:
- 仅暂停状态的 key 可恢复
- 写入审计事件
### DELETE /api/keys/:id
删除/退役 key。
响应 200
```json
{
"key_id": "key_abc123",
"admin_status": "retired"
}
```
约束:
- 退役后不再参与分发
- 写入审计事件
- 不真正删除记录,保留审计一致性
## 授权规则
用户侧:
- 仅管理自己的 key
- 不能查看他人 key、metadata、audit log
管理员侧:
- 可查看所有 key 的 metadata
- 可暂停 / 恢复 / 重置 / 退役任意 key
- 可查看审计事件
- 禁止查看已收回的 `plaintext_key`
## 安全限制
1. 创建 key 限频:每 subject 每小时 5 次vNext.2 建议值)
2. 重置 key 限频:每 subject 每 24 小时 2 次vNext.2 建议值)
3. key 最短存活时间:至少存活 1 小时才允许退役(可讨论)
4. 管理员暂停 key 不需要 subject 同意,但需要记录 reason
## 测试要求
- 用户 A 创建 key → 用户 B 不能看到
- 用户 A 创建 key → 用户 B 不能重置
- 创建后 `plaintext_key` 只返回一次
- 管理员暂停后,用户调用返回 403 且 reason 明确
- 重置后旧 key 失效,新 key 唯一可用的证据
## 与本轮范围关系
属于 vNext.2 设计产物。在 vNext.1 审核通过前,不允许实现。