Skip to content

gproxy v2.9.0

Choose a tag to compare

@LeenHawk LeenHawk released this 21 Aug 03:03

v2.9.0

⚠️ THIS RELEASE CANNOT BE ROLLED BACK — READ BEFORE UPGRADING.
v2.9.0 rewrites every user API-key digest in place (migration 27). v2.8.3 and
earlier hash the full token including sk-, so once upgraded they reject
every API key with a plain 401 unauthorized and no diagnostic in the logs.
Back up the database first. Rolling the binary back requires restoring the
pre-upgrade database with it — swapping only the binary locks out every key on
every route.

⚠️ 本次发布不可回退 —— 升级前请先阅读。
v2.9.0 会原地重写所有用户 API key 的摘要(migration 27)。v2.8.3 及更早版本对
sk- 前缀的完整 token 取哈希,因此升级后再退回旧版本,所有 API key 都会
被拒绝
,只返回朴素的 401 unauthorized,日志中没有任何线索。
升级前务必备份数据库。 回退二进制必须连同回退到升级前的数据库 —— 只换二进制
会导致所有路由上的所有 key 全部锁死。

Adds Codex PAT keys and the Codex/Claude Code service routes behind them, scoped file APIs, per-metric pricing rates, and stops a single contested key row from taking the whole instance down.

English

Added

  • Codex PAT keys (at- prefix). User keys can now be minted as a Codex personal access token instead of a standard sk- key; the key type is chosen in both the admin Console and the user portal. sk-X and at-X are presentation prefixes over the same identity, so the two forms of one key resolve to the same user — see the rollback warning above for what that costs.

  • Codex service routes. /api/codex/** now proxies the Codex control surface: environments (including lookup by repo), files, profiles/me, the config bundle, account checks, analytics events, and rate-limit reset credits. Task-to-credential bindings are persisted so a Codex task keeps landing on the credential that started it.

  • Claude Code API key services. /api/claude_cli/bootstrap, the CLI profile and penguin-mode endpoints, Claude Code skills, organization and OAuth file routes, and /v1/files are served for Claude Code clients.

  • Scoped file APIs. OpenAI /v1/files is modelled end to end, with a File Upload Concurrency instance setting bounding concurrent uploads (0 or blank for unlimited). A database size cap is also available on native SQLite: when exceeded, the oldest request and audit logs are compacted away until the database reaches 90% of the limit — usage data is always preserved.

  • Claude files and skills GA. The protocol crate models the GA shape of Claude files and skills, including skill versions.

  • Per-metric pricing rates. Price rules take independent rates for audio, images, search, requests and video, with unit sizes and conditional variants, and local cost is exposed across billable responses rather than only in usage rollups.

Changed

  • Claude OAuth tokens refresh thirty minutes early. The proactive refresh window was five minutes, which left almost no slack: a token that expired while an instance was down came back already dead, and Claude rotates the refresh token on every refresh, so the stale copy could not be recovered. The window is now thirty minutes.

  • User key digests are prefix-free. Digests are hashes of the key payload with sk-/at- stripped, so both presentations of a key resolve to one identity. Existing rows are normalized once on the first v2.9.0 boot. This is the change that makes the release irreversible.

Fixed

  • A contested key digest no longer refuses to start. A database holding both sk-X and at-X cannot normalize every row, because the two collapse to one identity under a unique index. Both the migration and the snapshot build previously answered that with a hard error, so one contested row took the entire instance down — recoverable only by editing the database by hand. The contested row is now left unmigrated and dropped from the identity map with a warning: it fails closed and cannot authenticate, while every other key keeps working. Resolution is deterministic — an already-normalized key never loses its digest, and the lowest id wins among legacy rows.

  • Quotas gate on live rows. Authorization checked the frozen control-plane snapshot, so a quota edited mid-flight kept being enforced at its old value until the next rebuild. It now reads live quota rows.

  • Pending image generation items. Image generation items that arrive still pending are carried through the Responses conversion instead of being dropped.

  • Codex route labels and endpoint metadata are corrected in the Console.

简体中文

新增

  • Codex PAT key(at- 前缀)。 用户 key 现在可以签发为 Codex 个人访问令牌,而不只是标准的 sk- key,key 类型在管理台和用户门户中均可选择。sk-Xat-X 是同一身份的两种呈现前缀,因此一把 key 的两种写法解析到同一用户 —— 代价见上方的回退警告。

  • Codex 服务路由。 /api/codex/** 现在代理 Codex 控制面:环境(含按仓库查找)、文件、profiles/me、配置包、账号检查、分析事件,以及限流重置额度。任务与凭据的绑定关系会持久化,使同一个 Codex 任务始终落在最初处理它的凭据上。

  • Claude Code API key 服务。 为 Claude Code 客户端提供 /api/claude_cli/bootstrap、CLI profile 与 penguin-mode 端点、Claude Code skills、组织与 OAuth 文件路由,以及 /v1/files

  • 带作用域的文件 API。 完整建模 OpenAI /v1/files,并新增「文件上传并发数」实例设置以限制并发上传(留空或 0 表示不限)。原生 SQLite 还支持数据库体积上限:超出后会压缩清理最旧的请求日志与审计日志,直到数据库回落到上限的 90% —— 用量数据始终保留。

  • Claude 文件与 skills GA。 protocol crate 按 GA 形态建模 Claude 文件与 skills,含 skill 版本。

  • 按计量项计价。 计价规则支持为音频、图片、搜索、请求、视频分别设置独立费率,可配置单位大小与条件变体;本地成本现在会在所有计费响应中暴露,而不再只出现在用量汇总里。

变更

  • Claude OAuth token 提前三十分钟刷新。 此前的主动刷新窗口是五分钟,几乎没有余量:实例停机期间过期的 token 再启动时已经失效,而 Claude 每次刷新都会轮换 refresh token,过期的那份无法再挽救。窗口现调整为三十分钟。

  • 用户 key 摘要不含前缀。 摘要改为对剥离 sk-/at- 后的 payload 取哈希,使一把 key 的两种呈现解析到同一身份。已有数据会在首次以 v2.9.0 启动时一次性归一化。正是这一改动使本次发布不可回退。

修复

  • 摘要冲突不再导致实例起不来。 库中同时存在 sk-Xat-X 时无法归一化全部行,因为二者在唯一索引下会归并成同一身份。此前迁移与快照构建都以硬失败应对,于是一行冲突数据就会拖垮整个实例,且只能手工进库修复。现在该行会被跳过、不参与迁移,并从身份表中剔除并告警:它失败关闭、无法认证,而其余所有 key 照常工作。裁决是确定性的 —— 已归一化的 key 永远不会丢失其摘要,legacy 行之间由 id 最小者胜出。

  • 配额基于实时行判定。 鉴权此前读取冻结的控制面快照,导致运行中修改的配额要等到下次重建才生效。现在直接读取实时配额行。

  • 处理 pending 状态的图片生成项。 仍处于 pending 的图片生成项会在 Responses 转换中透传,而不再被丢弃。

  • 修正 Console 中 Codex 的路由标签与端点元数据。