ui: add OAuth Grants page and identity exact-match filter for MCP sessions - #4511
Conversation
|
|
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 30 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 (16)
📝 WalkthroughWalkthroughAdds exact-match ChangesMCP Sessions identity filter
OAuth Grants management
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
ui/lib/store/apis/oauth2SessionsApi.ts (1)
25-28: ⚡ Quick winPrefer deterministic cache patch for revoke to avoid stale grants rows.
For this delete-by-id mutation, patching
getOAuth2GrantsinonQueryStartedis safer than full invalidation in this codebase’s clustered setup.♻️ Suggested change
revokeOAuth2Grant: builder.mutation<void, string>({ query: (id) => ({ url: `/oauth2/sessions/${id}`, method: "DELETE" }), - invalidatesTags: ["OAuth2Grants"], + async onQueryStarted(id, { dispatch, queryFulfilled }) { + const patch = dispatch( + oauth2SessionsApi.util.updateQueryData("getOAuth2Grants", undefined, (draft) => { + draft.sessions = draft.sessions.filter((s) => s.id !== id); + }), + ); + try { + await queryFulfilled; + } catch { + patch.undo(); + } + }, }),Based on learnings: “In
ui/lib/store/apis/, optimistically patch the cache withonQueryStarted + updateQueryDatafor deterministic mutations like deleting a known row.”🤖 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 `@ui/lib/store/apis/oauth2SessionsApi.ts` around lines 25 - 28, The revokeOAuth2Grant mutation currently uses invalidatesTags to fully invalidate the OAuth2Grants cache, which can cause stale rows in a clustered setup. Replace the invalidatesTags approach with an onQueryStarted handler that uses updateQueryData to patch the getOAuth2Grants query cache. The handler should optimistically remove the revoked grant with the matching ID from the cached grants list, ensuring only the specific deleted grant is removed rather than invalidating the entire cache, making the mutation deterministic and cache-safe.Source: Learnings
🤖 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 `@ui/app/workspace/mcp-sessions/page.tsx`:
- Line 35: Normalize the identity value before using it in the query and
active-filter checks to handle whitespace-only values consistently with the
backend. At line 35 where identity is assigned from urlState.identity and at
line 69 where it's used in the active-filter check, apply trimming to the
identity string and convert empty or whitespace-only values to undefined. This
ensures that values like identity=%20 don't create inconsistent UI state and
unnecessary cache fragmentation between the UI and backend behavior.
In `@ui/app/workspace/oauth-grants/page.tsx`:
- Around line 108-126: The AlertDialog component in the revoke confirmation
dialog is missing data-testid attributes on its interactive controls for E2E
testing. Add data-testid attributes to the AlertDialogCancel (Cancel button) and
AlertDialogAction (Revoke button) elements within the AlertDialogFooter to
ensure they are properly selectable in E2E tests, following the repository's
testing convention.
- Around line 305-317: The AccessTokenExpiry function does not validate that the
timestamp from row.created_at is valid before using it in calculations. When new
Date(row.created_at).getTime() receives an invalid date string, it returns NaN
instead of throwing an error, which causes the function to render "in NaN min".
Add a Number.isFinite() guard check immediately after calculating createdMs to
validate it is a valid number, and return a fallback span with an appropriate
message (such as "Unknown expiry") if the timestamp is invalid. This same
validation pattern should also be applied to other similar timestamp
calculations referenced in the "Also applies to" comment at lines 401-414.
- Around line 60-276: The OAuthGrantsPage component contains excessive UI logic
and rendering that should be extracted into view components according to project
conventions. Move the filter bar section (search input, ComboboxSelect, clear
filters button) into a separate view component, extract the table rendering
logic with its header and body rows into another view component, and separate
the AlertDialog confirmation logic into its own component. Keep the
OAuthGrantsPage function focused on state management and composition, delegating
rendering to these view components. Create these new components in a views/
subdirectory alongside page.tsx.
---
Nitpick comments:
In `@ui/lib/store/apis/oauth2SessionsApi.ts`:
- Around line 25-28: The revokeOAuth2Grant mutation currently uses
invalidatesTags to fully invalidate the OAuth2Grants cache, which can cause
stale rows in a clustered setup. Replace the invalidatesTags approach with an
onQueryStarted handler that uses updateQueryData to patch the getOAuth2Grants
query cache. The handler should optimistically remove the revoked grant with the
matching ID from the cached grants list, ensuring only the specific deleted
grant is removed rather than invalidating the entire cache, making the mutation
deterministic and cache-safe.
🪄 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: 41aea2ef-4014-4abc-bd40-7165db2edfda
📒 Files selected for processing (12)
framework/configstore/rdb.goframework/configstore/store.gotransports/bifrost-http/handlers/mcp_sessions.goui/app/workspace/mcp-sessions/page.tsxui/app/workspace/oauth-grants/layout.tsxui/app/workspace/oauth-grants/page.tsxui/components/sidebar.tsxui/lib/store/apis/baseApi.tsui/lib/store/apis/index.tsui/lib/store/apis/mcpSessionsApi.tsui/lib/store/apis/oauth2SessionsApi.tsui/lib/types/mcpSessions.ts
Confidence Score: 5/5Safe to merge — the SQL parenthesization fix is correct, the offset snap-back logic handles all edge cases, and the new UI components follow existing patterns with full data-testid coverage. The Go backend changes are narrow and correct: the identity filter uses explicit parentheses in the raw SQL string, the parameterized bindings prevent injection, and the change is additive with no regressions to existing filters. The React page correctly handles loading, error, empty, and paginated states; the offset useEffect snaps the page back when totalCount shrinks after a revoke; the revoke flow closes the dialog immediately and surfaces errors as toasts. No browser crypto APIs, no data-testid removals, and no auth/authz regressions were found. No files require special attention. The two comments are minor style nits (unused import, redundant type guard) with no behavioral impact. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User navigates to OAuth Grants page] --> B[useGetOAuth2GrantsQuery\nGET /oauth2/sessions — all grants]
B --> C{Response}
C -->|isLoading| D[Spinner]
C -->|isError| E[Error message]
C -->|data| F[Client-side filter\nsearch + bf_mode]
F --> G[Client-side pagination\nPAGE_SIZE = 50]
G --> H[GrantsTable renders current page slice]
H --> I{Row action}
I -->|View auth sessions| J[Navigate to MCP Sessions\n?auth_mode=bf_mode&identity=bf_sub]
J --> K[GET /mcp/sessions\nwith identity exact-match filter\nAND auth_mode filter]
I -->|Revoke| L[RevokeGrantDialog\nconfirmation]
L -->|Confirm| M[DELETE /oauth2/sessions/:id\nrevokeOAuth2Grant mutation]
M -->|success| N[Invalidate OAuth2Grants tag\nRe-fetch grants list]
M -->|error| O[Toast error]
N --> F
P[useEffect: offset snap] -->|totalCount shrinks| G
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[User navigates to OAuth Grants page] --> B[useGetOAuth2GrantsQuery\nGET /oauth2/sessions — all grants]
B --> C{Response}
C -->|isLoading| D[Spinner]
C -->|isError| E[Error message]
C -->|data| F[Client-side filter\nsearch + bf_mode]
F --> G[Client-side pagination\nPAGE_SIZE = 50]
G --> H[GrantsTable renders current page slice]
H --> I{Row action}
I -->|View auth sessions| J[Navigate to MCP Sessions\n?auth_mode=bf_mode&identity=bf_sub]
J --> K[GET /mcp/sessions\nwith identity exact-match filter\nAND auth_mode filter]
I -->|Revoke| L[RevokeGrantDialog\nconfirmation]
L -->|Confirm| M[DELETE /oauth2/sessions/:id\nrevokeOAuth2Grant mutation]
M -->|success| N[Invalidate OAuth2Grants tag\nRe-fetch grants list]
M -->|error| O[Toast error]
N --> F
P[useEffect: offset snap] -->|totalCount shrinks| G
Reviews (25): Last reviewed commit: "feat: adds mcp oauth grants ui" | Re-trigger Greptile |
identity exact-match filter for MCP sessionsidentity exact-match filter for MCP sessions
ffd24d4 to
9424fab
Compare
e5a9a8f to
47cce08
Compare
9424fab to
41e5b36
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 `@ui/app/workspace/oauth-grants/page.tsx`:
- Around line 33-35: The pagination offset can become invalid when the filtered
results shrink after actions like revoking items. On line 34 where
filtered.slice is called with offset, the offset variable needs to be clamped to
ensure it doesn't exceed the bounds of the new filtered array. Before calling
slice with offset and offset + PAGE_SIZE, calculate the maximum valid offset
using Math.max(0, Math.floor((totalCount - 1) / PAGE_SIZE)) or similar logic,
then use the smaller of the current offset and this maximum value to ensure
pagination stays within valid bounds when the filtered count decreases.
In `@ui/app/workspace/oauth-grants/views/grantActions.tsx`:
- Around line 40-47: The conditional check on the DropdownMenuItem gating the
View auth sessions link currently only includes user and vk modes, excluding
session-based grants. Extend the bf_mode condition to also include the "session"
mode so that session-bound grants can navigate to auth sessions, aligning with
the identity filter contract that supports exact matching on session_id just as
it does for user_id and virtual_key_id.
🪄 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: 92a7db2e-849e-43c1-8365-68106e57eb5f
📒 Files selected for processing (16)
framework/configstore/rdb.goframework/configstore/store.gotransports/bifrost-http/handlers/mcp_sessions.goui/app/workspace/mcp-sessions/page.tsxui/app/workspace/oauth-grants/layout.tsxui/app/workspace/oauth-grants/page.tsxui/app/workspace/oauth-grants/views/grantActions.tsxui/app/workspace/oauth-grants/views/grantsFilterBar.tsxui/app/workspace/oauth-grants/views/grantsTable.tsxui/app/workspace/oauth-grants/views/revokeGrantDialog.tsxui/components/sidebar.tsxui/lib/store/apis/baseApi.tsui/lib/store/apis/index.tsui/lib/store/apis/mcpSessionsApi.tsui/lib/store/apis/oauth2SessionsApi.tsui/lib/types/mcpSessions.ts
✅ Files skipped from review due to trivial changes (3)
- ui/app/workspace/oauth-grants/layout.tsx
- ui/lib/store/apis/index.ts
- ui/lib/store/apis/baseApi.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- ui/components/sidebar.tsx
- ui/lib/store/apis/mcpSessionsApi.ts
- framework/configstore/rdb.go
- transports/bifrost-http/handlers/mcp_sessions.go
- ui/lib/store/apis/oauth2SessionsApi.ts
- ui/app/workspace/mcp-sessions/page.tsx
41e5b36 to
d30ef75
Compare
47cce08 to
577e9c3
Compare
577e9c3 to
87046c1
Compare
d30ef75 to
15499ee
Compare
87046c1 to
c6c30c4
Compare
15499ee to
8bff02e
Compare
da29389 to
bcdf0a4
Compare
a4a55d2 to
e143956
Compare
bcdf0a4 to
91ef58c
Compare
e143956 to
8a77f80
Compare
91ef58c to
90b5a4b
Compare
8a77f80 to
110d3b7
Compare
90b5a4b to
ce55915
Compare
110d3b7 to
110c0aa
Compare
ce55915 to
520b193
Compare
110c0aa to
1736ff8
Compare
Merge activity
|
The base branch was changed.
1736ff8 to
c5fd042
Compare
…essions (#4511) ## Summary Adds an **OAuth Grants** management page to the UI and introduces an `identity` exact-match filter for MCP sessions. Together these allow operators to view all active downstream OAuth grants issued to MCP clients and drill through from a grant directly to the auth sessions belonging to that specific identity. ## Changes - Added `Identity` field to `MCPSessionsFilterParams` in the config store, which exact-matches against `user_id`, `virtual_key_id`, or `session_id` columns (ANDed with any other active filters). - Exposed the `identity` query parameter in the HTTP handler so callers can pass it via the API. - Added `identity` to the MCP sessions URL state and query params in the UI, included it in the "has active filters" check, and wired it into `handleClearFilters`. - Created `oauth2SessionsApi.ts` with `getOAuth2Grants` and `revokeOAuth2Grant` endpoints, registered the `OAuth2Grants` cache tag in `baseApi`, and exported the new API from the store index. - Built the `OAuthGrantsPage` component with client-side search and mode filtering, a paginated table showing client name, bound identity (user/virtual key/anonymous session), access token expiry, created time, and last used time, and per-row actions to revoke a grant or navigate to MCP sessions pre-filtered to that identity via `auth_mode` + `identity` query params. - Added the OAuth Grants route and sidebar entry under the MCP Gateway section. The `identity` filter is intentionally an exact match (not a substring) so that linking from a grant to its sessions produces a precise, unambiguous result rather than a fuzzy hit list. ## 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 1. Start the gateway with at least one MCP client connected via the OAuth consent flow. 2. Navigate to **OAuth Grants** in the sidebar — the table should list active grants with client name, bound identity, expiry, and timestamps. 3. Use the search box and identity-mode filter to narrow results; verify the Clear filters button resets both. 4. Open the row actions menu on a user or virtual-key grant and click **View auth sessions** — confirm the MCP Sessions page opens filtered to that exact identity and auth mode. 5. Click **Revoke** on a grant, confirm the dialog, and verify the grant disappears from the list and a success toast appears. 6. On the MCP Sessions page, manually append `&identity=<some-id>` to the URL and confirm only sessions matching that exact identity are returned. ```sh go test ./framework/configstore/... cd ui pnpm i pnpm build ``` ## Screenshots/Recordings _Add before/after screenshots of the OAuth Grants page and the MCP Sessions identity filter._ ## Breaking changes - [ ] Yes - [x] No ## Related issues _Link related issues here._ ## Security considerations Revocation stops refresh token rotation immediately; the current short-lived JWT access token (≤10 min TTL) remains valid until it expires naturally. This is documented in the revocation confirmation dialog so operators understand the brief window before full cutoff. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…essions (maximhq#4511) ## Summary Adds an **OAuth Grants** management page to the UI and introduces an `identity` exact-match filter for MCP sessions. Together these allow operators to view all active downstream OAuth grants issued to MCP clients and drill through from a grant directly to the auth sessions belonging to that specific identity. ## Changes - Added `Identity` field to `MCPSessionsFilterParams` in the config store, which exact-matches against `user_id`, `virtual_key_id`, or `session_id` columns (ANDed with any other active filters). - Exposed the `identity` query parameter in the HTTP handler so callers can pass it via the API. - Added `identity` to the MCP sessions URL state and query params in the UI, included it in the "has active filters" check, and wired it into `handleClearFilters`. - Created `oauth2SessionsApi.ts` with `getOAuth2Grants` and `revokeOAuth2Grant` endpoints, registered the `OAuth2Grants` cache tag in `baseApi`, and exported the new API from the store index. - Built the `OAuthGrantsPage` component with client-side search and mode filtering, a paginated table showing client name, bound identity (user/virtual key/anonymous session), access token expiry, created time, and last used time, and per-row actions to revoke a grant or navigate to MCP sessions pre-filtered to that identity via `auth_mode` + `identity` query params. - Added the OAuth Grants route and sidebar entry under the MCP Gateway section. The `identity` filter is intentionally an exact match (not a substring) so that linking from a grant to its sessions produces a precise, unambiguous result rather than a fuzzy hit list. ## 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 1. Start the gateway with at least one MCP client connected via the OAuth consent flow. 2. Navigate to **OAuth Grants** in the sidebar — the table should list active grants with client name, bound identity, expiry, and timestamps. 3. Use the search box and identity-mode filter to narrow results; verify the Clear filters button resets both. 4. Open the row actions menu on a user or virtual-key grant and click **View auth sessions** — confirm the MCP Sessions page opens filtered to that exact identity and auth mode. 5. Click **Revoke** on a grant, confirm the dialog, and verify the grant disappears from the list and a success toast appears. 6. On the MCP Sessions page, manually append `&identity=<some-id>` to the URL and confirm only sessions matching that exact identity are returned. ```sh go test ./framework/configstore/... cd ui pnpm i pnpm build ``` ## Screenshots/Recordings _Add before/after screenshots of the OAuth Grants page and the MCP Sessions identity filter._ ## Breaking changes - [ ] Yes - [x] No ## Related issues _Link related issues here._ ## Security considerations Revocation stops refresh token rotation immediately; the current short-lived JWT access token (≤10 min TTL) remains valid until it expires naturally. This is documented in the revocation confirmation dialog so operators understand the brief window before full cutoff. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…essions (maximhq#4511) ## Summary Adds an **OAuth Grants** management page to the UI and introduces an `identity` exact-match filter for MCP sessions. Together these allow operators to view all active downstream OAuth grants issued to MCP clients and drill through from a grant directly to the auth sessions belonging to that specific identity. ## Changes - Added `Identity` field to `MCPSessionsFilterParams` in the config store, which exact-matches against `user_id`, `virtual_key_id`, or `session_id` columns (ANDed with any other active filters). - Exposed the `identity` query parameter in the HTTP handler so callers can pass it via the API. - Added `identity` to the MCP sessions URL state and query params in the UI, included it in the "has active filters" check, and wired it into `handleClearFilters`. - Created `oauth2SessionsApi.ts` with `getOAuth2Grants` and `revokeOAuth2Grant` endpoints, registered the `OAuth2Grants` cache tag in `baseApi`, and exported the new API from the store index. - Built the `OAuthGrantsPage` component with client-side search and mode filtering, a paginated table showing client name, bound identity (user/virtual key/anonymous session), access token expiry, created time, and last used time, and per-row actions to revoke a grant or navigate to MCP sessions pre-filtered to that identity via `auth_mode` + `identity` query params. - Added the OAuth Grants route and sidebar entry under the MCP Gateway section. The `identity` filter is intentionally an exact match (not a substring) so that linking from a grant to its sessions produces a precise, unambiguous result rather than a fuzzy hit list. ## 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 1. Start the gateway with at least one MCP client connected via the OAuth consent flow. 2. Navigate to **OAuth Grants** in the sidebar — the table should list active grants with client name, bound identity, expiry, and timestamps. 3. Use the search box and identity-mode filter to narrow results; verify the Clear filters button resets both. 4. Open the row actions menu on a user or virtual-key grant and click **View auth sessions** — confirm the MCP Sessions page opens filtered to that exact identity and auth mode. 5. Click **Revoke** on a grant, confirm the dialog, and verify the grant disappears from the list and a success toast appears. 6. On the MCP Sessions page, manually append `&identity=<some-id>` to the URL and confirm only sessions matching that exact identity are returned. ```sh go test ./framework/configstore/... cd ui pnpm i pnpm build ``` ## Screenshots/Recordings _Add before/after screenshots of the OAuth Grants page and the MCP Sessions identity filter._ ## Breaking changes - [ ] Yes - [x] No ## Related issues _Link related issues here._ ## Security considerations Revocation stops refresh token rotation immediately; the current short-lived JWT access token (≤10 min TTL) remains valid until it expires naturally. This is documented in the revocation confirmation dialog so operators understand the brief window before full cutoff. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable

Summary
Adds an OAuth Grants management page to the UI and introduces an
identityexact-match filter for MCP sessions. Together these allow operators to view all active downstream OAuth grants issued to MCP clients and drill through from a grant directly to the auth sessions belonging to that specific identity.Changes
Identityfield toMCPSessionsFilterParamsin the config store, which exact-matches againstuser_id,virtual_key_id, orsession_idcolumns (ANDed with any other active filters).identityquery parameter in the HTTP handler so callers can pass it via the API.identityto the MCP sessions URL state and query params in the UI, included it in the "has active filters" check, and wired it intohandleClearFilters.oauth2SessionsApi.tswithgetOAuth2GrantsandrevokeOAuth2Grantendpoints, registered theOAuth2Grantscache tag inbaseApi, and exported the new API from the store index.OAuthGrantsPagecomponent with client-side search and mode filtering, a paginated table showing client name, bound identity (user/virtual key/anonymous session), access token expiry, created time, and last used time, and per-row actions to revoke a grant or navigate to MCP sessions pre-filtered to that identity viaauth_mode+identityquery params.The
identityfilter is intentionally an exact match (not a substring) so that linking from a grant to its sessions produces a precise, unambiguous result rather than a fuzzy hit list.Type of change
Affected areas
How to test
&identity=<some-id>to the URL and confirm only sessions matching that exact identity are returned.Screenshots/Recordings
Add before/after screenshots of the OAuth Grants page and the MCP Sessions identity filter.
Breaking changes
Related issues
Link related issues here.
Security considerations
Revocation stops refresh token rotation immediately; the current short-lived JWT access token (≤10 min TTL) remains valid until it expires naturally. This is documented in the revocation confirmation dialog so operators understand the brief window before full cutoff.
Checklist
docs/contributing/README.mdand followed the guidelines