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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tharga.Team.Service" Version="3.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tharga.Team.Service" Version="3.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Tharga.Team.Service" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tharga.Team.Service --version 3.0.3
                    
#r "nuget: Tharga.Team.Service, 3.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tharga.Team.Service@3.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tharga.Team.Service&version=3.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Tharga.Team.Service&version=3.0.3
                    
Install as a Cake Tool

Tharga Team Service

NuGet Nuget License

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-KEY header, validates against a store, and populates TeamKey, AccessLevel, and scope claims.
  • Access level authorization - AccessLevelProxy<T> enforces [RequireAccessLevel] on service methods via DispatchProxy.
  • 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 ApiKeyAdministrationService with key hashing. Configurable via ApiKeyOptions — see API key options.
  • Audit logging - CompositeAuditLogger with ILogger and MongoDB backends. ⚠️ Stores to ILogger only 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: StorageMode defaults to Logger only, so the MongoDB-backed AuditLogView stays empty until you set AuditStorageMode.MongoDB (or Logger | MongoDB). AuditStorageMode is 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

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
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
Loading failed