fix: enable silent token refresh in proxy mode#32
Conversation
In proxy mode, automatically append offline_access to the OAuth scope list when it is not already present. Most OIDC providers (Okta, Azure AD, etc.) only issue a refresh token when offline_access is explicitly requested as a scope. The existing oauth2.AccessTypeOffline option only appends access_type=offline to the authorization URL, which is honoured by Google but ignored by the rest. Without a refresh token, clients such as Claude Desktop cannot silently renew credentials and must prompt the user to re-authenticate every time the access token expires (~1 h). The guard is idempotent: callers who already include offline_access in their configured scope list are unaffected.
Add refresh_token to grant_types_supported in GetAuthorizationServerMetadata (both native and proxy mode branches) and HandleOIDCDiscovery. The /oauth/token handler already supports the refresh_token grant type, but the discovery documents were only listing authorization_code. Per RFC 8414 a conformant client will not attempt silent token renewal if refresh_token is absent from grant_types_supported, causing it to force a full re-authentication every time the access token expires. HandleRegister already returned both grant types correctly; this brings the discovery endpoints in line with that and with the actual behaviour of the token endpoint.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThis PR enables OAuth2 refresh token support by ensuring proxy mode includes the ChangesOAuth2 Refresh Token Support
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
Problem
Claude Desktop (and other MCP clients) require silent token renewal to avoid forcing users to re-authenticate every hour when the access token expires.
Two bugs prevented this from working in proxy mode:
1.
grant_types_supportedmissingrefresh_tokenin discovery documentsGetAuthorizationServerMetadata()andHandleOIDCDiscovery()only listedauthorization_code. Per RFC 8414, a conformant client will not attempt silent renewal ifrefresh_tokenis absent — it will fall back to a full re-auth. Notably,HandleRegister()already returned both grant types correctly; this brings the discovery endpoints in line.2.
offline_accessscope not requested from upstream providerMost OIDC providers (Okta, Azure AD, etc.) only issue a refresh token when
offline_accessis explicitly present in the scope list. The existingoauth2.AccessTypeOfflineoption only appendsaccess_type=offlineto the authorization URL, which is recognised by Google but silently ignored by Okta/Azure. Withoutoffline_accessin the scopes, the upstream provider never issues a refresh token, so there is nothing for the client to renew with.Changes
metadata.goAdd
"refresh_token"togrant_types_supportedinGetAuthorizationServerMetadata()(both native and proxy mode branches) andHandleOIDCDiscovery().handlers.goIn
NewOAuth2ConfigFromConfig, whenmode == "proxy", automatically append"offline_access"to the scope list if not already present. The guard is idempotent — callers who already includeoffline_accessin their configured scopes are unaffected.Testing
go test ./...)Summary by CodeRabbit
New Features