Skip to content

[codex] Serialize MCP OAuth credential refreshes#347

Merged
GraciousGazelles merged 5 commits into
mainfrom
codex/mcp-oauth-persistence-f948
Jun 20, 2026
Merged

[codex] Serialize MCP OAuth credential refreshes#347
GraciousGazelles merged 5 commits into
mainfrom
codex/mcp-oauth-persistence-f948

Conversation

@GraciousGazelles

Copy link
Copy Markdown
Collaborator

Summary

  • Serialize shared MCP OAuth refresh/login/logout writes under a per-server lock in CODEX_HOME.
  • Keep Codex as the owner of refresh-token persistence by passing request-only credentials to the RMCP client.
  • Reread the credential store before refresh and recover once from Auth required during initialize/operation paths.
  • Treat missing keyring token material as absent credentials instead of surfacing a misleading logged-in state.

Root cause

A completed MCP OAuth login could leave a usable-looking credential record while another Codex/RMCP client path still relied on stale in-memory access-token state or independently attempted refresh/persistence. After restart, Codex could then report that the server was not logged in even though the login flow appeared to complete.

This change centralizes refresh ownership in Codex and makes refresh/write paths lock and reread the authoritative store before mutating it.

Validation

Draft because this touches shared MCP OAuth client behavior and should get maintainer review before merge.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors OAuth token management by introducing cross-process file locking during token operations and implementing a transactional refresh mechanism to prevent replaying stale rotating tokens. It also updates the client to handle unauthorized errors with OAuth recovery. Feedback on the changes highlights critical compilation issues in oauth.rs due to the use of non-existent try_lock methods on std::fs::File, as well as potential thread starvation risks from calling blocking synchronous I/O and std::thread::sleep directly within async functions.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread codex-rs/rmcp-client/src/oauth.rs
Comment thread codex-rs/rmcp-client/src/oauth.rs
Comment thread codex-rs/rmcp-client/src/oauth.rs
Comment thread codex-rs/rmcp-client/src/oauth.rs

Copy link
Copy Markdown
Collaborator Author

Upstream-harvest refresh before landing:

Current downstream adoption choice: keep this PR as a downstream port/review surface for the upstream-in-flight architecture rather than waiting for the full upstream stack to merge, because the local MCP login/restart path is already user-visible broken.

Fresh validation after formatter repair commit 211b4d38197bdc8618718fbb9514e0d96bb7adcb:

  • gh pr checks 347 --watch --fail-fast --interval 60 completed successfully.
  • Passed gates include Rust CI required gate, CodeQL required gate, Format / etc, cargo-deny, cargo shear, codespell, and argument-comment lint on Linux/macOS/Windows.
  • Earlier targeted validation remains: https://github.com/sednalabs/codex/actions/runs/27863218322

@GraciousGazelles GraciousGazelles marked this pull request as ready for review June 20, 2026 09:00

Copy link
Copy Markdown
Collaborator Author

Resolving the remaining Gemini review threads after the base-update validation pass:

  • The compile concern about File::try_lock / TryLockError is not reproduced on the pinned CI toolchain; the branch now passes Rust CI, CodeQL, heavy smoke, and rust integration lanes after the base update.
  • The save_oauth_tokens_locked / delete_oauth_tokens_locked comments are valid performance considerations, but not correctness blockers for this regression fix. These wrappers serialize small credential-store operations behind bounded locks; moving all keyring/file work to spawn_blocking would be a broader async-I/O cleanup and is better handled as a follow-up if profiling or executor contention shows it matters.
  • For this PR, the critical safety property is preserving a single Codex-owned OAuth credential transaction: lock, reread authoritative persisted credentials, refresh/adopt, persist rotated state, and retry once on 401/Auth required.

Given the fresh green checks and the upstream OpenAI stack using the same architectural direction, I’m resolving those threads so branch protection can evaluate the already-validated fix.

@GraciousGazelles GraciousGazelles merged commit b577903 into main Jun 20, 2026
52 checks passed
@GraciousGazelles GraciousGazelles deleted the codex/mcp-oauth-persistence-f948 branch June 20, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant