Skip to content

Gate AI Workspace actions on scopes, and align scope matching with the API - #3127

Merged
Thushani-Jayasekera merged 4 commits into
wso2:mainfrom
Thushani-Jayasekera:fallback-remove
Aug 4, 2026
Merged

Gate AI Workspace actions on scopes, and align scope matching with the API#3127
Thushani-Jayasekera merged 4 commits into
wso2:mainfrom
Thushani-Jayasekera:fallback-remove

Conversation

@Thushani-Jayasekera

@Thushani-Jayasekera Thushani-Jayasekera commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

$subject

Problem

A user holding ap:llm_proxy:manage found the Create Proxy button disabled, while Add Provider stayed enabled for a role not meant to administer providers. Investigating both turned up four separate defects.

1. Most action buttons had no permission check at all. The LLM-proxy create buttons, all application create/delete affordances, provider templates, MCP proxies, projects, gateway row actions, guardrail and model-catalog editors, and API-key actions rendered fully enabled regardless of scope. The disabled Create Proxy button was not a permission decision — LLMProxyNew.tsx had no scope logic at all, and the button was blocked by unmet form state (an unfulfilled provider API key) with no explanation shown.

2. Two buttons that looked gated were not. ProvidersList and LLMProxiesList computed disabled from a quota flag hardcoded to false, so the scope check only controlled rendering. Whenever those buttons appeared they were clickable.

3. Frontend scope matching disagreed with the API. checkPermission derived a parent :manage from only the first two segments of the requested scope, so ap:llm_provider:api_key:manage failed to satisfy ap:llm_provider:api_key:read — a holder of the sub-resource grant was wrongly denied in the UI.

4. Disabled link-buttons did not look disabled. A Button rendered as component={RouterLink} is an <a>, not a <button>. The click is blocked, but the anchor does not pick up the theme's disabled colouring, so the control appeared fully enabled while doing nothing — reading as a broken button rather than a permission boundary. ProvidersList and LLMProxiesList already hand-rolled an opacity override for exactly this reason.

Changes

Scope matching (src/auth/permissions.ts)

checkPermission now resolves in the same order the API authorizes a request — exact match → own-level :* wildcard → own-level :manage → each broader ancestor's :manage. The ancestor rule is correct because sub-resource operations list the parent explicitly in their own security block: ap:llm_provider:manage appears in the accepted set of every /llm-providers/{id}/api-keys and /deployments operation.

Scopes ending :all:manage are excluded from derivation. ap:api_key:all:manage is an ownership override — it widens whose rows are reachable, not which actions — so ap:api_key:manage must not confer it, matching canManageAPIKey in platform-api/internal/service and the one operation (/me/api-keys) whose accepted list omits a parent :manage.

Two shared constants were added: NO_PERMISSION_TOOLTIP, which deliberately does not name the missing scope so the tooltip cannot be used to probe the authorization model, and DISABLED_ACTION_SX, which supplies the disabled styling anchors don't inherit.

UI gating

Create, update and delete affordances across LLM proxies, providers, applications, MCP proxies, projects, provider templates, gateways, guardrails, the model catalog and API keys are now disabled with an explanatory tooltip, rather than hidden or silently inert. Create pages for LLM proxies, applications and MCP proxies gained route-level guards mirroring the existing one in ServiceProviderNew.tsx.

Where a tab already had a gateway-managed read-only gate (guardrails, models), the permission was folded into that existing flag rather than added as a parallel mechanism, so one definition change covers every control it already guarded — and the tooltip switches to the permission message when that is the cause rather than mislabelling it "gateway-managed".

The Create Proxy submit button now names its actual blocker ("Select an LLM provider", "This provider requires an API key…") instead of disabling itself with no signal — the behaviour that made a form-state problem look like a permissions problem.

Detail-page header actions are gated alongside their list-table equivalents. ViewGateway and LLMProxyOverview each carried an Edit control that the corresponding row action in GatewaysTable/ProxiesList already gated, so the same operation was reachable or not depending on which screen you opened it from. LLMProxyOverview's sticky Save is gated on ap:llm_proxy:update as well, with handleSaveChanges returning before updateProxy — the button is not the only entry point to it.

Where two tooltips could fire on one control, the permission message takes precedence. The resource-level Add buttons on both guardrails tabs were wrapped in a DisabledActionTooltip that fell through to its "gateway-managed" default, so a permission block was mislabelled; the provider models tab nested a DisabledActionTooltip inside a Tooltip, letting the missing-permission and single-provider-limit messages render together. Both now resolve to one title, permission first.

Reads that would 403 are no longer attempted

Gating write actions is not sufficient on its own: a surface whose read is denied fails just as visibly. The gateway Policies tab loaded the gateway manifest and the org's custom policies on mount, so a caller without ap:gateway:manifest:read and ap:gateway_custom_policy:read got a 403 and a "Failed to load gateway policies" error that looked like an outage rather than a permission boundary. GatewayPoliciesProvider now skips the request entirely when either scope is missing, and the tab renders a permission notice instead. The per-row Sync action is separately gated on ap:gateway_custom_policy:create, since viewing the manifest and syncing a policy into the organization are different grants.

Role-to-scope mapping (committed separately)

With ancestor matching in place, sub-resource scopes listed alongside a parent :manage became redundant. 25 such entries were removed across the five roles, and the convention block now documents that a resource :manage covers its sub-resources and that :all:manage is neither implied by nor implies the plain :manage. The Helm chart's inlined ap_admin is now identical to the canonical role's ap: scopes.

Documentation links

Nine AI Workspace doc links pointed at the retired wso2.com/bijira/docs/ base (one was on api-platform but missing the /next/ segment). All now point at https://wso2.com/api-platform/docs/next/ai-workspace/…, verified against the live site — the section exists and its structure matches ours one-for-one.

Behaviour changes

Every role's effective access is unchanged except ap_publisher, which was deliberately narrowed:

Role Change
ap_admin, ap_operator, ap_subscriber, ap_viewer Redundant scopes removed; reachable operations identical
ap_publisher ap:llm_provider:manageap:llm_provider:read; ap:llm_provider:deployment:manage removed

Publishers can no longer create, edit, delete or deploy LLM providers — provider administration is now an admin task. They retain ap:llm_proxy:manage (which covers proxy API keys and deployments), so pointing a proxy at an existing provider and deploying it still works.

Three consequences to be aware of:

  • Publishers lose read access to provider deployments as well, not just write — six operations in total. ap:llm_provider:read does not reach the sub-resource, because those operations accept the parent :manage, never the parent :read. Add ap:llm_provider:deployment:read if read-only visibility is wanted.
  • Publishers cannot generate a provider API key (ap:llm_provider:api_key:create is admin-only). The Generate API Key button shows disabled with a tooltip; the manual key field on the proxy form remains available.
  • A gateway read-only holder (ap:gateway:read) can list gateways, open one and see live status — the row click and both read endpoints are unaffected — while Edit, Delete and Reconfigure are disabled, and the Policies tab shows a permission notice instead of erroring.

This is a live authorization narrowing — any ap_publisher currently managing LLM providers will receive 403s after a restart, which the mapping file requires to take effect.

Validation

  • Typecheck and build clean. tsc --noEmit reports zero errors in every touched file and npm run build succeeds; the remaining ~30 errors are pre-existing on this branch (missing JSX namespace, absent @types for js-yaml/swagger-ui-react, and unrelated context type errors). No lint run — portals/ai-workspace has no eslint.config.js.
  • Scope matching verified against the spec, not by inspection. The UI's decision was compared against a reimplementation of the API's scopeSatisfies looping over each operation's declared accepted scopes, for all 5 roles × 114 operations: 0 mismatches — no false enables, no false disables.
  • Compaction proven behaviour-preserving. Each role's full reachable operation set was computed before and after and diffed: identical. Redundancy was determined greedily per role — a scope was dropped only if reachability was unchanged given everything still remaining — so no ordering artifact where two scopes each look redundant because of the other.
  • Gating coverage audited mechanically. Every NO_PERMISSION_TOOLTIP site was checked for a paired disabled control, and separately for the subtler case where the tooltip condition and the disabled expression use different flags. Zero unpaired sites; a brace-aware JSX scan confirms no gated link-button is left without disabled styling. Review follow-up caught the inverse of that case — a control correctly disabled but carrying a tooltip that named the wrong reason — which the scan did not look for; those are fixed above.
  • The one action still not scope-checked was verified to be inert. ModelPill's remove icon takes removeDisabled={isSaving || isReadOnlyProvider} and re-checks the flag inside onRemove, so the missing ap:llm_provider:update check is a tooltip gap, not a reachable path.
  • 47 of 48 sub-resource operations in openapi.yaml accept the parent :manage, confirming the ancestor rule models the API correctly.

Notable fixes found while verifying

  • Gateway token rotation was gated too narrowly. Reconfigure runs three operations in sequence (list tokens → revoke each → rotate), but the gate checked only ap:gateway:token:create. A holder of :read + :create without :delete would have minted a new token while revoking nothing, leaving stale tokens live. It now requires all three; ap:gateway:token:manage and ap:gateway:manage satisfy them via the ancestor rule.
  • ServiceProviderModelsTab had isReadOnlyProvider hardcoded false, deliberately, because the model catalog is not part of the runtime artifact. That reasoning holds for read-only artifacts but not for permissions — editing it still writes to the provider — so it is now driven by ap:llm_provider:update, with the original comment preserved and extended.
  • Association-mapped API keys bypassed the API-key scopes entirely. AssociationsTab mapped and unmapped keys through POST/DELETE /applications/{id}/api-keys — the same two endpoints APIKeyTab gates on ap:application:api_key:create/:delete — but the file had no hasPermission call at all, so the association scopes were the only thing standing in front of them. The two grants are distinct: associating a provider with an application is not the same as minting a key against it. Both handlers now return before touching drawer state or the API, the permission is folded into the existing selectionBlockedMessage (which already gates key selection inside both association drawers), and the key payload is dropped from the add-association flows so associating still works without the key grant.
  • The gateway Policies tab fired a guaranteed-403 read for anyone without the manifest and custom-policy read scopes, surfacing as a load error. Found by tracing what a ap:gateway:read-only role can actually reach, rather than by testing the button gating alone.

Not covered

No unit tests for the changed matching logic. The portal has only Cypress e2e configured; adding a unit runner is a dependency decision under js-dependency-management.md. This logic is security-relevant and should get tests — worth resolving before or shortly after merge. The spec-driven equivalence checks above were run manually and are not committed as regression tests.

Eight files still lack scope checks, all deliberately: sub-components of an already-gated form (PolicyParameterEditor/*, GuardrailsSection, TemplateVersionDialog, ProviderTemplateFormFields, PolicyMapper), a display-only tab (LLMProxyOverviewTab), and pre-auth onboarding (OrgProvisioningPage, which runs before a user has scopes). AssociationsTab was on this list as "dialog confirm buttons whose trigger is gated" — that turned out to be wrong for its API-key actions, see above.

dp: scope redundancy not addressed. Three entries look redundant by the mapping file's documented convention (dp:key_manager:read under dp:key_manager:manage; dp:application_key:revoke under dp:application_key:manage). platform-api only shape-checks dp: scopes — the API Portal enforces them against a spec not verified here, and revoke being separately named suggests it may be an override like :all:manage. Removing them needs the portal's accepted-scope lists checked first.

Four scopes are referenced but declared nowhereap:gateway:artifact:read and ap:organization:subscription:read (in both OIDC scope-request strings) and ap:rest_api:api_key:read, ap:rest_api:publication:read (in permissions.ts). No role grants them and no UI check uses them, but they were left in place: the mapping file notes that scopes may also be declared by compiled-in plugins, exactly as the websub/webbroker entries are.

Five non-docs wso2.com/bijira/* links remain (terms-of-use, privacy-policy in appShellMain.tsx and BasicAuthLoginPage.tsx). These are legal pages, not documentation, and the api-platform equivalents were not verified.

Reviewer notes

  • The branch also carries earlier, unrelated /ai-workspace path-prefix commits. Confirm the intended PR scope before opening.
  • Worth a second opinion on the ap_publisher narrowing, since it changes production authorization.
image image

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR updates role scopes and adds permission-aware behavior across AI Workspace. It centralizes permission tooltip and inheritance logic, gates gateway policies and resource actions, disables unauthorized controls, and updates documentation links.

Changes

Permission enforcement

Layer / File(s) Summary
Permission contracts and policy context
platform-api/resources/role-to-scope-mapping.yaml, portals/ai-workspace/src/auth/permissions.ts, portals/ai-workspace/src/contexts/*
Updates ap_publisher secret access, expands scope inheritance, adds shared disabled-action constants, and exposes gateway policy permission state.
Application and project controls
portals/ai-workspace/src/pages/appShell/appShellPages/applications/*, portals/ai-workspace/src/pages/appShell/appShellPages/projects/*
Adds permission checks, disabled states, localized unavailable messages, and tooltips for application, association, API-key, and project actions.
Gateway and MCP proxy controls
portals/ai-workspace/src/pages/appShell/appShellPages/gateways/*, portals/ai-workspace/src/pages/appShell/appShellPages/externalServers/*
Gates policy viewing, syncing, gateway editing, token rotation, and MCP proxy creation or deletion.
Provider-template controls
portals/ai-workspace/src/pages/appShell/appShellPages/providerTemplate/*
Requires the relevant scopes for template creation, copying, editing, deletion, and version changes.
LLM proxy controls
portals/ai-workspace/src/pages/appShell/appShellPages/proxies/*
Gates proxy creation, deletion, editing, resource import, guardrails, and provider API-key generation.
Service-provider controls and documentation
portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/*, portals/ai-workspace/src/pages/appShell/QuickStartIntroPopup.tsx, portals/ai-workspace/src/pages/appShell/appShellPages/projects/ExploreMoreCard.tsx
Adds provider permission checks and changes AI Workspace documentation links to API Platform paths.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WorkspacePage
  participant AppAuth
  participant PermissionConstants
  participant ProtectedAction
  WorkspacePage->>AppAuth: request hasPermission
  AppAuth->>PermissionConstants: evaluate required scope
  PermissionConstants-->>AppAuth: return permission result
  AppAuth-->>WorkspacePage: return canPerform flag
  WorkspacePage->>ProtectedAction: enable or disable action
Loading

Possibly related PRs

Suggested reviewers: lasanthas, piumal1999, virajsalaka

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main changes: scope-based action gating and frontend/API scope-matching alignment.
Description check ✅ Passed The description is detailed and covers the problem, implementation, behavior changes, documentation, validation, and limitations, despite missing several template headings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Thushani-Jayasekera Thushani-Jayasekera changed the title Implement permission checks and tooltips for application and external server actions in AI Workspace Gate AI Workspace actions on scopes, and align scope matching with the API Aug 4, 2026
… enhancing user feedback with tooltips and alerts in the GatewayPolicies component.
…, changing secret read access to secret management, enhancing role definitions for better access control.
renuka-fernando
renuka-fernando previously approved these changes Aug 4, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderModelsTab.tsx (1)

493-514: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use one permission-aware tooltip for Add Model Provider.

When the update scope is absent and one provider already exists, both DisabledActionTooltip and the inner Tooltip are active. The control can show conflicting permission and single-provider-limit messages.

Compute one title with permission taking precedence and use one tooltip wrapper.

🤖 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
`@portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderModelsTab.tsx`
around lines 493 - 514, Replace the nested DisabledActionTooltip and Tooltip
wrappers around the Button with a single tooltip component. Compute one title
value that checks isReadOnlyProvider first and uses lockedActionTooltip if true,
otherwise checks disableAddProviderButton and shows the FormattedMessage for the
single-provider-limit case, otherwise returns an empty string. This ensures
permission-related messages take precedence and prevents conflicting tooltip
messages from both wrappers appearing simultaneously.
🧹 Nitpick comments (1)
portals/ai-workspace/src/auth/permissions.ts (1)

236-255: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add table-driven tests for checkPermission.

Test exact matches, own-level wildcards, own-level :manage, ancestor :manage, and the ap:api_key:all:manage exception. This logic now controls permission-aware actions across the workspace. The PR currently has no unit tests for these rules.

🤖 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 `@portals/ai-workspace/src/auth/permissions.ts` around lines 236 - 255, Add
table-driven unit tests for checkPermission covering exact scope matches,
own-level wildcard grants, own-level :manage grants, broader ancestor :manage
grants, and the ap:api_key:all:manage exception. Include both granting and
non-granting cases where needed, using representative scopes that verify the
documented wildcard and hierarchy boundaries.
🤖 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
`@portals/ai-workspace/src/pages/appShell/appShellPages/applications/OverviewTabs/AssociationsTable.tsx`:
- Around line 162-166: Update AssociationsTab’s API-key add/remove action guards
to also require SCOPES.APPLICATION_API_KEY_CREATE and
SCOPES.APPLICATION_API_KEY_DELETE, respectively, alongside the association
permissions. Ensure unauthorized actions are blocked before drawer state is
mutated or addAPIKeys/removeAPIKey are called, with UI gating consistent with
APIKeyTab if applicable.

In
`@portals/ai-workspace/src/pages/appShell/appShellPages/gateways/ViewGateway.tsx`:
- Around line 233-241: Update the detail-page edit control near the header
action in ViewGateway so it checks SCOPES.GATEWAY_UPDATE through hasPermission
before allowing navigation. Match the existing table-level edit gating and
feedback behavior, and verify the edit route and gateway update API enforce the
same permission scope.

In
`@portals/ai-workspace/src/pages/appShell/appShellPages/proxies/LLMProxyGuardrailsTab.tsx`:
- Around line 207-212: The resource-level DisabledActionTooltip wrappers do not
receive the permission-specific tooltip when editing is unauthorized. Update the
wrappers around the resource-level actions, including the occurrence near the
existing action rendering and the additional occurrence noted in the comment, to
pass title={lockedActionTooltip} so unauthorized controls display
NO_PERMISSION_TOOLTIP while preserving gateway-managed behavior.

In
`@portals/ai-workspace/src/pages/appShell/appShellPages/proxies/LLMProxyOverview.tsx`:
- Around line 155-156: In LLMProxyOverview, derive canUpdateProxy from
SCOPES.LLM_PROXY_UPDATE alongside canDeleteProxy, disable the overview Edit
button and Save action when it is false, and guard handleSaveChanges so
updateProxy is only called when canUpdateProxy is true.

In
`@portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderDeploymentsCard.tsx`:
- Around line 581-585: Update the delete action tooltip near the disabled
condition in ServiceProviderDeploymentsCard so it displays NO_PERMISSION_TOOLTIP
when key.id exists but canDeleteProviderApiKey is false, instead of the generic
“Delete API key” text. Ensure the permission message takes precedence over the
identifier check while preserving existing behavior for other disabled states.

In
`@portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderGuardrailsTab.tsx`:
- Around line 222-227: Update the resource-level DisabledActionTooltip around
the Add action to pass title={lockedActionTooltip}, matching the global Add
control. Use the existing lockedActionTooltip derived from canEditProvider so
missing LLM_PROVIDER_UPDATE permission displays NO_PERMISSION_TOOLTIP while
gateway-managed resources retain their existing behavior.

In
`@portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderModelsTab.tsx`:
- Around line 162-167: The ModelPill component at lines 665-675 renders a remove
icon regardless of edit permissions, even when isReadOnlyProvider is true.
Update the ModelPill rendering to either conditionally pass the onRemove prop
only when canEditProvider is true, or wrap the remove icon with
DisabledActionTooltip and pass the lockedActionTooltip constant when the user
lacks LLM_PROVIDER_UPDATE permissions. Use the computed isReadOnlyProvider flag
or canEditProvider boolean to determine which approach to apply.

---

Outside diff comments:
In
`@portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderModelsTab.tsx`:
- Around line 493-514: Replace the nested DisabledActionTooltip and Tooltip
wrappers around the Button with a single tooltip component. Compute one title
value that checks isReadOnlyProvider first and uses lockedActionTooltip if true,
otherwise checks disableAddProviderButton and shows the FormattedMessage for the
single-provider-limit case, otherwise returns an empty string. This ensures
permission-related messages take precedence and prevents conflicting tooltip
messages from both wrappers appearing simultaneously.

---

Nitpick comments:
In `@portals/ai-workspace/src/auth/permissions.ts`:
- Around line 236-255: Add table-driven unit tests for checkPermission covering
exact scope matches, own-level wildcard grants, own-level :manage grants,
broader ancestor :manage grants, and the ap:api_key:all:manage exception.
Include both granting and non-granting cases where needed, using representative
scopes that verify the documented wildcard and hierarchy boundaries.
🪄 Autofix

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: 84ed6f45-2144-4510-ad2a-38cdc606ff3b

📥 Commits

Reviewing files that changed from the base of the PR and between 4bca0ae and e85b69b.

📒 Files selected for processing (34)
  • platform-api/resources/role-to-scope-mapping.yaml
  • portals/ai-workspace/src/auth/permissions.ts
  • portals/ai-workspace/src/contexts/GatewayPoliciesContext.tsx
  • portals/ai-workspace/src/contexts/OIDCAppAuthProvider.tsx
  • portals/ai-workspace/src/pages/appShell/QuickStartIntroPopup.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/applications/ApplicationNew.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/applications/ApplicationsList.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/applications/GenAIApplicationsSummaryCardSection.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/applications/OverviewTabs/APIKeyTab.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/applications/OverviewTabs/AssociationsTable.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/externalServers/ExternalServersList.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/externalServers/ExternalServersNew.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/externalServers/MCPProxiesSummaryCardSection.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/gateways/GatewayPolicies.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/gateways/GatewaysTable.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/gateways/ViewGateway.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/projects/AddNewProject.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/projects/ExploreMoreCard.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/projects/ProjectListView.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/providerTemplate/CreateProviderTemplate.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/providerTemplate/CreateProviderTemplateVersion.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/providerTemplate/ProviderTemplateOverview.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/providerTemplate/ProviderTemplatesList.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/proxies/LLMProxiesList.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/proxies/LLMProxiesSummaryCardSection.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/proxies/LLMProxyGuardrailsTab.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/proxies/LLMProxyNew.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/proxies/LLMProxyOverview.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/proxies/LLMProxyResourcesTab.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ProvidersList.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderDeploymentsCard.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderGuardrailsTab.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderModelsTab.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/serviceProvider/ServiceProviderOverview.tsx

… and AssociationsTable, enhancing user feedback with tooltips for create and delete actions. Update ViewGateway and ProxyOverview components to include permission checks for editing actions, ensuring consistent access control across the application.
@Thushani-Jayasekera
Thushani-Jayasekera merged commit 2b1b519 into wso2:main Aug 4, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants