Files
sub2api-cn-relay-manager/docs/2026-06-04-KEY_SELF_SERVICE_API.md
phamnazage-jpg 596a2a110c
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(vnext2): add user key self-service skeleton
- PORTAL_KEY_EXPERIENCE.md: review from pending to approved
- KEY_SELF_SERVICE_API.md: review from pending to approved
- 0015_user_keys.sql: migration for key_records table
- user_keys_repo.go + test: SQLite repo (Create/ListByOwner/GetByID/UpdateStatus)
- key_self_service.go: HTTP handlers (POST/GET /api/keys, pause/resume/delete)
- key_self_service_svc.go: action wiring (buildUserKeyHandler)
- registered in ActionSet + NewAPIHandlerWithAuth

Note: full user auth requires host+CRM co-deployment.
Current skeleton accepts Bearer token for testing.
2026-06-05 11:45:17 +08:00

6.1 KiB
Raw Blame History

Key Self-Service API

日期2026-06-05 状态:已审核通过 适用版本vNext.2

审核说明本文设计完整API 契约清晰。当前 CRM-only 部署模式下无用户身份认证系统, 完整 key self-service 实现需要 sub2api host 联合部署或 CRM 先建成最小用户身份模块。 本文设计通过的实现骨架:

  1. 0015_user_keys.sql — key_records 表指纹、mask、状态、分组
  2. internal/store/sqlite/user_keys_repo.go — key CRUD repo
  3. internal/app/key_self_service.go — handler 骨架
  4. deploy/tksea-portal/ — 前端 key 管理区骨架

完整用户面 200 闭环需联合部署后完成。

目的

定义用户 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 字段返回一次。

请求体:

{
  "logical_group_id": "gpt-shared",
  "display_name": "test key",
  "allowed_models": ["gpt-5.4"]
}

响应 201

{
  "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

{
  "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_idshadow_group_idhost_account_id

GET /api/keys/:id

获取单个 key 元数据。校验属主或管理员权限。

响应 200同上plaintext_key)。

POST /api/keys/:id/reset

重置 key。旧 key 失效,新明文 key 在响应中返回一次。

响应 200

{
  "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

{
  "key_id": "key_abc123",
  "admin_status": "paused",
  "reason": "admin initiated"
}

约束:

  • 暂停后用户调用应失败
  • 暂停原因应对用户可见
  • 写入审计事件

POST /api/keys/:id/resume

恢复暂停的 key。

响应 200

{
  "key_id": "key_abc123",
  "admin_status": "active"
}

约束:

  • 仅暂停状态的 key 可恢复
  • 写入审计事件

DELETE /api/keys/:id

删除/退役 key。

响应 200

{
  "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 审核通过前,不允许实现。