Tharga.Team
3.9.0
See the version list below for details.
dotnet add package Tharga.Team --version 3.9.0
NuGet\Install-Package Tharga.Team -Version 3.9.0
<PackageReference Include="Tharga.Team" Version="3.9.0" />
<PackageVersion Include="Tharga.Team" Version="3.9.0" />
<PackageReference Include="Tharga.Team" />
paket add Tharga.Team --version 3.9.0
#r "nuget: Tharga.Team, 3.9.0"
#:package Tharga.Team@3.9.0
#addin nuget:?package=Tharga.Team&version=3.9.0
#tool nuget:?package=Tharga.Team&version=3.9.0
Tharga Team
Domain models, service abstractions, and authorization primitives for multi-tenant Blazor applications. This package has no server-side dependencies and works with both Blazor Server and Blazor WebAssembly.
What's included
Team and user models
ITeam/ITeam<TMember>- Team aggregate with members.ITeamMember- Team member withAccessLevel, invitation state, tenant roles, and scope overrides.IUser- User identity.Invitation,InviteUserModel,MembershipState.
Service interfaces
ITeamService- Team CRUD, member management, invitations. IncludesGetMembersAsync(teamKey)returningIAsyncEnumerable<ITeamMember>for consumers that need to enumerate members without knowing the per-consumerTMembertype.ITeamManagementService- Scope-enforced mutations (create, rename, delete, invite, etc.).IUserService- Current user resolution.IApiKeyAdministrationService/IApiKeyManagementService- API key management.IApiKeyLifecycleHandler- Opt-in hook receiving an API key's private token on create/recycle (and a tokenless delete signal) viaApiKeyLifecycleContext/ApiKeyLifecycleReason. Registered throughThargaTeamOptions.AddApiKeyLifecycleHandler<T>().
Authorization
AccessLevelenum - Owner, Administrator, User, Viewer, Custom.Customgrants no inherited base scopes (effective scopes = roles ∪ scope overrides only) for least-privilege keys/members.Tagrecord - System-set key-value tag on an API key (a list, so a key may repeat). Set at creation only; surfaced as atag.{Key}claim on the authenticated principal.TeamClaimTypes- Claim type constants (TeamKey,AccessLevel,Scope,TagPrefix).IScopeRegistry/ScopeRegistry- Register and resolve scopes per access level.ITenantRoleRegistry/TenantRoleRegistry- Register code roles (global, fixed at deploy time) with associated scopes.ITenantRoleService/TenantRoleService- Team-aware role resolution: merges code roles with a team's runtime-defined custom roles and unions their scopes for a member of a given team. Registered byAddThargaDynamicTenantRoles()(wired wheno.EnableDynamicRoles = true); custom roles are created/edited per team viaITeamService.SetTeamCustomRolesAsync, with scopes constrained to app-registered scopes. The scope required to manage custom roles is configurable viaAddThargaDynamicTenantRoles(o => o.ManageScope = "…")(defaultteam:manage).ITenantRoleVisibilityProvider- Optional per-team hook that decides whether a tenant role is offered in the role editor. Default (AllRolesVisibleTenantRoleVisibilityProvider) shows every role; register your own to hide feature-gated roles from teams where the feature is disabled. Hiding a role never prunes existing assignments and does not affect scope resolution.RequireAccessLevelAttribute/RequireScopeAttribute- Declarative authorization on service methods.TeamScopes/ApiKeyScopes/AuditScopes- Built-in scope constants (audit:readgates the audit log).SystemTeamScopes- Cross-team system scopes:teams:read(enumerate any team),teams:delete(delete any team),teams:assign-owner(give an ownerless team an owner, chosen from its existing members; refused when the team already has one).ISystemScopeRegistry/ISystemRoleRegistry- Global (system) scopes for system API keys, and a mapping of app/global roles (e.g.Developer) to those scopes for privileged users. Configured viao.ConfigureSystemScopes/o.ConfigureSystemRoles.
Base classes
TeamServiceBase- Implement your own team service backend.UserServiceBase- Implement your own user service backend.
What you must override, and what happens if you do not
UserServiceBase leaves persistence to you. Several members are virtual with a do-nothing default,
so forgetting one produces a write that reports success and discards the data — no error, no log, and a
feature that looks configured and is not.
| Member | If you do not override it |
|---|---|
SetUserNameAsync |
Renaming a user reports success and changes nothing |
SeedUserNameAsync |
An invited user's name is discarded when they accept |
SetUserIconReferenceAsync (protected) |
An uploaded icon is stored, its reference discarded, and the blob orphaned |
SetUserDirectoryIdAsync |
The directory link is never persisted, so verification falls back to matching by email |
You are told at startup. AddThargaTeamBlazor reports every un-overridden member in one error,
naming the type and what each silently loses. Set o.Blazor.ThrowOnIncompleteUserService = true to make
it fatal instead. Members whose feature is unreachable — the icon one with no IIconStore registered —
are not reported, so the message stays about real mistakes.
Deriving from
UserServiceRepositoryBase(in Tharga.Team.MongoDB) implements all of these. The gaps only apply to a service extendingUserServiceBasedirectly.
One of them cannot be caught by an interface check. SetUserIconReferenceAsync is protected, so it
does not appear in an interface map — a test asserting "my service implements IUserService" cannot see
it. The startup check reflects over the concrete type and walks the base chain instead, so an override on
your own intermediate base counts.
The user cache
UserServiceBase caches resolved users. Overriding a persistence member replaces the path that
invalidated it, so the toolkit invalidates through a decorator instead — you do not need to call
InvalidateUserCache yourself.
If you see a change that survives every page reload and corrects only on process restart, that is a stale-cache read. Nothing else looks like that; a write that never landed looks identical on screen and has the opposite fix.
Related packages
| Package | Description |
|---|---|
| Tharga.Team.Blazor | Team management Blazor UI components, authentication |
| Tharga.Team.MongoDB | MongoDB persistence for teams and users |
| Tharga.Team.Service | Server-side API key auth, Swagger, audit logging |
| Tharga.Blazor | Generic Blazor UI components (buttons, breadcrumbs, etc.) |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.AspNetCore.Components.Authorization (>= 10.0.10)
- Microsoft.Extensions.DependencyInjection (>= 10.0.10)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Tharga.Toolkit (>= 1.16.0)
NuGet packages (5)
Showing the top 5 NuGet packages that depend on Tharga.Team:
| Package | Downloads |
|---|---|
|
Tharga.Team.Service
Server-side API-key authentication, authorization enforcement, controller registration, OpenAPI/Swagger setup, and audit logging for ASP.NET Core projects. |
|
|
Tharga.Team.MongoDB
MontoDB Team features for Tharga Blazor. |
|
|
Tharga.Team.Blazor
Team management Blazor components for multi-tenant applications. Works with both Blazor Server and WebAssembly. |
|
|
Tharga.Team.Entra
Microsoft Entra ID user-directory provider for Tharga Team: verify users against Entra, list directory-only users, and delete users from the directory via Microsoft Graph. |
|
|
Tharga.Team.Images
Image processing for Tharga Team icons — automatic downscaling of uploaded icons via ImageSharp. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.10.8 | 0 | 8/9/2026 |
| 3.10.7 | 49 | 8/7/2026 |
| 3.10.6 | 50 | 8/7/2026 |
| 3.10.5 | 151 | 8/4/2026 |
| 3.10.4 | 159 | 8/3/2026 |
| 3.10.3 | 164 | 8/2/2026 |
| 3.10.2 | 152 | 8/2/2026 |
| 3.10.1 | 154 | 8/2/2026 |
| 3.10.0 | 154 | 8/1/2026 |
| 3.9.0 | 151 | 8/1/2026 |
| 3.8.3 | 159 | 8/1/2026 |
| 3.8.2 | 147 | 8/1/2026 |
| 3.8.1 | 160 | 7/31/2026 |
| 3.8.0 | 157 | 7/31/2026 |
| 3.7.0 | 176 | 7/30/2026 |
| 3.6.1 | 152 | 7/27/2026 |
| 3.6.0 | 157 | 7/27/2026 |
| 3.5.4 | 165 | 7/27/2026 |
| 3.5.3 | 156 | 7/27/2026 |
| 3.5.2 | 170 | 7/26/2026 |