feat: add disable_vk_identity to suppress virtual-key identity in OAuth consent flow - #4751
Conversation
|
|
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 55 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughAdds a ChangesVK Identity Disable Feature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
disable_vk_identity to suppress virtual-key identity in OAuth consent flow
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (9): Last reviewed commit: "feat: adds options to disable vks in mcp..." | Re-trigger Greptile |
d3f43d6 to
6e6e126
Compare
e99cc6c to
f1911fa
Compare
f1911fa to
c834625
Compare
6e6e126 to
92bc69c
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@transports/bifrost-http/handlers/config.go`:
- Around line 563-571: The validation in config.go only checks
payload.ClientConfig.OAuth2ServerConfig, so it can miss an existing
DisableVKIdentity=true when a partial update changes mcp_server_auth_mode to a
non-oauth mode. Update the guard around the auth-mode check to validate the
merged/configured state used by the handler, not just the incoming payload,
using the existing config fields and effectiveAuthMode logic in the same block.
Ensure the SendError path triggers whenever DisableVKIdentity would remain set
while the final auth mode is not MCPServerAuthModeOAuth.
In `@transports/bifrost-http/server/server.go`:
- Around line 1408-1411: The OAuth2 issuance setup is passing nil into
handlers.NewOAuth2IssuanceHandler, which leaves
OAuth2IssuanceHandler.handleTokenRefresh without an identityResolver and
bypasses the VK-refresh cutoff logic. Update the server initialization in the
code path that creates or registers OAuth2IssuanceHandler so it receives a real
OAuth2IdentityResolver instance from the HTTP server instead of nil, and ensure
RegisterRoutes still uses that configured handler.
In `@ui/app/workspace/config/views/mcpView.tsx`:
- Around line 25-31: The SCIM prerequisite check in mcpView.tsx is treating
loading, missing data, and request errors as the same “not configured” state.
Update the logic around useGetSCIMProvidersQuery and idpConfigured so failures
and in-flight requests are handled separately from an empty provider list, and
only hide the toggle when SCIM is truly unavailable. Make the toggle rendering
in mcpView.tsx distinguish pending/error states from “no IdP configured” so an
already-enabled setting isn’t lost.
- Around line 598-645: The hidden oauth-only flag remains dirty when
`mcp_server_auth_mode` changes away from "oauth", causing `hasChanges` and
`handleSave` in `mcpView.tsx` to submit an invalid `disable_vk_identity` value.
Update the auth-mode change flow (the handler that updates
`localConfig.mcp_server_auth_mode`) to clear or reset
`localConfig.oauth2_server_config.disable_vk_identity` whenever the mode is no
longer "oauth", so the form cannot persist the rejected setting and the save
path stays valid.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 56eb980b-9aea-438e-b281-feaf0c1907c0
📒 Files selected for processing (9)
transports/bifrost-http/handlers/config.gotransports/bifrost-http/handlers/mcpoauth2consent.gotransports/bifrost-http/handlers/mcpoauth2consent_test.gotransports/bifrost-http/handlers/mcpoauth2issuance.gotransports/bifrost-http/handlers/mcpoauth2issuance_test.gotransports/bifrost-http/server/server.gotransports/config.schema.jsonui/app/workspace/config/views/mcpView.tsxui/lib/types/config.ts
92bc69c to
e1cdee5
Compare
c834625 to
da1325d
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@transports/bifrost-http/server/server.go`:
- Around line 1760-1763: The `OAuth2SweepWorker` started in `Serve`/`Start` is
not cleaned up when the `errChan` branch returns on listen/serve failure. Update
the `Start` or `Serve` error path to stop the worker before returning, mirroring
the existing bootstrap and graceful shutdown cleanup; use the
`OAuth2SweepWorker` and `newOAuth2SweepWorker` flow to locate the fix.
- Around line 1797-1803: The OAuth2 signing-key bootstrap in server startup is
currently warning and continuing when GetOAuth2SigningKey fails, which leaves
discovery enabled before JWKS/JWT signing is ready. Update the bootstrap path in
server.go to fail closed by returning an error or aborting startup from the
surrounding initialization flow instead of just logging in the
s.Config.ConfigStore.GetOAuth2SigningKey(s.Ctx) branch. Keep the check gated by
s.Config.ClientConfig.IsMCPOAuthDiscoveryEnabled(), and ensure the caller of
this startup block propagates the failure so the server does not advertise the
OAuth2 surface until the signing key is successfully loaded.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: bb1b8233-7c16-45c9-98db-fd83807576d7
📒 Files selected for processing (9)
transports/bifrost-http/handlers/config.gotransports/bifrost-http/handlers/mcpoauth2consent.gotransports/bifrost-http/handlers/mcpoauth2consent_test.gotransports/bifrost-http/handlers/mcpoauth2issuance.gotransports/bifrost-http/handlers/mcpoauth2issuance_test.gotransports/bifrost-http/server/server.gotransports/config.schema.jsonui/app/workspace/config/views/mcpView.tsxui/lib/types/config.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- transports/bifrost-http/handlers/config.go
- transports/bifrost-http/handlers/mcpoauth2consent.go
- ui/app/workspace/config/views/mcpView.tsx
- transports/bifrost-http/handlers/mcpoauth2consent_test.go
- ui/lib/types/config.ts
- transports/bifrost-http/handlers/mcpoauth2issuance.go
- transports/config.schema.json
- transports/bifrost-http/handlers/mcpoauth2issuance_test.go
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@transports/bifrost-http/server/server.go`:
- Around line 1760-1763: The `OAuth2SweepWorker` started in `Serve`/`Start` is
not cleaned up when the `errChan` branch returns on listen/serve failure. Update
the `Start` or `Serve` error path to stop the worker before returning, mirroring
the existing bootstrap and graceful shutdown cleanup; use the
`OAuth2SweepWorker` and `newOAuth2SweepWorker` flow to locate the fix.
- Around line 1797-1803: The OAuth2 signing-key bootstrap in server startup is
currently warning and continuing when GetOAuth2SigningKey fails, which leaves
discovery enabled before JWKS/JWT signing is ready. Update the bootstrap path in
server.go to fail closed by returning an error or aborting startup from the
surrounding initialization flow instead of just logging in the
s.Config.ConfigStore.GetOAuth2SigningKey(s.Ctx) branch. Keep the check gated by
s.Config.ClientConfig.IsMCPOAuthDiscoveryEnabled(), and ensure the caller of
this startup block propagates the failure so the server does not advertise the
OAuth2 surface until the signing key is successfully loaded.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: bb1b8233-7c16-45c9-98db-fd83807576d7
📒 Files selected for processing (9)
transports/bifrost-http/handlers/config.gotransports/bifrost-http/handlers/mcpoauth2consent.gotransports/bifrost-http/handlers/mcpoauth2consent_test.gotransports/bifrost-http/handlers/mcpoauth2issuance.gotransports/bifrost-http/handlers/mcpoauth2issuance_test.gotransports/bifrost-http/server/server.gotransports/config.schema.jsonui/app/workspace/config/views/mcpView.tsxui/lib/types/config.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- transports/bifrost-http/handlers/config.go
- transports/bifrost-http/handlers/mcpoauth2consent.go
- ui/app/workspace/config/views/mcpView.tsx
- transports/bifrost-http/handlers/mcpoauth2consent_test.go
- ui/lib/types/config.ts
- transports/bifrost-http/handlers/mcpoauth2issuance.go
- transports/config.schema.json
- transports/bifrost-http/handlers/mcpoauth2issuance_test.go
🛑 Comments failed to post (2)
transports/bifrost-http/server/server.go (2)
1760-1763: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Mirror
OAuth2SweepWorkercleanup in theServe-error path.This worker is stopped on bootstrap failures and graceful shutdown, but
Start()still returns from theerrChanbranch without stopping it. If the process stays alive after a listen/serve failure, the sweep goroutine keeps running against a server that never came up.Suggested fix
case err := <-errChan: if s.IntegrationHandler != nil { s.IntegrationHandler.Close() } + if s.OAuth2SweepWorker != nil { + logger.Info("stopping oauth2 sweep worker...") + s.OAuth2SweepWorker.stop() + s.OAuth2SweepWorker = nil + } if s.wsPool != nil { s.wsPool.Close() } return errAlso applies to: 1957-1960
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@transports/bifrost-http/server/server.go` around lines 1760 - 1763, The `OAuth2SweepWorker` started in `Serve`/`Start` is not cleaned up when the `errChan` branch returns on listen/serve failure. Update the `Start` or `Serve` error path to stop the worker before returning, mirroring the existing bootstrap and graceful shutdown cleanup; use the `OAuth2SweepWorker` and `newOAuth2SweepWorker` flow to locate the fix.
1797-1803: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Fail startup if OAuth2 signing-key bootstrap fails.
When discovery is enabled, this only logs and continues, so the server can advertise/register the OAuth2 surface before JWKS/JWT signing is actually ready. That should fail closed during bootstrap instead of degrading into first-request auth failures. As per path instructions, "Apply HTTP/API security review: authentication and authorization checks, fail-closed behavior..."
Suggested fix
if s.Config.ConfigStore != nil && s.Config.ClientConfig.IsMCPOAuthDiscoveryEnabled() { - if _, keyErr := s.Config.ConfigStore.GetOAuth2SigningKey(s.Ctx); keyErr != nil { - logger.Warn("oauth2: failed to bootstrap signing key: %v", keyErr) - } + if _, keyErr := s.Config.ConfigStore.GetOAuth2SigningKey(s.Ctx); keyErr != nil { + return fmt.Errorf("oauth2: failed to bootstrap signing key: %w", keyErr) + } }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.// Bootstrap OAuth2 signing key when discovery is enabled — ensures JWKS // and JWT signing are ready before the first request arrives. if s.Config.ConfigStore != nil && s.Config.ClientConfig.IsMCPOAuthDiscoveryEnabled() { if _, keyErr := s.Config.ConfigStore.GetOAuth2SigningKey(s.Ctx); keyErr != nil { return fmt.Errorf("oauth2: failed to bootstrap signing key: %w", keyErr) } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@transports/bifrost-http/server/server.go` around lines 1797 - 1803, The OAuth2 signing-key bootstrap in server startup is currently warning and continuing when GetOAuth2SigningKey fails, which leaves discovery enabled before JWKS/JWT signing is ready. Update the bootstrap path in server.go to fail closed by returning an error or aborting startup from the surrounding initialization flow instead of just logging in the s.Config.ConfigStore.GetOAuth2SigningKey(s.Ctx) branch. Keep the check gated by s.Config.ClientConfig.IsMCPOAuthDiscoveryEnabled(), and ensure the caller of this startup block propagates the failure so the server does not advertise the OAuth2 surface until the signing key is successfully loaded.Source: Path instructions
e1cdee5 to
ad3df93
Compare
da1325d to
09dee71
Compare
09dee71 to
bc9a251
Compare
a9fef25 to
6686182
Compare
bc9a251 to
217bdba
Compare
6686182 to
6673c1a
Compare
217bdba to
2044a98
Compare
Merge activity
|
The base branch was changed.
6673c1a to
4624785
Compare
…Auth consent flow (#4751) ## Summary Adds a `disable_vk_identity` configuration option that removes virtual-key identity from the OAuth consent flow. When enabled, virtual keys are no longer offered or accepted during OAuth consent, and existing virtual-key grants stop refreshing (they expire within one access-token TTL). The flag is only honored when an identity provider is configured, ensuring the consent flow always retains at least one usable identity path. Anonymous session access remains unaffected and is still governed by `EnforceAuthOnInference`. ## Changes - Added `DisableVKIdentity bool` field to `OAuth2ServerConfig` with the constraint that it is only honored when an identity provider is configured and `mcp_server_auth_mode` is `oauth`. - `availableModes()` in the consent handler now conditionally excludes `consentFlowModeVK` when `DisableVKIdentity` is set and user mode is available. - Token refresh in the issuance handler rejects VK-mode grants with `invalid_grant` when `DisableVKIdentity` is active and user mode is available, causing existing VK sessions to expire within one access-token TTL. - `OAuth2IssuanceHandler` now accepts an `OAuth2IdentityResolver` so it can apply the same user-mode availability gate as the consent handler. - `OAuth2IssuanceHandler` is promoted to a named field on `BifrostHTTPServer` (matching the existing pattern for `OAuth2ConsentHandler`) so it can be injected with a resolver. - Config update endpoint validates that `disable_vk_identity` is only set when `mcp_server_auth_mode` is `oauth`, returning a `400` otherwise. - JSON schema updated with the new `disable_vk_identity` boolean field. - UI exposes a "Require identity-provider login" toggle in the MCP settings view, visible only in `oauth` mode when an IdP is configured (enterprise-only, gated via SCIM provider check). A warning alert is shown when the toggle is enabled, explaining that existing VK OAuth sessions will lose access within one access-token lifetime. - `disable_vk_identity` added to the `CoreConfig` TypeScript interface and to the dirty-state comparison in the MCP settings view. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [x] Core (Go) - [x] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test ```sh # Core/Transports go test ./transports/bifrost-http/handlers/... ``` 1. Configure an identity provider and set `mcp_server_auth_mode` to `oauth`. 2. Enable `disable_vk_identity` via the API or UI toggle. 3. Attempt to initiate an OAuth consent flow — verify the virtual-key option is absent from the consent page. 4. Attempt to refresh an existing VK-mode token — verify the response is `400 invalid_grant` with the message "virtual-key identity is no longer accepted; re-authenticate". 5. Verify that setting `disable_vk_identity` without an identity provider configured results in the flag being silently ignored (VK remains available). 6. Verify that setting `disable_vk_identity` when `mcp_server_auth_mode` is not `oauth` returns `400 disable_vk_identity is only valid when mcp_server_auth_mode is oauth`. ## Breaking changes - [x] Yes - [ ] No Enabling `disable_vk_identity` causes existing MCP clients authenticated via virtual-key OAuth grants to lose access within one access-token TTL. They must re-authenticate through the configured identity provider. The flag is opt-in and off by default, so no existing deployments are affected unless explicitly enabled. ## Security considerations This feature is intended to enforce identity-provider authentication for MCP OAuth flows, preventing virtual keys from being used as an OAuth identity mechanism. The guard that requires user mode to be available before the flag takes effect ensures the consent flow can never be left with zero usable identity options. The refresh cutoff uses the same availability gate as the consent handler, so the two surfaces remain consistent. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [x] I added/updated tests where appropriate - [ ] I updated documentation where needed - [x] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…Auth consent flow (maximhq#4751) ## Summary Adds a `disable_vk_identity` configuration option that removes virtual-key identity from the OAuth consent flow. When enabled, virtual keys are no longer offered or accepted during OAuth consent, and existing virtual-key grants stop refreshing (they expire within one access-token TTL). The flag is only honored when an identity provider is configured, ensuring the consent flow always retains at least one usable identity path. Anonymous session access remains unaffected and is still governed by `EnforceAuthOnInference`. ## Changes - Added `DisableVKIdentity bool` field to `OAuth2ServerConfig` with the constraint that it is only honored when an identity provider is configured and `mcp_server_auth_mode` is `oauth`. - `availableModes()` in the consent handler now conditionally excludes `consentFlowModeVK` when `DisableVKIdentity` is set and user mode is available. - Token refresh in the issuance handler rejects VK-mode grants with `invalid_grant` when `DisableVKIdentity` is active and user mode is available, causing existing VK sessions to expire within one access-token TTL. - `OAuth2IssuanceHandler` now accepts an `OAuth2IdentityResolver` so it can apply the same user-mode availability gate as the consent handler. - `OAuth2IssuanceHandler` is promoted to a named field on `BifrostHTTPServer` (matching the existing pattern for `OAuth2ConsentHandler`) so it can be injected with a resolver. - Config update endpoint validates that `disable_vk_identity` is only set when `mcp_server_auth_mode` is `oauth`, returning a `400` otherwise. - JSON schema updated with the new `disable_vk_identity` boolean field. - UI exposes a "Require identity-provider login" toggle in the MCP settings view, visible only in `oauth` mode when an IdP is configured (enterprise-only, gated via SCIM provider check). A warning alert is shown when the toggle is enabled, explaining that existing VK OAuth sessions will lose access within one access-token lifetime. - `disable_vk_identity` added to the `CoreConfig` TypeScript interface and to the dirty-state comparison in the MCP settings view. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [x] Core (Go) - [x] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test ```sh # Core/Transports go test ./transports/bifrost-http/handlers/... ``` 1. Configure an identity provider and set `mcp_server_auth_mode` to `oauth`. 2. Enable `disable_vk_identity` via the API or UI toggle. 3. Attempt to initiate an OAuth consent flow — verify the virtual-key option is absent from the consent page. 4. Attempt to refresh an existing VK-mode token — verify the response is `400 invalid_grant` with the message "virtual-key identity is no longer accepted; re-authenticate". 5. Verify that setting `disable_vk_identity` without an identity provider configured results in the flag being silently ignored (VK remains available). 6. Verify that setting `disable_vk_identity` when `mcp_server_auth_mode` is not `oauth` returns `400 disable_vk_identity is only valid when mcp_server_auth_mode is oauth`. ## Breaking changes - [x] Yes - [ ] No Enabling `disable_vk_identity` causes existing MCP clients authenticated via virtual-key OAuth grants to lose access within one access-token TTL. They must re-authenticate through the configured identity provider. The flag is opt-in and off by default, so no existing deployments are affected unless explicitly enabled. ## Security considerations This feature is intended to enforce identity-provider authentication for MCP OAuth flows, preventing virtual keys from being used as an OAuth identity mechanism. The guard that requires user mode to be available before the flag takes effect ensures the consent flow can never be left with zero usable identity options. The refresh cutoff uses the same availability gate as the consent handler, so the two surfaces remain consistent. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [x] I added/updated tests where appropriate - [ ] I updated documentation where needed - [x] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable

Summary
Adds a
disable_vk_identityconfiguration option that removes virtual-key identity from the OAuth consent flow. When enabled, virtual keys are no longer offered or accepted during OAuth consent, and existing virtual-key grants stop refreshing (they expire within one access-token TTL). The flag is only honored when an identity provider is configured, ensuring the consent flow always retains at least one usable identity path. Anonymous session access remains unaffected and is still governed byEnforceAuthOnInference.Changes
DisableVKIdentity boolfield toOAuth2ServerConfigwith the constraint that it is only honored when an identity provider is configured andmcp_server_auth_modeisoauth.availableModes()in the consent handler now conditionally excludesconsentFlowModeVKwhenDisableVKIdentityis set and user mode is available.invalid_grantwhenDisableVKIdentityis active and user mode is available, causing existing VK sessions to expire within one access-token TTL.OAuth2IssuanceHandlernow accepts anOAuth2IdentityResolverso it can apply the same user-mode availability gate as the consent handler.OAuth2IssuanceHandleris promoted to a named field onBifrostHTTPServer(matching the existing pattern forOAuth2ConsentHandler) so it can be injected with a resolver.disable_vk_identityis only set whenmcp_server_auth_modeisoauth, returning a400otherwise.disable_vk_identityboolean field.oauthmode when an IdP is configured (enterprise-only, gated via SCIM provider check). A warning alert is shown when the toggle is enabled, explaining that existing VK OAuth sessions will lose access within one access-token lifetime.disable_vk_identityadded to theCoreConfigTypeScript interface and to the dirty-state comparison in the MCP settings view.Type of change
Affected areas
How to test
mcp_server_auth_modetooauth.disable_vk_identityvia the API or UI toggle.400 invalid_grantwith the message "virtual-key identity is no longer accepted; re-authenticate".disable_vk_identitywithout an identity provider configured results in the flag being silently ignored (VK remains available).disable_vk_identitywhenmcp_server_auth_modeis notoauthreturns400 disable_vk_identity is only valid when mcp_server_auth_mode is oauth.Breaking changes
Enabling
disable_vk_identitycauses existing MCP clients authenticated via virtual-key OAuth grants to lose access within one access-token TTL. They must re-authenticate through the configured identity provider. The flag is opt-in and off by default, so no existing deployments are affected unless explicitly enabled.Security considerations
This feature is intended to enforce identity-provider authentication for MCP OAuth flows, preventing virtual keys from being used as an OAuth identity mechanism. The guard that requires user mode to be available before the flag takes effect ensures the consent flow can never be left with zero usable identity options. The refresh cutoff uses the same availability gate as the consent handler, so the two surfaces remain consistent.
Checklist
docs/contributing/README.mdand followed the guidelines