【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载本文基于 opencodex 仓库中devlog/_fin/260720_issue180_cli_account_parity/003_management_api_contracts.md的调研结论系统梳理代理进程暴露的/api/*管理端点从客户端认证与端口发现、到 CodexChatGPT账户池、通用 OAuth 多账号与 API-Key 池三大家族凭证契约再到 provider 能力判别矩阵与 CLI 账号命令list/current/use的落地要点。读者读完可掌握为 CLI、GUI 或脚本对接 opencodex 管理面所需的全部请求形状、鉴权前提与语义边界。一、管理面契约的总闸门认证与跨域防线所有/api/*管理路由都由代理进程自身提供并统一穿过两道检查管理鉴权requireApiAuth(req, config, management)见 src/server/index.ts 的调用入口。即使用户环境不要求 API 认证loopback 绑定管理面也要求请求携带合法的 Host 与 Origin。来源检查handleManagementAPI在进入任何业务 handler 之前先调用isAllowedManagementOrigin(req, config)跨域来源直接返回 403src/server/management-api.tsif (!isAllowedManagementOrigin(req, config)) { return jsonResponse({ error: cross-origin request blocked }, 403, req, config); }同时所有 POST/PUT/PATCH 请求在 handler 缓冲 body 之前会拒绝超过 2 MiB 的载荷返回 413request body too large避免管理面被超大 JSON 拖垮src/server/management-api.ts。错误约定一律返回 JSON{ error: string }codex-auth相关端点有时额外附加code/reason字段。浏览器安全头管理面响应带X-Frame-Options: DENY与Content-Security-Policy: frame-ancestors nonesrc/server/auth-cors.ts。CORS 头管理面额外放行X-OpenCodex-GUI-Origin、X-OpenCodex-CSRF-Token两个自定义请求头src/server/auth-cors.ts。Origin校验采取“进程推导 origin 精确匹配”策略无Origin头、与Host推导出的 origin 完全一致、或命中运维配置的corsAllowOrigins列表时才放行——后者专门覆盖 TLS 终结器把进程观测到的http://…变为外部https://…的场景src/server/auth-cors.ts。二、客户端鉴权与端口解析CLI 连代理的第一公里2.1 绑定地址决定鉴权强度isApiAuthRequired(config)的实现极简绑定地址为 loopbacklocalhost/127.0.0.1/::1/[::1]之一时返回false否则返回truesrc/server/auth-cors.tsexport function isApiAuthRequired(config: PickOcxConfig, hostname): boolean { return !isLoopbackHostname(config.hostname); }两种情形下管理面的要求不同绑定方式客户端要求Loopback默认127.0.0.1无需 token但Host必须是 loopbackisLoopbackRequestHost按 hostname 判定信任边界端口可不同——ssh -L转发同样合法且不得携带外部Originsrc/server/auth-cors.ts非 loopback 绑定必须携带x-opencodex-api-key、Authorization: Bearer或x-api-key三者之一且值需匹配OPENCODEX_API_AUTH_TOKEN环境变量或config.apiKeys中某一项这些头是跨数据面与管理面共享的白名单的一部分STATIC_ALLOWED_REQUEST_HEADERS中明确包含X-OpenCodex-API-Key与X-Api-Keysrc/server/auth-cors.ts。CLI 侧的既有惯例是runningProxyUpdateHeaders()——读取configuredAdminToken()后注入X-OpenCodex-API-Key头src/oauth/login-cli.ts。2.2 端口阶梯canonicalfindLiveProxy()按固定优先级定位正在运行的代理src/server/proxy-liveness.tsPID 文件readAlivePidsrc/config.ts——从 pid 文件读取存活进程runtime-port.jsonreadRuntimePortsrc/config.ts——读取运行时记录的真实端口/healthz身份探针isOpencodexHealthzsrc/server/proxy-liveness.ts——对候选端口发起健康检查确认是 opencodex 自己的/healthz兜底config.port ?? 10100。配置目录为OPENCODEX_HOME环境变量指定目录缺省为~/.opencodexsrc/config.ts。值得注意的是configuredPort()直接解析_corsOrigin默认http://localhost:10100且任何准入检查都不依赖端口号——loopback 谓词只认 hostnamesrc/server/auth-cors.ts。三、Family A —— CodexChatGPT账户池契约Codex 账户池路由由handleCodexAuthAPI统一处理src/server/management-api.ts 动态导入 src/codex/auth-api/routes.ts。其身份规则主账户Codex App 登录id 恒为__main__MAIN_CODEX_ACCOUNT_IDsrc/codex/main-account.ts池账户 id 必须匹配^[a-zA-Z0-9._-]{1,64}$token 永不离服务端邮箱一律经maskEmail掩码后展示src/lib/privacy.ts。完整端点契约如下表Endpoint形状 / 语义锚点GET /api/codex-auth/accounts?refresh1强制刷新配额{ accounts: CodexAuthAccountDto[] }main-firstDTO 为{ id, email(masked), plan?, logLabel?, isMain, quota: { weeklyPercent?, monthlyPercent?, weeklyResetAt?, monthlyResetAt?, resetCredits?, updatedAt } \| null, needsReauth?, hasCredential }go/free 套餐只暴露月度字段routes.tsPOST /api/codex-auth/accounts手动导入 token受OPENCODEX_ENABLE_UNVERIFIED_CODEX_IMPORT1环境变量门控未开启则 403manual_import_disabledroutes.tsDELETE /api/codex-auth/accounts?id恒 200{ ok: true }不返回 404清除凭证、配额与线程亲和若删除的是当前 active 账户则同时清空activeCodexAccountIdsrc/codex/account-lifecycle.tsGET /api/codex-auth/active{ activeCodexAccountId: string \| null, autoSwitchThreshold: number(默认 80), upstreamFailoverThreshold: number(默认 3) }routes.tsPUT /api/codex-auth/activebody{ accountId: string \| null }__main__表示 Codex App 登录池 id 必须存在否则 400 Account not foundnull清除 pin回落自动选择最低用量src/codex/routing.ts。响应{ ok, activeCodexAccountId }。只写配置不清除内存中的线程亲和——已 pin 的线程在亲和过期前保持原账户src/codex/routing.ts即只作用于新线程/新会话routes.tsPUT /api/codex-auth/auto-switchbody{ threshold: 0-100 }0表示禁用持久化为autoSwitchThresholdroutes.tsPUT /api/codex-auth/failoverbody{ threshold: 0-20 }连续上游失败次数阈值达到后触发故障转移routes.tsGET /api/codex-auth/quota{ quotas: { [accountId]: StoredAccountQuota } }不含 token/邮箱routes.tsGET /api/codex-auth/reset-credits?accountId{ credits: [{ granted_at, expires_at }], available_count? }400/401/404 状态矩阵routes.tsPOST /api/codex-auth/reset-credits/consumebody{ accountId }成功返回{ code: reset }并强制刷新配额可选operationId提供幂等语义格式非法返回 400池配额探测忙碌时返回 503server_busy且带Retry-After: 1routes.tsPOST /api/codex-auth/loginbody{ id? }浏览器 OAuth 流程服务端拉起浏览器返回{ ok, flowId, url, instructions? }流程进行中重复发起返回 409routes.tsPOST /api/codex-auth/login/cancel/GET /api/codex-auth/login-status?flowId{ ok, cancelled }/{ status: pending\|done\|error\|expired\|idle, accountId?, email?(masked), error? }routes.ts实现细节佐证配额查询直接遍历listAccountQuotas()内存表routes.tsreset-credits 消费端具备幂等 operationId 与 503 忙碌语义routes.ts。四、Family B —— 通用 OAuth provider 账户契约管理面在 src/server/management-api.ts 的 accounts/logout 区块约 L1427-L1471处理通用 OAuth 账户。有效 provider 集合由listOAuthProviders()给出xai、anthropic、kimi、kiro、google-antigravity、cursor、github-copilotchatgpt通过isPublicOAuthProvider排除在公开列表外src/oauth/index.ts。未知 provider 一律 400unknown oauth provider。Endpoint形状 / 语义锚点GET /api/oauth/providers{ providers: string[] }management-api.tsPOST /api/oauth/loginbody{ provider, addAccount? }addAccount: true强制拉起全新浏览器身份返回{ url, instructions? }冲突时 409management-api.tsPOST /api/oauth/login/cancel/POST /api/oauth/login/codecancel 返回{ ok, cancelled }粘贴 code{ provider, input? }→{ ok: true }被拒时 409不适用于 chatgptmanagement-api.tsGET /api/oauth/status?provider{ loggedIn, email?(masked), source?, error?, done, activeAccountId?, accounts?: [{ id, email?(masked), active, needsReauth?, expiresAt? }] }src/oauth/index.tsPOST /api/oauth/logout?provider通过 query 参数指定只移除 ACTIVE 账户并提升第一个剩余账户为 activesrc/oauth/store.tsGET /api/oauth/accounts?provider{ activeAccountId: string \| null, accounts: OAuthAccountSummary[] }掩码展示management-api.tsPUT /api/oauth/accounts/activebody{ provider, accountId }{ ok, provider, activeAccountId }缺 id 400、不存在 404 account not found。立即生效——getCredential每次请求重读 active 行src/oauth/store.tsDELETE /api/oauth/accounts?providerid{ ok: true }缺 id 400不存在 404删除 active 时提升第一个剩余账户src/oauth/store.ts存储层背景OAuth token 存在~/.opencodex/auth.json按 provider 名组织为ProviderAccountSet{ activeAccountId, accounts: [{ id, credential, needsReauth?, addedAt? }] }旧的单凭证形态{ access, refresh, expires, ... }在加载时自动归一化首次以新形态落盘会先备份auth.json.pre-multiauth防止降级加载器静默丢弃刷新 tokensrc/oauth/store.ts。五、Family C —— API-Key 池契约API-Key 池仅对isKeyAuthProvider判定的 provider 开放——即鉴权方式既非 oauth 也非 forward 的已配置 providersrc/providers/api-keys.ts。池定义在provider.apiKeyPoolsrc/types.tsprovider.apiKey镜像当前 active 条目。key id 为sha256(key)[:8]前 8 位src/providers/api-keys.ts掩码规则maskApiKeyfirst4****last4长度 ≤ 8 时整体显示****${ENV}引用原样展示src/providers/api-keys.ts。Endpoint形状 / 语义锚点GET /api/providers/keys?name{ activeId: string \| null, keys: [{ id, label?, masked, active, addedAt? }] }非 key provider 返回{ activeId: null, keys: [] }未知 name 返回 404management-api.ts / api-keys.tsPOST /api/providers/keysbody{ name, key, label? }201{ ok, id }新 key立即成为 ACTIVE同时清空 model/quota 缓存与 key 冷却状态management-api.tsPUT /api/providers/keys/activebody{ name, id }{ ok, name, activeId }缺 id 400未知 provider/key 404。立即生效镜像provider.apiKeymanagement-api.tsDELETE /api/providers/keys?nameid{ ok: true }删除 active 时提升第一个剩余 keymanagement-api.ts相邻端点注意区分GET /api/key-providerskey 登录选择器的元数据GET/POST/DELETE /api/keys代理自身的准入 keyadmission keys——POST 返回完整ocx_…key且只返回一次用于外部客户端接入代理。六、Provider 能力判别矩阵程序化判别依据两个字段authKindsrc/providers/registry.ts与codexAccountMode值为direct | pool见 src/types.ts二者均通过GET /api/provider-presets暴露src/providers/derive.ts。ProviderauthKind账户能力openai内置forwardCodex 池默认或仅主账户codexAccountMode: directxaioauth多账户anthropicoauth多账户kimioauth多账户——JWTuser_id/sub稳定身份src/oauth/kimi.ts并非issue 假设的单槽kirooauth替换式单槽——凭证中不含 accountId/emailsrc/oauth/store.tsgoogle-antigravityoauth多账户cursoroauth多账户JWTsubgithub-copilotoauth多账户全部authKind: keyprovideropenrouter、groq、google、cerebras、opencode、qwen-* 等keyapiKeyPool多 key active 镜像ollama / vllm / lm-studiolocal无凭证已知缺口多账户与替换式单槽的差异无法仅凭 HTTP 判别。SINGLE_SLOT_PROVIDERS常量只覆盖chatgptsrc/oauth/store.tskiro 的替换行为来自无身份凭证分支登录时未提取 accountId/emailsrc/oauth/store.ts。因此 CLI 必须硬编码已知的替换式集合kiro或向用户展示通用提示。七、服务端缺失契约与 CLI 落地结论调研同时记录了五条对 CLI 账号命令有直接影响的“服务端缺口”没有跨 provider 的聚合账户视图——CLI 必须扇出先GET /api/oauth/providers再对每个 provider 调GET /api/oauth/accounts并对每个 key-provider 调GET /api/providers/keysCodex 池是唯一自带聚合的Codex 池没有手动粘贴 code 的登录路径仅浏览器流程——openai 的account add保持浏览器流超出最小命令集范围没有可经 HTTP 推导的多/替换标志见矩阵缺口PUT /api/codex-auth/active不强制立即切换——已 pin 线程保留原账户CLI 输出必须注明applies to new sessions/threads可容忍的不对称DELETE /api/codex-auth/accounts与DELETE /api/keys对未知 id 返回 200/api/oauth/logout走 query 参数。最终结论issue #180 的最小范围list/current/use不需要任何新的服务端契约——三大家族已经完整暴露了所需的读取与切换能力。这为 CLI 账号子命令的实现划定了清晰的集成边界读操作走扇出式聚合切换操作分别落在PUT /api/codex-auth/activeCodex 池、PUT /api/oauth/accounts/activeOAuth 多账号与PUT /api/providers/keys/activeKey 池之上并各自遵守上文表格中的鉴权、掩码与幂等语义。赞分享【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载相关推荐HAMi异构GPU调度如何让AI计算资源利用率提升100%HAMi异构GPU调度如何让AI计算资源利用率提升100% 在当今AI计算浪潮中GPU资源短缺与浪费并存成为企业面临的严峻挑战。 HAMi异构AI计算虚拟云原生容器编排人工智能任务调度IronClaw Reborn 产品认证契约解析OAuth 流程、凭证账户与 HTTP 路由的完整实现指南IronClaw Reborn 产品认证契约解析OAuth 流程、凭证账户与 HTTP 路由的完整实现指南 IronClaw 是一个以隐私、安全与可扩展性为核人工智能AI 应用交互助手AI Agentopencodex 多账号安全加固账户生命周期事务与凭据代际失效机制解析opencodex 多账号安全加固账户生命周期事务与凭据代际失效机制解析 opencodex 作为同时服务 OpenAI Codex 与 Claude Cod上一篇react-native-elements Switch 组件完全指南props 详解与跨平台实现原理下一篇前端大文件上传终极优化指南5个高效并发上传与进度控制技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
