Roles: tenant-owned roles, with a small set of platform roles
- Dominant language
- C#
- Stars
- 6
- Forks
- 7
- Avg merge
- 4h 42m
- Merged PRs (30d)
- 307
Description
Roles are one global list. `Role` is `SingleTenanted` (`barakoCMS/Extensions/ServiceCollectionExtensions.cs:626`), `GET /api/roles` queries every role with no tenant filter (`barakoCMS/Features/Roles/List/Endpoint.cs:32`), and `PUT /api/roles/{id}` loads and saves any role by id (`Features/Roles/Update/Endpoint.cs:47`). `docs/multi-tenancy.md` states this is by design. A role's `Permissions` name content types (`barakoCMS/Models/Role.cs:26`), but content types live in each tenant's partition, so the same entry means a different type in each tenant. `User.RoleIds` is unioned into the caller's roles in every tenant (`Infrastructure/Multitenancy/MembershipRoles.cs`).
### What was checked for a cross-tenant bug
A seeded tenant administrator cannot reach this today. Creating a tenant gives its first member the seeded Admin role (`Features/Tenants/Endpoints.cs:188`), Admin's defaults do not include `manage_roles` (`Models/SystemCapabilities.cs:289`), and all five roles routes require `manage_roles` (`Features/Roles/List/Endpoint.cs:25` and siblings), so `GET /api/roles` with that tenant admin's token answers 403. No bug for the 4.2.0 train.
The exposure is configuration. `manage_roles` is only meaningful platform-wide, but nothing says so. A tenant member endpoint accepts any existing role except SuperAdmin (`Features/Tenants/Members/Endpoints.cs:41`), so if an operator ever creates a role holding `manage_roles` for a client, that client's administrator can assign it within their tenant, and the holder then lists and edits the role definitions every other tenant uses, including the shared Admin role.
### Why it is too specific
One list assumes one organisation. An agency running a clinic and a bakery wants a Nurse role in one and a Baker role in the other, and neither client should see or change the other's. Editing Admin for one client changes Admin for all of them.
### The general concept
Tenant-owned roles: a role belongs to a tenant, and its permissions refer to that tenant's content types. A small set of platform roles (SuperAdmin, and the seeded defaults a tenant copies from) stays global and is editable only with a platform capability. `manage_roles` becomes tenant scoped; a separate platform capability covers platform roles.
### Where it lives
Core: roles, capabilities and multi-tenancy.
### Compatibility
Released, stored data changes. A migration assigns each existing custom role to the tenants whose memberships hold it (copying a role held in several), leaves the seeded ids global, and keeps role ids stable. `/api/roles` keeps its shape and answers with the caller's tenant roles plus platform roles; a platform caller keeps seeing everything. Default single-tenant deployments see no difference.
Part of the decision on what a principal is, linked from the umbrella issue. Relates #883, #886.
### Done when
- A caller holding tenant `manage_roles` in tenant A gets 404 on `PUT /api/roles/{id}` for a role owned by tenant B, with a test that fails before the change.
- Tenant A's role list does not contain tenant B's roles.
- The seeded Admin role cannot be edited without the platform capability.
- The migration keeps every existing membership's effective permissions unchanged.
Found in the architecture sweep of 15 September 2026.
Contributor guide
Research direction
Start with the role registration and access paths in barakoCMS/Extensions/ServiceCollectionExtensions.cs, Features/Roles/List/Endpoint.cs, Features/Roles/Update/Endpoint.cs, and Features/Tenants/Members/Endpoints.cs. Then read Models/Role.cs, Infrastructure/Multitenancy/MembershipRoles.cs, Features/Tenants/Endpoints.cs, and docs/multi-tenancy.md to understand seeded roles and effective permissions. Done means tenant isolation, protected platform roles, and unchanged effective permissions after migration, covered by failing-before tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- authorization, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100