feat(kb-open): P0-A 认证体系 + 数据模型 + 管理端 + 限流 + 集中授权#444
Conversation
…authz Implements the authentication backbone for the KB Open API (mateaix#441): API key lifecycle, a permitAll-path filter that rejects (never pass-through), per-key sliding-window rate limiting, and a centralized @RequireKbScope interceptor for scope + KB-ownership checks. Components: - TokenHashUtil: shared SHA-256 hash kernel (A4), reusable by PAT later - KbApiKeyService: mint/authenticate/revoke/update + multi-KB binding (R3: empty binding = zero access, not "all KBs") - KbOpenApiAuthFilter: sole gatekeeper for /api/v1/open/kb/** (R1: must return 401, no pass-through); R2: per-key rate limit (429) - KbApiKeyRateLimiter: sliding-window limiter (TriggerRateLimiter pattern) - @RequireKbScope + KbScopeInterceptor: centralized authorization (A1), scope check + kbId ownership from path variable - KbApiKeyAdminController: JWT-authenticated CRUD (list/create/detail/ update/revoke), workspace-scoped - V162 migration (h2/mysql/kingbase): mate_kb_api_key + _binding tables Security: - mck_ prefix (distinct from PAT mc_ and JWT eyJ) - SHA-256 hash storage, plaintext shown once at creation - prefix column (4 chars) for UI display only Tests (17 new, all green): - KbApiKeyServiceTest: R3 empty-binding rejection, auth round-trip, expired/disabled/wrong-prefix rejection, kb:* wildcard, revoke - KbApiKeyRateLimiterTest: sliding window, per-key isolation, recovery Closes mateaix#441
|
感谢这份 P0-A 开放 API 基座 🙏 安全设计整体很扎实:token 只存 SHA-256( 不过有两个阻塞项需要先修,合并前请处理: 1. 2. 迁移版本号 V162 与已合并的 #437 冲突。 非阻塞建议:
P0-A 是整条 P0-B/Deep Research 栈的地基,建议先在这里把上面两个阻塞项(列宽 + 版本号)和设计文档位置改掉,#445/#446 再相应 rebase。改好后我们就合并 🙏 |
BLOCKERS: - prefix column VARCHAR(6) → VARCHAR(12) across all 3 migration dialects; KbApiKeyService.create() produces 8 chars (mck_ + 4 random), VARCHAR(6) would silently truncate on H2 and throw on MySQL strict mode - Rename migration V162 → V164 to avoid collision with merged mateaix#437 (V162=wiki_raw_material_error_code, V163=wiki_raw_material_warning) and fix stale V161 references in h2/kingbase comments NITS: - SecurityConfig/WebMvcConfig: replace inline FQN with import + simple name - parseScopes: add .map(String::trim) so ' kb:read' matches correctly - Remove ?token= SSE query fallback in KbOpenApiAuthFilter (P0-A has no SSE endpoint; key would leak into access/proxy logs — R5) - Move kb-open-api-design.md from repo root to rfcs/ (contains RFC-090 internal reference that would be exposed by sync-opensource) - KbApiKeyEntity Javadoc: 'first 4 chars' → 'first 8 chars (mck_ + 4)' to match actual behavior
|
Fixed. Commit Blockers:
Nits: Compilation and all 17 KB Open API tests pass. Ready for re-review. |
|
感谢按 review 全部改好了 🙏 两个阻塞项都已解决:
其余建议也都采纳了: 一个可选小尾巴(不阻塞): |
Closes #441 · Part of #440
改动
知识库开放 API 的认证骨架。这是 P0-B(9 个端点,#442)的前置依赖。
认证与鉴权
TokenHashUtil(共享 hash 内核,A4):SHA-256 生成/校验,KB-key 与 PAT 共享(先 hash 层,CRUD/UI 后续)KbApiKeyService:签发(mck_前缀)/ 校验(hash 索引 O(1))/ 撤销 / 多 KB 绑定管理KbOpenApiAuthFilter:permitAll 路径的唯一守门人@RequireKbScope+KbScopeInterceptor(A1):集中授权(scope 检查 + KB 归属校验),仿@RequireWorkspaceRole,不逐端点手写KbApiKeyRateLimiter:滑动窗口限流器(复用TriggerRateLimiter范式)管理端
KbApiKeyAdminController:JWT 认证 CRUD(list/create/detail/update/revoke),workspace 隔离,@RequireWorkspaceRole("admin")数据模型
mate_kb_api_key+mate_kb_api_key_bindingtoken_hashSHA-256(UNIQUE 自带索引)、prefix(4 位)、rate_limit_per_min(P0 强制)kb_id索引(Wiki 面板反查)SecurityConfig
/api/v1/open/kb/**permitAll + KbOpenApiAuthFilter 注册WebMvcConfig.addCorsMappings("/api/**")覆盖(R6)测试
回归验证:
WebChatApprovalInteractionTest(9)全绿。安全设计要点