feat(v3): add CRM gateway /v1/chat/completions with key auth + governance check
- POST /v1/chat/completions public route on CRM (not host pass-through) - Bearer token → sha256 fingerprint → ListByFingerprint → governance check - paused → 403 forbidden, retired/deleted → 403 - ProxyRouteChatCompletions to upstream - NewAPIHandler/NewAPIHandlerWithAuth: optional dsn param for gateway SQLite access - ListByFingerprint in user_keys_repo
This commit is contained in:
46
docs/2026-06-06-V3-1-GATEWAY-PLAN.md
Normal file
46
docs/2026-06-06-V3-1-GATEWAY-PLAN.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# V3-1 网关治理执行计划
|
||||
|
||||
> 目标:在 CRM 新增公开 `/v1/chat/completions` 入口,用户在入口用 portal key 认证,CRM 校验 `admin_status` 后再转发到宿主,实现 0 延迟的 pause/resume 治理阻断。
|
||||
|
||||
## 改动概览
|
||||
|
||||
| 文件 | 改动 |
|
||||
| ------------------------------------------------ | ------------------------------------------------------------------------------- |
|
||||
| `internal/app/http_api.go` | 新增 `POST /v1/chat/completions` 公开路由(无 admin auth),调用治理校验 + 转发 |
|
||||
| `internal/app/route_proxy_api.go` | 新增 user-key 认证和治理校验的入口函数 |
|
||||
| `internal/app/openaicompat_handler.go`(新文件) | OpenAI-compatible 请求解析 + user-key auth 提取 |
|
||||
| `deploy/tksea-portal/nginx/` 或部署脚本 | 加 `location /v1 { proxy_pass http://127.0.0.1:18190; }` |
|
||||
|
||||
## 执行分步
|
||||
|
||||
### Step 1: 新增公开 `/v1/chat/completions` 路由
|
||||
|
||||
在 `internal/app/http_api.go` 中,在 `NewAPIHandlerWithAuth` 函数注册路由处(在 admin auth 区块之外)添加:
|
||||
|
||||
```go
|
||||
mux.Handle("POST /v1/chat/completions", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
handlePublicChatCompletions(w, r, actions.UserKeyHandler)
|
||||
}))
|
||||
```
|
||||
|
||||
注意必须放在 `requireAdminAccess` 包的外面,这样用户不需要 admin token。
|
||||
|
||||
### Step 2: 实现 `handlePublicChatCompletions`
|
||||
|
||||
```go
|
||||
func handlePublicChatCompletions(w http.ResponseWriter, r *http.Request, ukh *UserKeyHandler) {
|
||||
// 1. 提取 Bearer token → user_key_id
|
||||
// 2. 查 user_keys 表,校验 admin_status != "paused"
|
||||
// 3. 获取 key 的 subject_id 和 logical_group_id
|
||||
// 4. 调用 buildRouteChatCompletionsAction 或 buildProxyRouteChatCompletionsAction 转发
|
||||
// - 传入 gateway_api_key = managed key(来自 user_key 的 managed subscription)
|
||||
// - 传入 subject_id = user_key 的 owner_subject_id
|
||||
// - 传入 model = 请求体中的 model
|
||||
// - 传入 messages = 请求体中的 messages
|
||||
// 5. 返回 OpenAI-compatible chat completion 响应形状
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: deploy 脚本更新
|
||||
|
||||
更新 nginx 配置,让 `location /v1` 指向 CRM 的 18190。
|
||||
Reference in New Issue
Block a user