Repository navigation
fix(auth): keep MCP agent logins alive and let users disconnect agents - #361
Merged
Merged
Conversation
Codex runs many processes off one stored MCP credential, and each refreshes from its own in-memory copy when it next needs Fanout, minutes or hours after another process has already rotated the refresh token. A one-minute reuse grace did not cover that: on prod a second process presented the rotated token 140 seconds later, the family was revoked, and every Codex process was signed out, about once an hour. Other MCP operators report the same pattern upstream (openai/codex#46028, #45944, #48507). Access tokens now last 30 days and refresh tokens 90 days, renewed on each use, so agents refresh at most monthly and re-login only after 90 idle days. A rotated refresh token stays reusable by its own client, while its family is live, for one access-token lifetime. Rotation and replay-family revocation remain for later reuse. Access tokens are checked against the database on every request, so the longer lifetime is safe only if users can cut off one agent. Settings now lists the agents connected to the signed-in user's account, through GET /api/auth/oauth/connections, and Disconnect revokes one client's tokens through POST /api/auth/oauth/connections/{id}/revoke, with an audit event. Disconnecting, and an administrator's revoke-all, also delete that client's or user's pending authorization codes, so a code issued before the disconnect cannot mint a new family. Claude-Session: https://claude.ai/code/session_018HfyEXHyGD1utmKF4CQtyQ
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.
Problem
Codex runs many processes off one stored MCP credential. Each one refreshes from its own in-memory copy when it next needs Fanout, which can be minutes or hours after another process has already rotated the refresh token.
The one-minute reuse grace from #359 did not cover that. On prod, one Codex process rotated the token at 03:54:05Z, and a second presented the rotated token at 03:56:25Z. The family was revoked and every Codex process was signed out. With one-hour access tokens, this happened about hourly.
Other MCP server operators report the same pattern upstream: openai/codex#46028, #45944 and #48507. Codex's own fix (
mcp_oauth_refresh_coordination) is still labelled under development.Change
Token lifetimes:
Rotation and replay-family revocation stay for reuse after the window, for expired tokens, other clients and revoked families.
Connected agents:
GET /api/auth/oauth/connections).POST /api/auth/oauth/connections/{id}/revoke), with anoauth_connection.revokedaudit event.Pending authorization codes: a disconnect, and the existing administrator revoke-all (
POST /api/users/{id}/access/revoke), now delete that client's or user's pending authorization codes. A code issued before the disconnect can no longer mint a new family.Security trade-off
Verification
just test ./internal/auth/... ./internal/api/... ./cmd/...just ui-check,just docs-generate-check, Settings unit testshttps://claude.ai/code/session_018HfyEXHyGD1utmKF4CQtyQ