Summary
Expose role-claims management (RoleManager.GetClaimsAsync / AddClaimAsync / RemoveClaimAsync) through the Admin module, with a "Claims" tab on the role edit page.
Why we need this
Role claims are the cleanest way to attach bulk attributes to every user holding a role — once, in one place — and have them flow into every principal automatically. They complement the per-user claims feature (sister issue) and the existing permission system without overlapping either:
- A
Tier1Support role might carry support_queue: tier1. Every user with that role inherits the claim — no per-user wiring.
- A
Manager role might carry can_approve_amount: 5000. Bumping the limit across the company is a one-line edit, not a script.
- An
Admin role might carry audit_level: high so the AuditLogs module knows to capture extra detail.
- OIDC tokens minted by OpenIddict can include role claims by configuration, so anything stored here propagates to API clients and external services.
RoleClaim<TKey> is part of IdentityDbContext and the AspNetRoleClaims table is already in our schema. Today, nothing reads or writes it.
How the user (admin) will use it
On /admin/roles/{id}/edit, add a Claims tab next to the existing details / users-in-role view:
- Tab loads →
RoleManager.GetClaimsAsync(role) → table of Type / Value rows.
- "Add claim" form: type + value inputs.
- Delete →
RemoveClaimAsync.
- Edit a claim → remove + add (RoleManager has no
Replace shortcut, so do this server-side as one transaction).
- After any mutation, every active session of every user holding the role should see the new claim on their next request. The
PermissionClaimsTransformation already invalidates per request via the claims-transformation pipeline; verify role claims behave the same and document if there's a cache to bust.
- Like the user-claims tab, hide / mark read-only any
permission-type claims that come from the Permissions module.
Implementation notes
- New endpoints under
modules/Admin/src/SimpleModule.Admin/Endpoints/Admin/:
AdminRoleClaimsListEndpoint (GET).
AdminRoleClaimAddEndpoint (POST).
AdminRoleClaimUpdateEndpoint (PUT) — internally remove + add.
AdminRoleClaimDeleteEndpoint (DELETE).
- Gate behind
Admin.Roles.ManageClaims permission.
- Front-end:
RoleClaimsTab.tsx under Pages/Admin/components/, mirroring the user-claims tab from the sister issue for consistency.
- Audit event
RoleClaimChangedEvent per mutation.
- Tests: CRUD coverage + ensuring users holding the role observe the new claim on next sign-in.
Benefits
- One edit propagates to every user holding the role — no scripts, no batch jobs.
- Claims are exposed in OpenIddict tokens automatically, so external API consumers benefit too.
- Removes a long-standing dead branch of the Identity schema.
- Pairs cleanly with the user-claims feature: per-user overrides on top of role baselines.
Acceptance criteria
Summary
Expose role-claims management (
RoleManager.GetClaimsAsync/AddClaimAsync/RemoveClaimAsync) through the Admin module, with a "Claims" tab on the role edit page.Why we need this
Role claims are the cleanest way to attach bulk attributes to every user holding a role — once, in one place — and have them flow into every principal automatically. They complement the per-user claims feature (sister issue) and the existing permission system without overlapping either:
Tier1Supportrole might carrysupport_queue: tier1. Every user with that role inherits the claim — no per-user wiring.Managerrole might carrycan_approve_amount: 5000. Bumping the limit across the company is a one-line edit, not a script.Adminrole might carryaudit_level: highso the AuditLogs module knows to capture extra detail.RoleClaim<TKey>is part ofIdentityDbContextand theAspNetRoleClaimstable is already in our schema. Today, nothing reads or writes it.How the user (admin) will use it
On
/admin/roles/{id}/edit, add a Claims tab next to the existing details / users-in-role view:RoleManager.GetClaimsAsync(role)→ table ofType / Valuerows.RemoveClaimAsync.Replaceshortcut, so do this server-side as one transaction).PermissionClaimsTransformationalready invalidates per request via the claims-transformation pipeline; verify role claims behave the same and document if there's a cache to bust.permission-type claims that come from the Permissions module.Implementation notes
modules/Admin/src/SimpleModule.Admin/Endpoints/Admin/:AdminRoleClaimsListEndpoint(GET).AdminRoleClaimAddEndpoint(POST).AdminRoleClaimUpdateEndpoint(PUT) — internally remove + add.AdminRoleClaimDeleteEndpoint(DELETE).Admin.Roles.ManageClaimspermission.RoleClaimsTab.tsxunderPages/Admin/components/, mirroring the user-claims tab from the sister issue for consistency.RoleClaimChangedEventper mutation.Benefits
Acceptance criteria
RoleManagerworks end-to-end.permission-type claims appear read-only (managed by Permissions module).Admin.Roles.ManageClaimspermission.