模型下拉框能给前端,API Key 为什么不能:mic_ai 的安全投影

模型选择器只需要身份与能力字段;密钥、端点、提示词和向量库凭据仍留在受保护边界内。
摘要| 一个 AI 模型下拉框看似只是普通查询,背后却同时面对兼容旧客户端、隐藏 API Key、防止条件探测和保护系统表元数据四个问题。本文结合 Microi吾码当前源码与 6 项定向测试,拆解 mic_ai 如何用服务端强制投影开放可用模型,同时不把秘密字段、隐藏模型和元数据一起暴露给普通用户。
✦ ① 旧模型选择器为什么不能直接封死
AI 助手、知识库或工作流在创建时,需要先列出当前可选模型。历史客户端往往直接读取 mic_ai;如果后端把整张表一刀切成“仅平台管理员可读”,普通租户用户连模型名称都拿不到,页面就会退化成空下拉框。
但恢复兼容不能等同于恢复整表读取。mic_ai 同时可能保存 API Key、服务端点、系统提示词和向量数据库凭据。真正的问题不是“放开还是封死”,而是把公开目录与管理数据拆成两条完全不同的读取路径。
设计目标| 普通已登录用户可以看见启用模型的名称和能力;任何客户端参数都不能把这条兼容路径变成秘密查询接口。
✦ ② 白名单不是前端约定,而是服务端权威投影

调用方的选择字段、筛选和排序先被收敛,再进入启用模型目录。
当前源码把安全字段固定为 Id、Name、AiModel、ModelType、Provider、SupportReasoning、EnableVectorDatabase、IsRelayModel、IsEnable、Sort、CreateTime 和 UpdateTime。它们足以渲染模型选择器,却不包含任何密钥或私有端点。
更关键的是,服务端选择的是替换调用方字段列表,而不是与它求交集。旧客户端没有传 _SelectFields 也能工作;恶意客户端即使明确请求 ApiKey 或 QdrantApiKey,也只会得到服务器写死的安全投影。
客户端请求:Name, ApiKey, Endpoint
服务端改写:Id, Name, AiModel, ModelType, Provider, ...
最终结果:仅返回安全目录字段
✦ ③ 看不到密钥,还可能用条件把它猜出来
只从返回列里删除 ApiKey 仍然不够。如果攻击者可以按 ApiKey 前缀筛选、按 Endpoint 分组,或者根据秘密字段排序,就能把接口当成布尔预言机:每次回答“有或没有”,多次组合后逐步推断秘密。

返回列、筛选、分组和排序都必须收敛,才算完成字段级隔离。
因此兼容路径会清空 _Where、Keyword、各种 Search、分组与附加投影,只保留服务器设置的 IsEnable=1。排序字段也只能来自安全白名单,否则回落到 Sort 升序;分页上限被限制为 500。公开目录由服务端完整拥有查询谓词,而不是只修剪返回结果。
容易漏掉的边界| 秘密字段不能出现在 SELECT、WHERE、HAVING、ORDER BY 或可扩展投影中的任何位置。
✦ ④ 为什么只返回 IsEnable=1
未启用模型可能处于下线、调试、欠费或配置未完成状态。让普通用户看见它们不仅制造无效选择,也会泄露运营配置。安全投影把等值条件强制固定为 IsEnable=1,客户端不能把它改成 0,也不能删除这个条件。
这使模型目录成为一个面向使用者的稳定视图:它回答“现在能选什么”,而不是“管理员在后台配置过什么”。公开能力与后台资产的语义由此分开。
目录语义| 模型选择器读取的是可用能力目录,不是 mic_ai 管理表的缩水版。
✦ ⑤ 开放行数据,不等于开放字段元数据
另一个常见误区是:既然普通用户能读取安全投影,就顺便允许读取 mic_ai 的 diy_field 配置、字段数据源和系统表结构。源码明确拒绝这种推导。兼容逻辑只解决模型选择器的行数据,受保护平台表的元数据仍要求平台管理员授权。
原因很直接:字段元数据可能暴露隐藏字段名称、后台配置入口、数据源规则和管理语义。即便行查询已经删除密钥,元数据泄露仍会为后续探测提供地图。
- 普通用户:读取启用模型的安全字段投影。
- 平台管理员:通过真实授权快照管理系统表和字段元数据。
- 匿名调用:不能借兼容路径读取受保护资源。
✦ ⑥ 写入权限没有跟着读取兼容一起打开
兼容分支只适用于读取操作。普通用户不能因为能看模型名称,就新增、修改或删除 mic_ai 记录。读目录与管配置是两个授权动作,后者仍属于平台管理边界。
这种不对称是合理的:大量用户需要选择模型,只有少数管理员需要维护供应商、密钥与路由。如果为了代码简化让两者共享权限,最小授权原则就失效了。
权限拆分| 读安全目录是兼容能力;写系统配置、读元数据和读秘密字段仍是管理能力。
✦ ⑦ 6 项测试证明了哪些边界

本地 .NET 10 定向测试:6 执行、6 通过、0 失败;TRX 与源码摘要已归档。
本轮定向执行 FormEngineTenantBoundaryTests 中与 mic_ai 相关的用例,结果为 6 / 6 通过。覆盖普通已登录用户的无密钥投影、敏感字段请求清洗、隐藏模型过滤、元数据拒绝、平台管理员管理能力,以及普通用户写入继续被拒绝。
证据文件记录了命令、退出码、TRX、源码路径、行号与 SHA-256。它证明当前工作区代码在这些测试条件下满足边界,不把本地测试等同于线上租户的全部授权验收。线上仍需结合真实角色、菜单权限和公开接口回读。
证据边界| 测试证明安全投影逻辑按预期工作;不证明任何未测试的自定义接口都自动继承相同策略。
✦ ⑧ 把安全投影复用到其他配置表
- 先定义使用者真正需要的最小字段集合。
- 由服务端替换字段和谓词,不信任客户端的筛选、分组与排序。
- 公开视图只返回处于可用状态的数据。
- 行数据兼容、元数据读取与写入管理分别授权。
- 用定向测试覆盖正常读取、恶意字段、条件探测、匿名和写入路径。
公开目录 = 最小字段白名单 + 服务端固定谓词
管理能力 = 元数据读取 + 秘密读取 + 配置写入
两条路径独立授权,不能相互推导
安全投影不是把一张管理表“少返回几列”,而是为特定使用场景构造一条服务器拥有的公开目录。模型下拉框因此可以继续工作,API Key 也不必为兼容性付出代价。
结论| 可以开放的是可用模型目录;必须守住的是秘密、查询侧信道、元数据与管理写入。
更多推荐




所有评论(0)