Skip to content

Commit c93f236

Browse files
committed
Serialize MCP OAuth refresh transactions
1 parent f1e1c17 commit c93f236

12 files changed

Lines changed: 1234 additions & 179 deletions

File tree

codex-rs/config/src/types.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ pub enum AuthCredentialsStoreMode {
103103
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
104104
#[serde(rename_all = "lowercase")]
105105
pub enum OAuthCredentialsStoreMode {
106-
/// `Keyring` when available; otherwise, `File`.
106+
/// Prefer `Keyring` and use `File` when keyring storage is unavailable.
107+
/// Once an MCP client loads credentials from one store, that client keeps the resolved store
108+
/// for its lifetime: refresh reads and writes surface store failures instead of switching to
109+
/// the other store and risking replay of an older rotating refresh token.
107110
/// Credentials stored in the keyring will only be readable by Codex unless the user explicitly grants access via OS-level keyring access.
108111
#[default]
109112
Auto,

codex-rs/core/config.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2123,7 +2123,7 @@
21232123
"description": "Determine where Codex should store and read MCP credentials.",
21242124
"oneOf": [
21252125
{
2126-
"description": "`Keyring` when available; otherwise, `File`. Credentials stored in the keyring will only be readable by Codex unless the user explicitly grants access via OS-level keyring access.",
2126+
"description": "Prefer `Keyring` and use `File` when keyring storage is unavailable. Once an MCP client loads credentials from one store, that client keeps the resolved store for its lifetime: refresh reads and writes surface store failures instead of switching to the other store and risking replay of an older rotating refresh token. Credentials stored in the keyring will only be readable by Codex unless the user explicitly grants access via OS-level keyring access.",
21272127
"enum": [
21282128
"auto"
21292129
],

codex-rs/rmcp-client/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ keyring = { workspace = true, features = ["sync-secret-service"] }
8787
# This test is compiled through `#[path]` inside the inline `oauth::tests` module. Cargo-shear
8888
# cannot resolve that nested module path and otherwise reports the linked file as unlinked.
8989
[package.metadata.cargo-shear]
90-
ignored-paths = ["src/oauth/tests/store_lock_tests.rs"]
90+
ignored-paths = [
91+
"src/oauth/tests/persistor_tests.rs",
92+
"src/oauth/tests/store_lock_tests.rs",
93+
]
9194

9295
[lib]
9396
doctest = false

codex-rs/rmcp-client/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ pub use in_process_transport::InProcessTransportFactory;
2626
pub use oauth::StoredOAuthTokens;
2727
pub use oauth::WrappedOAuthTokenResponse;
2828
pub use oauth::delete_oauth_tokens;
29-
pub(crate) use oauth::load_oauth_tokens;
3029
pub use oauth::save_oauth_tokens;
3130
pub use perform_oauth_login::OAuthProviderError;
3231
pub use perform_oauth_login::OauthLoginHandle;

0 commit comments

Comments
 (0)