I am using ABP AI Management in an Angular-based multi-portal application. I created an AI workspace named PatientAssistant and granted the Consume permission to the Patient role, the test2 user, and the admin role. In the AI Management workspace permission modal, the permission appears correctly granted. However, when I open the Patient Portal and access the AI Assistant page, I still get the authorization error: “Authorization failed! Given policy has not granted: Volo.AIManagement.Workspaces.Workspace.Consume”. The failing portal URL is http://localhost:4200/ai-management/workspaces, and the logged-in patient user is test2. I have already checked that the Consume permission is visible in the workspace permissions modal, granted to the Patient role, granted directly to the test2 user, and that the user is authenticated in the Patient Portal. I want to know whether this permission is tenant-specific, whether I need to grant it inside the tenant context instead of the host/admin context, whether AI Management workspace permissions require any additional role or claim configuration for Angular portals, and whether I need to clear permission cache, restart the API, logout/login again, or refresh dynamic claims after granting the permission. Also, please confirm if there is any special setup required when consuming ABP AI Management workspaces from a separate Patient Portal in a multi-portal ABP Angular application. My environment is ABP Framework version [write your ABP version], UI Angular, authentication OpenIddict, multi-tenancy enabled, AI Management module enabled, and the portal is the Patient Portal.
3 Answer(s)
-
0
Hi,
Before suggesting any change, I'd like to confirm a few things, because the error message you posted is raised from a very specific code path and the URL you mentioned doesn't match it.
First, one fact about how this works in AI Management:
Volo.AIManagement.Workspaces.Workspace.Consumeis a resource permission, granted per-workspace instance. The grants are stored inAbpResourcePermissionGrants, which is multi-tenant aware — every grant row carries aTenantId, and queries are automatically filtered by the current tenant. So a grant written under the host context (TenantId = NULL) is not visible when a tenant user checks the permission, and vice versa.A few things would help me give you a precise answer:
1) The exact request that returns the error. Open browser DevTools → Network tab, reproduce the issue, and tell me which HTTP request returns the
Authorization failed!...Consumeresponse. The URLhttp://localhost:4200/ai-management/workspacesis the workspaces list page, and its route guard / list endpoint requiresAIManagement.Workspaces(a regular permission), notWorkspace.Consume. TheConsumecheck only fires from endpoints that actually consume a workspace — chat completion, embeddings, OpenAI-compatible chat/model/validation paths, and similar. So something on the page is hitting one of those endpoints — most likely a child component initializing against a workspace, or a click into a specific one. Knowing the exact failing request URL will pin this down.2) The actual grant rows, the user's tenant, and the workspace config. Please run these on your API database and share the result. Note that
ResourceKeystores the workspace Id (GUID as string), not the name — so filter byNameand inspect the rows:SELECT Id, Name, ProviderName, ProviderKey, TenantId, ResourceName, ResourceKey FROM AbpResourcePermissionGrants WHERE Name = 'Volo.AIManagement.Workspaces.Workspace.Consume'; SELECT Id, UserName, TenantId FROM AbpUsers WHERE UserName = 'test2'; SELECT Id, Name, RequiredPermissionName FROM AbpWorkspaces WHERE Name = 'PatientAssistant';This tells us (a) whether the grants were really persisted — the modal showing the checkbox is not proof, (b) the
TenantIdon the grant rows (NULL = host, otherwise a tenant), (c) theTenantIdoftest2, and (d) whether the workspace has aRequiredPermissionNameset. IfRequiredPermissionNameis not null, the check path is different — it goes through a regular permission check (IsGrantedAnyAsync) before the resource permission check, and theConsumegrant is bypassed if that one is granted.3) Where you granted the permission. Were you logged in as the host admin when you opened the workspace's permission modal, or were you operating inside a tenant (for example via Saas → Tenants → "Login with admin")? And the "Patient" role you granted to — is it a host-level role or a tenant-level role? These are separate records in
AbpRoleseven if they share the same name.While we're at it, the answers to your other questions:
- You don't need to clear the permission cache manually — it's invalidated automatically when grants are written.
- You don't need to restart the API.
- Logout / login matters in one specific case: the role-based provider key comes from the
roleclaim in the token, and the user-based provider key comes from thesubclaim. If you recently assigned a new role totest2(e.g. just added Patient),test2needs to re-login so the new role appears in the token; otherwise the role-based grant won't be matched. If you only changed the resource permission on an existing role, re-login is not needed. - There's no Angular- or portal-specific configuration required for AI Management workspace consumption. The issue, whatever it turns out to be, is on the API side.
Once I have the three items above I can give you the exact fix.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
I ran the queries you requested. Here are the results.

- AbpResourcePermissionGrants
The Consume permission exists in AbpResourcePermissionGrants with TenantId = NULL.
Rows found:
ProviderName = R ProviderKey = Patient TenantId = NULL ResourceName = Volo.AIManagement.Workspaces.Workspace ResourceKey = 5E45D5C5-AE6A-7604-1A18-3A2151F28514
ProviderName = U ProviderKey = 3B23E6FF-AA66-8029-6CA7-3A214C3D575F TenantId = NULL ResourceName = Volo.AIManagement.Workspaces.Workspace ResourceKey = 5E45D5C5-AE6A-7604-1A18-3A2151F28514
ProviderName = R ProviderKey = admin TenantId = NULL ResourceName = Volo.AIManagement.Workspaces.Workspace ResourceKey = 5E45D5C5-AE6A-7604-1A18-3A2151F28514
- AbpUsers
The logged-in user is:
- Id = 3B23E6FF-AA66-8029-6CA7-3A214C3D575F
- UserName = test2
- TenantId = NULL
- AIManagementWorkspaces
The workspace is:
- Id = 5E45D5C5-AE6A-7604-1A18-3A2151F28514
- Name = PatientAssistant
- RequiredPermissionName = NULL
So the ResourceKey in AbpResourcePermissionGrants matches the PatientAssistant workspace Id, and both the user and grants are in host context with TenantId = NULL.
I also confirmed that there is a direct user grant for test2 using ProviderName = U and ProviderKey = test2 user Id.
I will now capture the exact failing API request from the browser Network tab and share it as well. Based on the database rows above, the resource permission seems to be persisted correctly, so I want to understand why the Consume check is still failing for this user.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
Thanks for the SQL results — they actually rule out the most common cause I had in mind. Both
test2and all three grant rows haveTenantId = NULL, so this is not a host/tenant isolation issue. TheRequiredPermissionNameis also NULL, so the check goes straight to the resource permission path. And the direct user grantU / 3b23e6ff-...matchestest2's Id exactly, so on paperUserResourcePermissionValueProvider.CheckAsyncshould returnGrantedimmediately.The fact that it still fails means the mismatch is happening at runtime, not in the data. To pin it down I need two more things from you.
1) A HAR file of the failing request. Please sign
test2out, sign in fresh, reproduce the error once, then export a HAR from the Patient Portal browser and share it. Instructions are in the second answer of https://abp.io/support/questions/8622/How-to-enable-Debug-logs-for-troubleshoot-problems — DevTools → Network → right-click → "Save all as HAR with content". The HAR contains the full request (URL, headers includingAuthorization: Bearer ..., response body, status code), which lets me check three things at once: (a) which API host the call actually went to, (b) what thesubclaim in the token is — it needs to equal3b23e6ff-aa66-8029-6ca7-3a214c3d575f, otherwise theUgrant won't match, and (c) thetraceIdin the response body, so we can match it against the API log. Signing out and back in before reproducing rules out a stale token / cached session.2) API-side debug logs of one failed request. Please enable Debug-level logging on the API that's serving the failing request, reproduce the error once, and share the log around the failed call. The standard way to enable it is described here: https://abp.io/support/questions/8622/How-to-enable-Debug-logs-for-troubleshoot-problems — just bump your
appsettings.jsonSerilogDefaultlevel toDebug, keepMicrosoft.EntityFrameworkCoreatWarning. The permission checker logs at Debug level which providers it tried and what each returned, so the log will show us exactly which value provider producedUndefinedand why.You can email the HAR and log files to me directly at liming.ma@volosoft.com — they tend to be large and may contain sensitive request data, so email is easier than attaching here.
One side question while you're at it: in your multi-portal setup, is the Patient Portal calling the same API host (same DB) as the admin portal where you opened the workspace permission modal? If they're separate services with separate databases (a common microservice setup), the grants you queried might live in a different DB than the one performing the check.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)