ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OmniRoute Zed IDE Docker 集成:Keychain 导入失效原因解析与手动 Token 导入实战

OmniRoute Zed IDE Docker 集成:Keychain 导入失效原因解析与手动 Token 导入实战 OmniRoute Zed IDE Docker 集成Keychain 导入失效原因解析与手动 Token 导入实战【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline Copilot. Quota-aware auto-fallback, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute当 OmniRoute 以容器化方式部署时标准的 “Import from Zed Keychain”从 Zed 钥匙串导入凭据流程必然失败——容器既无法访问宿主机的 keychain 守护进程也默认看不到宿主机的 Zed 配置目录。本文以 docs/providers/ZED-DOCKER.md波兰语版本见 docs/i18n/pl/docs/providers/ZED-DOCKER.md为主线完整讲清 Docker 环境下 Zed 导入失败的两个根本原因、官方 Manual Token Import手动 Token 导入的使用步骤与 API 调用方式并结合仓库源码剖析 Docker 检测启发式、两步导入安全机制与前端自动展开逻辑帮助你在容器化部署中正确接入 Zed 中已有的 AI 供应商凭据。为什么 Keychain 导入在 Docker 中会失败Zed IDE 将 AI 供应商的 OAuth/Token 凭据存放在操作系统级钥匙串中Linux 的 libsecret、macOS 的 Keychain、Windows 的 Credential Manager。当 OmniRoute 运行在容器内时存在两个相互独立的阻塞问题1. 文件系统隔离导入流程的第一步是调用isZedInstalled()探测宿主机上是否安装了 Zed。从 src/lib/zed-oauth/keychain-reader.ts 的实现可以看到它依次检查以下三个候选路径是否存在Linux~/.config/zedmacOS~/Library/Application Support/ZedWindows~/AppData/Roaming/Zed这些路径位于宿主机文件系统上除非显式以卷volume形式挂载进容器否则在容器内不存在。因此即使 Zed 确实安装在宿主机上容器内也会得出“未安装”的结论。2. IPC进程间通信隔离即便把 Zed 配置目录挂载进了容器读取凭据这一步依然走不通。OmniRoute 通过原生模块keytar与操作系统钥匙串服务通信在 Linux 上依赖 Unix 套接字或 D-Bus 会话对接 libsecret在其他平台上对接各自的 keychain 服务。这些 IPC 通道默认并不会桥接进容器任何凭据读取尝试都会失败。源码中keytar采用动态import(keytar)惰性加载见 keychain-reader.ts 的loadKeytar()加载失败时直接返回空凭据列表而非崩溃保证在无原生依赖的构建/CI 环境中行为优雅。Docker 环境检测的两条启发式OmniRoute 不会“猜测”容器环境而是通过两条互补的启发式规则显式检测实现位于 src/lib/zed-oauth/dockerDetect.ts/.dockerenv文件存在由 Docker 守护进程在容器启动时写入/proc/1/cgroupLinux cgroup v1内容中出现docker字符串。从源码结构看isRunningInDocker()是**尽力而为best-effort**的检测两条检查均包裹在 try/catch 中对非 Linux 平台、/proc未挂载或权限不足的情况静默降级对 Podman 等没有 Docker 兼容层的运行时可能出现漏判这是刻意接受的设计——即使漏判调用方也会降级并继续暴露手动导入选项。一旦检测命中/discover与/import两条路由都会返回HTTP 422响应体携带zedDockerEnvironment: true并附带指向 Manual Token Import 标签页的提示文案参见 src/app/api/providers/zed/discover/route.ts 与 src/app/api/providers/zed/import/route.ts 中完全一致的处理分支。使用 Manual Token Import 标签页在确认环境为 Docker 后收到 422 zedDockerEnvironment: true走手动导入流程打开Dashboard → Providers → ZedManual Token Import面板位于 keychain 导入卡片下方。当 OmniRoute 检测到 Docker 时该面板会在第一次 keychain 导入失败后自动展开——前端逻辑见 ZedImportCard.tsx/dashboard/providers/[id]/components/ZedImportCard.tsx)一旦响应中出现data.zedDockerEnvironment为真就执行setShowZedManual(true)展开面板在下拉列表中选择供应商OpenAI、Anthropic、Google、Mistral、xAI、OpenRouter 或 DeepSeek与 keychain 探测支持的七个供应商一一对应在密码输入框中粘贴 API Key点击Import。提交成功后密钥会被保存为一个新的供应商连接默认命名为Zed Manual Import (provider)例如Zed Manual Import (openai)。Zed 在宿主机上把密钥存放在哪里Zed 将 AI 供应商密钥以zed-openai、ai.zed.openai、zed-anthropic这类服务名写入操作系统钥匙串。要从宿主机取出密钥用于手动导入Linux配置文件位于~/.config/zed/settings.json其中的language_models段包含各供应商配置。但通过 Zed 界面保存进 keychain 的密钥不会以明文形式出现在settings.json中需要通过 keychain 浏览器如 GNOME Keyring / Seahorse查看或直接运行secret-tool lookup service zed-openai account api-keymacOS配置文件位于~/Library/Application Support/Zed/settings.json钥匙串条目可在Keychain Access.app中搜索zed找到。从源码角度看keychain 探测覆盖的服务名模式不止上面几种keychain-reader.ts 中的ZED_SERVICE_PATTERNS为每个供应商枚举了zed-openai、ai.zed.openai、zed.openai、Zed-OpenAI等四种命名变体覆盖全部七个供应商共 28 个模式再由extractProviderFromService()将服务名映射到 OmniRoute 内部供应商 IDopenai、anthropic、google、mistral、xai、openrouter、deepseek。进阶选项只读挂载 Zed 配置卷可选方案是把宿主机上的 Zed 配置目录以只读方式挂载进容器。注意这不能解决 keychain 访问问题IPC 隔离依然存在其价值在于为未来读取 Zed 非机密配置项如模型偏好预留能力# docker-compose.yml 片段 services: omniroute: image: omniroute:latest volumes: # Linux 宿主机 - ${HOME}/.config/zed:/host-zed-config:ro # macOS 宿主机改用下面这条取消注释 # - ${HOME}/Library/Application Support/Zed:/host-zed-config:ro environment: # 未来ZED_CONFIG_PATH/host-zed-config PORT: 20128注意环境变量ZED_CONFIG_PATH的覆盖逻辑目前尚未实现上述片段仅作为该功能落地后的参考。手动导入 API 直调方式绕过 UI也可以直接调用手动导入端点POST /api/providers/zed/manual-import Content-Type: application/json Authorization: Bearer management-token { provider: openai, token: sk-..., label: My Zed OpenAI key // 可选 }成功时返回{ success: true, connectionId: ..., provider: openai }结合 src/app/api/providers/zed/manual-import/route.ts 的源码可以补充文档未展开的字段约束由 zod schema 校验字段约束说明provider必填字符串1–64 字符供应商 IDtoken必填字符串1–512 字符API Key 明文label可选最长 128 字符连接名缺省为Zed Manual Import (provider)校验失败返回 400 并附具体错误项端点由requireManagementAuth保护未携带有效管理 Token 会被拒绝。安全纵深两步式 Keychain 导入流程虽然 Docker 环境下走的是手动导入但了解非容器场景的 keychain 导入机制有助于理解整体安全边界细节见 docs/security/SOCKET_DEV_FINDINGS.md 第 2 节第一步POST /api/providers/zed/discover服务端读取 keychain只把{ provider, service, account, fingerprint }返回列表发给前端原始 token 绝不下发——fingerprint是sha256(service|account|token)的前 16 个字符第二步POST /api/providers/zed/import请求体携带用户勾选的confirmedAccountsservice/account/fingerprint 三元组。服务端会重新读取 keychain 实时快照只导入指纹与当前 keychain 状态匹配的凭据从而保证被篡改或重放的 discover 响应无法诱骗端点保存无关 token向后兼容开关OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEPtrue可退回 v3.8.5 的“全量导入”一步式行为但默认关闭且已被标记为将在 v3.9 移除见 import/route.ts。两条路由与手动导入端点一样均由requireManagementAuth鉴权。故障排查现象原因解决方案422 zedDockerEnvironment: true运行在 Docker 容器内使用 Manual Token Import 标签页404 zedInstalled: false宿主机上未安装 Zed安装 Zed或改用手动导入403 keychain access denied系统拒绝访问 keychain在系统授权弹窗中授予权限404 keychain service not availableLinux 缺少libsecret安装libsecret-1-dev其中 403 与 404libsecret 缺失两类错误的判定逻辑直接来自 import/route.ts 的异常分支错误消息包含 “User canceled”/“denied” 时映射为 403包含 “not found”/“ENOENT” 时映射为 404 并提示安装libsecret-1-dev。小结Docker 化部署 OmniRoute 时Zed keychain 导入受文件系统隔离与 IPC 隔离双重阻断这是容器架构的固有边界而非配置疏漏。正确的落地路径是确认收到 422 zedDockerEnvironment: true信号后从宿主机secret-tool/ Keychain Access取出密钥通过 Dashboard 的 Manual Token Import 面板或POST /api/providers/zed/manual-import端点完成接入若未来需要读取 Zed 非机密配置可预先以只读方式挂载~/.config/zed卷等待ZED_CONFIG_PATH功能落地。【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline Copilot. Quota-aware auto-fallback, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表