From 0bb78e004b86aed659c29c555c8dec0de70f6920 Mon Sep 17 00:00:00 2001 From: KiriAky 107 Date: Sun, 30 Aug 2026 10:57:14 +0800 Subject: [PATCH] =?UTF-8?q?docs(provider):=20=E8=AE=B0=E5=BD=95=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E5=AF=86=E9=92=A5=E5=8A=A0=E5=AF=86=E8=BE=B9=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 +++------------ docs/后端接口契约-开发版.md | 2 +- docs/模型提供商与模型发现开发说明.md | 16 +++++++++++++--- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 193aabb..0ab01bc 100644 --- a/README.md +++ b/README.md @@ -76,20 +76,11 @@ uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000 #### 开发环境使用外部模型 -当前仓库尚未包含 Tauri Host 与 Stronghold。需要联调外部模型时,应在启动后端的同一个终端会话中,通过进程环境注入密钥,再启动 AI Core: +在“设置 → 模型提供商”中选择 DeepSeek 或 OpenAI 预设后,直接在密码输入框填写 API Key。前端只在提交期间持有该值,不写入 Pinia 或 localStorage;AI Core 将其加密保存到本机 `backend/data/credentials/`,Provider 配置只保留内部 Credential ID。 -- DeepSeek 预设的 Credential ID 为 `deepseek`,开发环境读取 `DEEPSEEK_API_KEY`,也兼容 Host 约定的 `AINOTE_CREDENTIAL_DEEPSEEK`; -- OpenAI 预设的 Credential ID 为 `openai`,开发环境读取 `OPENAI_API_KEY`,也兼容 `AINOTE_CREDENTIAL_OPENAI`。 +该目录同时包含本地开发用主密钥和密文,并已加入 `.gitignore`。这提供本地静态加密和完整性校验,但不能替代操作系统凭据库。开始 Tauri 桌面集成后,应将存储实现迁移到 Stronghold,保留现有 Credential API 与 Provider 接口边界。 -PowerShell 7 中可以在启动后端的同一终端安全输入 DeepSeek Key,输入内容不会回显,也不会进入命令历史: - -```powershell -$env:DEEPSEEK_API_KEY = Read-Host "DeepSeek API Key" -MaskInput -cd backend -uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000 -``` - -环境变量只应配置在本机或当前进程中,不要写入仓库文件、README、Issue、提交信息或聊天记录。设置环境变量后必须重新启动后端进程,已经运行的进程无法读取之后才添加的变量。前端 Provider 表单中的 Credential ID 不是 API Key,不能把密钥明文粘贴到该字段。 +无界面或自动化环境仍可使用 `DEEPSEEK_API_KEY`、`OPENAI_API_KEY` 或 `AINOTE_CREDENTIAL_` 注入;设置页保存的本地密钥优先,环境变量仅在本地未保存对应 Credential ID 时作为回退。密钥不得写入仓库文件、README、Issue、提交信息或聊天记录。 ### 终端二:启动前端 diff --git a/docs/后端接口契约-开发版.md b/docs/后端接口契约-开发版.md index 10e69df..71f13bd 100644 --- a/docs/后端接口契约-开发版.md +++ b/docs/后端接口契约-开发版.md @@ -75,7 +75,7 @@ | GET | `/api/providers/{provider_id}/models` | 获取模型及 Capability 列表 | | POST | `/api/providers/test` | 测试 Provider 连接 | -Provider Contract 只传递 `credential_id` 或临时 `credential_context_id`,不通过普通 JSON 接口传递明文 API Key。 +Provider Contract 只传递 `credential_id` 或临时 `credential_context_id`。当前前后端开发阶段通过独立的 `PUT /api/credentials/{credential_id}` 接收 API Key,并立即加密落盘;该接口只返回配置状态,不返回密钥。Provider CRUD、模型列表和测试接口均不携带明文 API Key。Tauri 集成后由 Stronghold 接管存储实现。 ### Tasks、Media 与 Index diff --git a/docs/模型提供商与模型发现开发说明.md b/docs/模型提供商与模型发现开发说明.md index fe53d8e..91b5385 100644 --- a/docs/模型提供商与模型发现开发说明.md +++ b/docs/模型提供商与模型发现开发说明.md @@ -67,11 +67,21 @@ Provider Adapter 的错误在 FastAPI 路由转换为统一 API Error: ## 3. 凭据边界 -设置页只保存 `credential_id`。桌面 Host 负责将 Stronghold 中的密钥以临时凭据上下文注入 AI Core,`EnvironmentCredentialResolver` 根据 Credential ID 解析。API Key 明文不会进入 Provider Contract、Pinia、localStorage、日志或本文档。 +设置页选择 OpenAI 或 DeepSeek 预设后展示密码类型的 API Key 输入框,不再要求用户理解 Credential ID。输入值只存在于表单的临时 `ref`,不会写入 Pinia 或 localStorage;请求完成、取消表单或失败后都会清空。 -当前尚未实现 Tauri Host 的开发环境中,`openai` 和 `deepseek` Credential ID 分别兼容标准的 `OPENAI_API_KEY` 和 `DEEPSEEK_API_KEY` 进程环境变量。Host 注入的 `AINOTE_CREDENTIAL_OPENAI`、`AINOTE_CREDENTIAL_DEEPSEEK` 优先级更高。环境变量必须在启动 AI Core 前设置;Provider 明确指定了 Credential ID 但进程内无法解析时,Adapter 会在网络请求前返回 `PROVIDER_CREDENTIAL_MISSING`,避免把本地配置缺失误报为厂商 401。 +API Key 通过独立接口写入: -本次没有创建或使用本机 OpenAI API Key,也没有对 OpenAI、DeepSeek 发起真实请求。外部模型列表的联调需要在桌面 Host 完成 Stronghold 注入后进行。 +```http +GET /api/credentials/{credential_id} +PUT /api/credentials/{credential_id} +DELETE /api/credentials/{credential_id} +``` + +PUT 请求使用 Pydantic `SecretStr` 接收密钥,响应仅包含 Credential ID 和 `configured` 状态。后端使用 Fernet 认证加密,将密文保存到 `data/credentials/credentials.json`,主密钥保存到 `data/credentials/master.key`;目录和文件尽可能设置为仅当前用户可访问并整体排除版本控制。写入采用临时文件替换,避免进程中断留下半写文件。Provider 发起请求时按 Credential ID 解密,解密失败转换为统一 Provider Error,任何读取接口均不返回明文。 + +本地开发存储的主密钥与密文仍位于同一用户数据目录,因此它解决的是仓库泄漏、普通配置误提交和静态明文暴露,不等同于操作系统安全硬件或 Stronghold。Tauri 集成后应以 Stronghold 实现替换 `EncryptedCredentialStore`。无界面环境仍兼容 `OPENAI_API_KEY`、`DEEPSEEK_API_KEY` 和 Host 注入的 `AINOTE_CREDENTIAL_`;设置页保存的本地密钥优先,环境变量仅作为回退。 + +自动化测试仅使用虚构测试值,验证磁盘文件不包含明文、加解密往返、API 响应不泄密,以及 Provider 能用解密后的值构造 Authorization Header。本次没有使用真实 OpenAI 或 DeepSeek Key,也没有向厂商发起真实请求。 ## 4. 验证