Repository navigation
fix(oauth): harden OAuth login/import, quota diagnostics, service/update paths and shim token handling (B5) - #7397
Merged
Conversation
Co-authored-by: Ingwannu <186453546+Ingwannu@users.noreply.github.com>
…ble (carry #7304) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
…#7343) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
…7301) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
…7313) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
…arry #7342) Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
All three Codex shims loaded the service API token into OPENCODEX_API_AUTH_TOKEN before checking OCX_SHIM_BYPASS, so a bypassed native passthrough launch handed the proxy data-plane token to the real Codex and its descendants. The POSIX, CMD and PowerShell shims now skip the token load under bypass; the Unix revision marker moves to 4 so installed wrappers are refreshed. loadServiceTokenFromFile reads the inherited OCX_API_TOKEN_FILE through a no-follow, nonblocking descriptor, accepts only a regular file of at most 4 KiB and returns only a single-line printable token.
…tion Re-applying the same utimes moves ctime only after the kernel clock ticks, so the real ctime case from #7301 often observed no change and the reader correctly returned {}. Repeat the call until ctime has advanced (bounded), assert that precondition, then require desktop_config_not_regular. Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
…t import (carry #7385) An Antigravity account whose Cloud Code Assist project is not auto-discovered was rejected with missing_project even when the operator knows its project. A Cockpit record may now carry a bounded project_id (Google Cloud project grammar, 6-30 chars, exact match). Discovery keeps precedence; the fallback is admitted only after the account quota probe succeeds with that account own access token against that project. Probe refusal, probe errors and cancellation write nothing. No shared default project. Co-authored-by: yobushka <51312852+yobushka@users.noreply.github.com>
Anthropic per-account quota rows reported quotaUnavailable with no reason, and Antigravity reported account_unavailable for any credential-side throw. The Anthropic usage read now reports a closed code for an HTTP status class, an unusable body or a thrown dispatch, and a probe that cannot obtain a credential reports account_unavailable without dispatching. Antigravity distinguishes a credential refresh deadline (timeout). Codes reuse the existing closed QUOTA_FAILURE_CODES set, carry no upstream text and never change account health.
…r restore case The atomic writer renames onto the symlink-resolved target, so on macOS (/var -> /private/var) the rollback rename never matched the fixture path and the restore-failure injection did not fire. Compare both spellings. Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
…ort request probeAntigravityUsageQuota accepts an optional caller signal that cancels every request of the probe and stops before the models fallback; the import verifier forwards the import signal and never admits after cancellation.
…e bypass CMD and PowerShell wrappers now carry a Windows revision marker. A marked wrapper without it (installed before the bypass-token fix) is obsolete: installCodexShim and autoRestoreCodexShim rewrite it in place over the same backing launcher instead of reporting it healthy or already installed, and diagnostics report it unhealthy. On Windows the service token reader also binds the opened descriptor to the path by identity, so a link swapped in after lstat is refused.
…rrent replacement The obsolete-wrapper refresh truncated whatever occupied the wrapper path. It now moves the observed wrapper aside and proves it is the probed file, stages the current wrapper beside it, and publishes with a hard link that refuses an occupied path. A concurrent replacement is restored or kept untouched and the refresh reports deferred.
…ume partial upgrades The refresh stage is now created with O_CREAT|O_EXCL (and O_NOFOLLOW on POSIX) under an independent random name, and publication, withdrawal and cleanup are bound to the identity of the file this refresh created, so a planted link is never written through. Auto-restore resumes a Windows revision-only sibling mix (current plus obsolete wrappers) instead of deferring forever after one transient publish failure.
…ed identities Publication keeps a linked entry only if it is the created stage, and withdraws a link to a swapped stage (file or symlink) while leaving independent replacements. Restoring the moved wrapper requires the aside to still be the moved file. Automatic revision recovery now refreshes only the admitted obsolete wrappers and first re-verifies every current sibling, so a replacement during the stability wait is never adopted.
…t be published The refresh proves hard-link support in the wrapper directory with a throwaway pair before moving the wrapper aside, and if a restore link still fails it falls back to an identity-checked rename onto the empty path, so the launcher never stays missing.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Contributor
|
✅ Deterministic PR hygiene checks passed. |
Contributor
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing: 77
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
2 of 3 tasks
This was referenced Oct 19, 2026
Closed
Transient OAuth login failure persists in getLoginStatus and masks active account in dashboard
#7378
Closed
lidge-jun
added a commit
that referenced
this pull request
Oct 19, 2026
Merged with #7397, the three new rows pushed layout.json to 2001 lines. Fold them onto neighboring rows; the file stays at dev's 1998. Co-authored-by: adaurban <31841049+adaurban@users.noreply.github.com> Co-authored-by: HeiTuz <79418013+HeiTuz@users.noreply.github.com>
This was referenced Oct 19, 2026
lidge-jun
added a commit
that referenced
this pull request
Oct 19, 2026
…l-result handling for 2.90 (#7395) * fix(opengateway): normalize paired tool result inputs Carry the input-normalization slice of draft #7281 (16263b7). Preserve call/result identities and image content while projecting text arrays; reject unsupported or malformed parts explicitly instead of forwarding them. Keep the normalizer independently covered by mocked, immutable-input tests. Co-authored-by: HeiTuz <79418013+HeiTuz@users.noreply.github.com> * fix(opengateway): inspect empty completions with bounded replay Carry the independent completion guard and replay-safety tests from draft #7281 (16263b7). Inspect SSE/JSON only before meaningful output, release the held prefix on time/size expiry, and permit at most one eligible retry callback. Release the owned reader lock on cancellation and remove a redundant counter. Co-authored-by: HeiTuz <79418013+HeiTuz@users.noreply.github.com> * fix(opengateway): integrate completion recovery with the send budget Port the remaining adapter/dispatch integration from draft #7281 (16263b7) onto current dev. Map input incompatibility to HTTP 400 before any send; cap empty-completion recovery at one physical send, including HTTP 503 and connection-reset failures, while preserving existing admission and accounting. Cover the actual handler with mocked fetches and keep English/Korean guidance consistent. Split the OpenGateway structure contract to stay within document budgets and distinguish native recovery from the translated opt-in guard. Verification: typecheck, 118 focused tests, 27 layout tests, 9 size-ratchet tests, structure and privacy checks, and the docs build passed. Changed-mode rerun passed 19780 tests with 34 skips (30s timeout, two workers); the first run had one unrelated package-tree subprocess timeout, which also passed standalone. Co-authored-by: HeiTuz <79418013+HeiTuz@users.noreply.github.com> * fix(mistral): preserve cache keys and recover from rate limits Canonical key-auth Mistral Chat now sends prompt-cache keys, paces each credential/model pair from measured refusal headers with bounded, abortable waits outside the upstream header deadline, and retries 429s with a slower default budget. A server delay beyond the retry budget is kept non-replayable and its Retry-After reaches the caller. Relays, other adapters, OAuth credentials and xAI are unchanged. Co-authored-by: adaurban <31841049+adaurban@users.noreply.github.com> * fix(mistral): pace native Chat sends through the Mistral transport A single-key native Chat route never re-resolved its transport, so the new Mistral retry default replayed an over-budget Retry-After after 60 seconds instead of returning the refusal. Co-authored-by: adaurban <31841049+adaurban@users.noreply.github.com> * fix(opengateway): share the exact-URL boundary between normalization and recovery Co-authored-by: HeiTuz <79418013+HeiTuz@users.noreply.github.com> * test(responses): inventory the OpenGateway completion owners Co-authored-by: HeiTuz <79418013+HeiTuz@users.noreply.github.com> * fix(mistral): keep evicted pacing deadlines in force At 128 live identities the pacer dropped the oldest deadline, so that credential/model pair could send before its Retry-After. Remember the latest evicted deadline and make identities without an entry wait it out; memory stays bounded and the only cost is conservative pacing under extreme fan-out. Co-authored-by: adaurban <31841049+adaurban@users.noreply.github.com> * test(layout): keep B4b registrations within the layout file budget Merged with #7397, the three new rows pushed layout.json to 2001 lines. Fold them onto neighboring rows; the file stays at dev's 1998. Co-authored-by: adaurban <31841049+adaurban@users.noreply.github.com> Co-authored-by: HeiTuz <79418013+HeiTuz@users.noreply.github.com> * fix(mistral): hold only same-key replays on an over-budget Retry-After Marking the refusal non-replayable also blocked key-pool rotation and sanitized the upstream body. Use a same-target retry hold that only the same-key 429 loops check (native Chat, adapter dispatch and continuation, image and web-search loops), carried across response rewraps, so another pooled key can still serve and the original status, body and Retry-After reach the caller. Also keep an evicted identity's live deadline in force when it re-enters with a shorter delay. Co-authored-by: adaurban <31841049+adaurban@users.noreply.github.com> --------- Co-authored-by: HeiTuz <79418013+HeiTuz@users.noreply.github.com> Co-authored-by: adaurban <31841049+adaurban@users.noreply.github.com>
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bundle B5 for 2.90: OAuth login/import, account health diagnostics, service/update hardening, and a Codex shim token-exposure fix. It carries nine contributor PRs onto current
dev, reworks a tenth (#7385) to meet its review, and adds three new fixes.Shim token exposure (security). All three Codex shims loaded the service API token into
OPENCODEX_API_AUTH_TOKENbefore checkingOCX_SHIM_BYPASS, so a bypassed native launch handed the proxy's data-plane token to the real Codex and everything it spawned. Now:shim-probe.ts) sets bypass and never needed the token.src/codex/shim-windows-refresh.ts) that never truncates or writes through a concurrent replacement or a planted link. A partial sibling upgrade resumes automatically.loadServiceTokenFromFilereads the inheritedOCX_API_TOKEN_FILEthrough one bounded descriptor: no-follow and nonblocking on POSIX, a dev/ino identity recheck on Windows, regular file only, at most 4 KiB, single-line printable token.#7380 quota diagnostics. A per-account quota probe that returns no quota now names one closed
quotaFailurecode, drawn from the existing ten-code set, so the GUI needs no change.account_unavailable(no request sent), the HTTP status class,response_unusable, ortimeout/transport_error.timeout) fromaccount_unavailable.needsReauthare never changed.#7382 via #7385, reworked. A Cockpit import record may carry an optional
project_id. Discovery always wins. The fallback is used only when discovery finds no project, and only after the account's own token passes the existing Antigravity quota probe for that project. There is no shared default project.Items fixed
ocx codexlauncher mirroringocx claude#7346's review; no issue number).Carried PRs
utimesuntil ctime really advances (bounded), asserts that, then requires rejection (10/10 runs). Also fixed a macOS-only picker test failure: the atomic writer renames onto the symlink-resolved/private/varpathRunAtLoad:truebefore Desktop relaunchproject_idin Cockpit importinvalid_record); probe-gated admission with the account's own token; discovery precedence; cancellation forwarded into the probe; no write on refusal, error or cancel; fakes only in tests; owning docstructure/providers/antigravity-account-import.mdand providers guideCo-authored-by: Ingwannu 186453546+Ingwannu@users.noreply.github.com
Co-authored-by: luvs01 27862058+luvs01@users.noreply.github.com
Co-authored-by: yobushka 51312852+yobushka@users.noreply.github.com
Held out
ocx codexlauncher mirroringocx claude#7346ocx codexlauncher feature: only its review's security defect is fixed here; the launcher can rebase on this.response_unusablerather thantimeout/transport_error, becausereadQuotaJsoncollapses body-read failures. It is diagnosis granularity only and leaks nothing.Judgment calls
quotaFailurecodes. The GUI translates exactly the existing ten, and GUI work is out of scope, so every new diagnosis maps onto an existing code.project_idprobe reports the existingmissing_projectcode; adding a new code would also touch the CLI and GUI code lists.Security review
SECURITY REVIEW: PASS
A dedicated sol (gpt-6.1-sol) security review ran over the full diff, iterating until it passed:
Each finding was fixed with a regression test. The sol code review found 0 P0 / 0 P1; its two P2s are covered above (one fixed, one held out).
Verification
All commands run on this host (macOS, Bun 1.4.3) from the repository root, at the final head rebased on
origin/dev74463a2.bun run typecheck— pass.bun run structure:check— pass.bun run structure:indexwas regenerated for the newproviders/antigravity-account-import.md.bun run privacy:scan— pass.tests/ci-workflows/file-size-ratchet.test.ts,import-cycle-ratchet.test.ts,structure-ssot.test.ts,tests/test-layout.test.ts,tests/test-layout-tooling.test.ts,tests/lab/core-lab-boundary.test.ts) — 128 pass, 0 fail.bun test --isolateover the 31 files covering every carried and new change (oauth status, fix(providers): preserve explicit key mode when credentials are unavailable #7304 boundary/upsert/selection/router, DSH, Claude CLI admission, Desktop library/picker, service wrapper/preflight, cold start, updater env, service secrets/WinSW, account import + fallback, quota failure reasons + account quota + accounts API, shim bypass/Windows revision/standalone) — 737 pass, 0 fail.bun test --isolate tests/service/service.test.ts— 212 pass, 0 fail.tests/codex-integration/codex-shim*.test.ts,codex-shim-path-readiness.test.ts) — under host load average 15–29 some spawn-based cases hit their 2–5 sETIMEDOUT. Every one of those cases was rerun back-to-back on this branch and on a cleanorigin/dev74463a2 checkout. Both give identical results: 7 pass, and 1 fails identically on both (Unix shim permits a real Codex process to start a new child invocation, a 2 s spawn timeout). Every shim test that changed in this PR (bypass token, Windows revision and transaction, standalone, readiness fixture) passes.bun run test:changed(before the last rebase and the round-5 fix): 35393 pass / 102 skip / 4 fail across 1599 files.ETIMEDOUT. At load average 22–29, the same shim tests fail identically on a cleanorigin/devcheckout under the same load, so they are host contention.test:changedfound one real failure: a macOS-only picker fixture path in the fix(claude): bound Desktop library reads and preflight writes #7301 carry, fixed here.bun run testwas not run: several worktrees share this host and spawn-timed tests are unreliable at this load. The rest of the cross-platform coverage is left to CI. Windows shim behavior is covered by template-text tests andprocess.platformemulation; native Windows shells were not executed.No live provider, OAuth or
ocxservice calls were made.Ratchet hot files touched:
src/providers/quota.ts549/558,src/codex/shim.ts1243/1246,tests/service/service.test.ts4104/4106. No touched file without a baseline cap reaches 2000 lines (scripts/test-layout/layout.jsonis 1998; it has no cap and passes the ratchet, but is close to the 2000 line mark).Checklist