mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: revoke MCP server OAuth grants at the provider on disconnect (#27300)
Closes [CODAGT-805](https://linear.app/codercom/issue/CODAGT-805/revoke-oauth-grants-at-the-source-for-mcp-servers). The experimental MCP server OAuth2 disconnect endpoint previously deleted only the stored token row, leaving the grant active at the OAuth provider. This PR adds provider-side token revocation while keeping local disconnect independent of provider availability. ## Changes - Add `mcp_server_configs.oauth2_revocation_url` in migration `000547`. The value can be configured manually, discovered from RFC 8414 metadata, and managed through the MCP server settings UI. Non-admin responses redact it with the other OAuth2 fields. - Revoke the refresh token first through the RFC 7009 endpoint, then fall back to the access token only for `unsupported_token_type`. Public clients send `client_id`; confidential clients use `client_secret_basic`. - Delete the local token transactionally before best-effort provider revocation. Callers without a token receive the same response for hidden and nonexistent config IDs, and provider failures return a generic warning without exposing provider response bodies. - Require HTTPS revocation endpoints except for HTTP loopback URLs. Redirects must preserve the POST and remain on the configured origin. Redirect errors omit provider-controlled paths and query strings so reflected token material cannot enter logs. - Treat `200 OK` and `204 No Content` as completed revocations. `202 Accepted` remains a failure because it does not confirm completion. - Prevent an in-flight refresh from recreating a token deleted by disconnect. Refresh persistence now uses an optimistic update keyed by token ID and `updated_at`; only the OAuth callback can create a token row. Refresh conflicts reload the current row or clear in-memory auth when disconnect deleted it. - Return `{token_revoked, token_revocation_error}` from disconnect, while retaining SDK compatibility with the legacy `204` response. The UI surfaces provider revocation failures as warning toasts. - Document revocation endpoint discovery, HTTPS requirements, and best-effort disconnect behavior. No token or no configured revocation URL returns `token_revoked: false` without an error, so disconnect remains idempotent. > Updated by Mux, an AI coding agent, on Mike's behalf.
This commit is contained in:
@@ -75,10 +75,14 @@ each user independently completes the authorization flow.
|
||||
|
||||
Optional fields:
|
||||
|
||||
| Field | Description |
|
||||
|------------------------|---------------------------------|
|
||||
| `oauth2_client_secret` | OAuth2 client secret. |
|
||||
| `oauth2_scopes` | Space-separated list of scopes. |
|
||||
| Field | Description |
|
||||
|-------------------------|-------------------------------------------|
|
||||
| `oauth2_client_secret` | OAuth2 client secret. |
|
||||
| `oauth2_scopes` | Space-separated list of scopes. |
|
||||
| `oauth2_revocation_url` | Token revocation endpoint URL (RFC 7009). |
|
||||
|
||||
The revocation endpoint must use HTTPS.
|
||||
Loopback URLs may use HTTP for local development and tests.
|
||||
|
||||
**Auto-discovery** — leave `oauth2_client_id`, `oauth2_auth_url`, and
|
||||
`oauth2_token_url` empty. The server attempts discovery in this order:
|
||||
@@ -87,9 +91,17 @@ Optional fields:
|
||||
1. RFC 8414 — Authorization Server Metadata
|
||||
1. RFC 7591 — Dynamic Client Registration
|
||||
|
||||
Auto-discovery also records the provider's `revocation_endpoint` from the
|
||||
RFC 8414 metadata when advertised. An explicit `oauth2_revocation_url` in
|
||||
the request takes precedence over the discovered value.
|
||||
|
||||
Users connect through a popup that redirects through the OAuth2 provider.
|
||||
Tokens are stored per-user and refreshed automatically. Users can disconnect
|
||||
via the UI or API to remove stored tokens.
|
||||
via the UI or API to remove stored tokens. When a revocation endpoint is
|
||||
configured, disconnecting also asks the provider to revoke the token
|
||||
(RFC 7009). Provider revocation is best-effort: the stored token is always
|
||||
deleted from Coder, and the disconnect response reports whether provider
|
||||
revocation succeeded via `token_revoked` and `token_revocation_error`.
|
||||
|
||||
### API key
|
||||
|
||||
|
||||
Reference in New Issue
Block a user