Tharga.Team.Service
3.0.3
dotnet add package Tharga.Team.Service --version 3.0.3
NuGet\Install-Package Tharga.Team.Service -Version 3.0.3
<PackageReference Include="Tharga.Team.Service" Version="3.0.3" />
<PackageVersion Include="Tharga.Team.Service" Version="3.0.3" />
<PackageReference Include="Tharga.Team.Service" />
paket add Tharga.Team.Service --version 3.0.3
#r "nuget: Tharga.Team.Service, 3.0.3"
#:package Tharga.Team.Service@3.0.3
#addin nuget:?package=Tharga.Team.Service&version=3.0.3
#tool nuget:?package=Tharga.Team.Service&version=3.0.3
Tharga Team Service
Server-side API-key authentication, authorization enforcement, controller registration, OpenAPI/Swagger setup, and audit logging for ASP.NET Core projects. Targets .NET 9.0 and .NET 10.0.
Features
- API key authentication - Reads the
X-API-KEYheader, validates against a store, and populatesTeamKey,AccessLevel, and scope claims. - Access level authorization -
AccessLevelProxy<T>enforces[RequireAccessLevel]on service methods viaDispatchProxy. - Scope authorization -
ScopeProxy<T>enforces[RequireScope]with audit logging. - Controller + Swagger registration - Single-call setup for MVC controllers, OpenAPI document with API key security scheme, and Swagger UI.
- API key management - Default MongoDB-backed
ApiKeyAdministrationServicewith key hashing. Configurable viaApiKeyOptions— see API key options. - Audit logging -
CompositeAuditLoggerwithILoggerand MongoDB backends. ⚠️ Stores toILoggeronly by default — see Audit logging. - API-key lifecycle hook - Capture the private token on create/recycle (plus a delete signal) via
IApiKeyLifecycleHandler— see Capturing the private token. - Pluggable - Implement
IApiKeyAdministrationService(from Tharga.Team) to bring your own storage backend.
Quick start
using Tharga.Team;
using Tharga.Team.Service;
// Program.cs
builder.Services.AddThargaControllers();
builder.Services.AddAuthentication()
.AddThargaApiKeyAuthentication();
builder.Services.AddThargaApiKeys();
var app = builder.Build();
app.UseThargaControllers();
app.UseAuthentication();
app.UseAuthorization();
app.Run();
System API keys
For infrastructure-level credentials that aren't tied to a team (MCP gatekeepers, CI/CD callers, cross-team admin tooling), use system keys — API keys with no TeamKey.
Create and manage them via the <SystemApiKeyView /> component in Tharga.Team.Blazor (gated by the Developer role), or programmatically via IApiKeyAdministrationService.CreateSystemKeyAsync(name, scopes, expiryDate, createdBy).
System keys authenticate through the same X-API-KEY header. The principal they produce carries the IsSystemKey=true claim and the explicit scopes granted at creation time — no TeamKey claim.
Protect system-only endpoints with the system policy:
app.UseThargaMcp().RequireAuthorization(ApiKeyConstants.SystemPolicyName);
The two policies are mutually exclusive: ApiKeyPolicy rejects system keys, SystemApiKeyPolicy rejects team keys.
Team API keys
Protect endpoints with the built-in policy:
[Authorize(Policy = ApiKeyConstants.PolicyName)]
[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
var teamKey = User.FindFirst(TeamClaimTypes.TeamKey)?.Value;
return Ok(new { teamKey });
}
}
Enforce access levels on services:
public interface IMyService
{
[RequireAccessLevel(AccessLevel.Viewer)]
IAsyncEnumerable<Item> GetAsync();
[RequireAccessLevel(AccessLevel.User)]
Task<Item> AddAsync(string name);
}
// Program.cs
builder.Services.AddScopedWithAccessLevel<IMyService, MyService>();
API key options
API key behaviour is configured via ApiKeyOptions (passed to AddThargaApiKeyAuthentication, or o.ApiKey under AddThargaPlatform):
| Option | Default | Purpose |
|---|---|---|
AdvancedMode |
false |
When false, keys are auto-created per team and only refresh/lock are exposed. When true, full CRUD (name, access level, roles, scope overrides, expiry). |
AutoKeyCount |
2 |
Number of keys auto-created per team in simple mode. |
AutoLockKeys |
false |
Lock keys immediately after creation so the raw value is shown only once. |
MaxExpiryDays |
365 |
Caps expiry for team and system keys. null = no cap. |
LastUsedThrottle |
1 min |
Minimum interval between LastUsedAt writes for a key (avoids a DB write per request). TimeSpan.Zero = stamp every request. |
MinKeyLength / MaxKeyLength |
24 / 32 |
Random alphanumeric length of the key secret (base62, ≈5.95 bits/char). The length is chosen at random in [Min, Max] per key. ~190-bit at the default 32; 43 ≈ 256-bit. Floor 24 (≈143-bit). |
Audit logging
AddThargaAuditLogging records mutations (team-service operations and API-key management) and authorization events via CompositeAuditLogger.
builder.Services.AddThargaAuditLogging(o =>
{
o.StorageMode = AuditStorageMode.MongoDB; // see gotcha below
o.RetentionDays = 90; // null (or <= 0) = keep forever
});
⚠️ Gotcha:
StorageModedefaults toLoggeronly, so the MongoDB-backedAuditLogViewstays empty until you setAuditStorageMode.MongoDB(orLogger | MongoDB).AuditStorageModeis a[Flags]enum.
| Option | Default | Notes |
|---|---|---|
StorageMode |
Logger |
[Flags]: Logger, MongoDB, or both. Set MongoDB to populate AuditLogView. |
CallerFilter / EventFilter |
Api\|Web / All |
[Flags] — which caller sources / event types to record. |
ExcludedActions / ExcludedEndpoints |
empty | Skip noisy actions (e.g. "read") or endpoints. |
RetentionDays |
90 |
int? → MongoDB TTL index (Timestamp_TTL). null or <= 0 = keep forever (no TTL index). Changing/removing the TTL on an existing collection may need a manual index drop. |
BatchSize / FlushIntervalSeconds |
100 / 5 |
Background MongoDB writer tuning. |
See the implementation guide for the full reference.
Capturing the private token
The private token is shown once and never persisted, logged, or exposed over an API. To capture it (e.g. to re-deliver a minted key), register an IApiKeyLifecycleHandler — it receives the token on create and recycle/regenerate, plus a tokenless delete signal:
public class MyHandler(ISecretProtector protector, IMyStore store) : IApiKeyLifecycleHandler
{
public Task OnApiKeyLifecycleAsync(ApiKeyLifecycleContext ctx) => ctx.Reason switch
{
ApiKeyLifecycleReason.Deleted => store.RemoveAsync(ctx.ApiKeyId),
_ => store.SaveAsync(ctx.ApiKeyId, protector.Protect(ctx.PrivateToken), ctx.TeamKey, ctx.Tags),
};
}
builder.AddThargaPlatform(o => o.AddApiKeyLifecycleHandler<MyHandler>());
A throwing handler propagates out of the originating operation (capture failures are not swallowed). You own whatever you capture — encrypt it at rest.
Dependencies
- Tharga.Team - Domain models, authorization primitives, and service abstractions.
- Tharga.MongoDB - MongoDB repository infrastructure.
- Tharga.Toolkit - Shared utilities including API key hashing.
- Swashbuckle.AspNetCore - Swagger UI generation.
Related packages
| Package | Description |
|---|---|
| Tharga.Team | Domain models and authorization primitives (plain .NET, WASM-safe) |
| Tharga.Team.Blazor | Team-specific Blazor UI components |
| Tharga.Blazor | Generic Blazor UI components |
| Tharga.Team.MongoDB | MongoDB persistence for teams and users |
Links
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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.OpenApi (>= 10.0.8)
- Swashbuckle.AspNetCore (>= 10.1.7)
- Tharga.MongoDB (>= 2.10.12)
- Tharga.Team (>= 3.0.3)
-
net9.0
- Microsoft.AspNetCore.OpenApi (>= 9.0.16)
- Swashbuckle.AspNetCore (>= 10.1.7)
- Tharga.MongoDB (>= 2.10.12)
- Tharga.Team (>= 3.0.3)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Tharga.Team.Service:
| Package | Downloads |
|---|---|
|
Tharga.Team.Blazor
Team management Blazor components for multi-tenant applications. Works with both Blazor Server and WebAssembly. |
|
|
Tharga.Platform.Mcp
Platform bridge for Tharga.Mcp. Provides Platform-backed IMcpContext, scope enforcement, audit logging, and authentication for MCP tool and resource invocations. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.3 | 94 | 6/11/2026 |
| 3.0.2 | 136 | 6/4/2026 |
| 3.0.1 | 133 | 6/2/2026 |
| 3.0.0 | 120 | 6/2/2026 |
| 2.1.3 | 129 | 5/30/2026 |
| 2.1.2 | 132 | 5/29/2026 |
| 2.1.1 | 139 | 5/26/2026 |
| 2.1.0 | 136 | 5/18/2026 |
| 2.0.18 | 199 | 5/11/2026 |
| 2.0.17 | 138 | 5/10/2026 |
| 2.0.16 | 133 | 5/7/2026 |
| 2.0.15 | 155 | 4/29/2026 |
| 2.0.14 | 130 | 4/29/2026 |
| 2.0.13 | 139 | 4/21/2026 |
| 2.0.12 | 129 | 4/20/2026 |
| 2.0.11 | 158 | 4/18/2026 |
| 2.0.10 | 126 | 4/17/2026 |
| 2.0.9 | 113 | 4/17/2026 |
| 2.0.8 | 155 | 4/8/2026 |
| 2.0.7 | 132 | 4/6/2026 |