TAF.Identity.SDK 1.0.2

dotnet add package TAF.Identity.SDK --version 1.0.2
                    
NuGet\Install-Package TAF.Identity.SDK -Version 1.0.2
                    
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="TAF.Identity.SDK" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TAF.Identity.SDK" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="TAF.Identity.SDK" />
                    
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 TAF.Identity.SDK --version 1.0.2
                    
#r "nuget: TAF.Identity.SDK, 1.0.2"
                    
#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 TAF.Identity.SDK@1.0.2
                    
#: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=TAF.Identity.SDK&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=TAF.Identity.SDK&version=1.0.2
                    
Install as a Cake Tool

TAF.Identity.SDK

The client for IdentityService, for the services that need to ask it things.

Every other TAF service ships an SDK — Metadata, CRUD, Kibana, Blueprint, Trigger, CodeExecutor, FileManager, Report, Template, WorkflowEngine, Notification, Approval. Identity did not, so each consumer wrote its own client. This is what that cost:

Consumer Hand-written client What was wrong
taf_crud EntitlementResolverClient called a route that did not exist, sent a header nothing reads, and its base URL was set in no config file for any environment
taf_backgroundjobexecutors IdentityBillingClient read the payload from value where the service sends result, so every sweep reported null counts

None of those failed loudly. The entitlement client treats any error as "no opinion" and allows the request, so licensing enforcement was off for every tenant with nothing in any log to say so. The scheduler's sweeps genuinely ran; only their results vanished.

A path is a string, a header name is a string, and a wrong string does not break a build. This package exists so those strings live in one place, next to the service that serves them.

Install

<PackageReference Include="TAF.Identity.SDK" Version="1.0.1" />

Register

builder.Services.AddIdentitySdk(builder.Configuration);
{
  "IdentityService": {
    "BaseUrl": "http://identity.internal:8080",   // required — validated at startup
    "ApiKey": "",                                 // optional — falls back to ServiceAuth:ApiKey
    "TimeoutSeconds": 5,                          // entitlement lookups sit on the request path
    "SweepTimeoutSeconds": 600,                   // sweeps are long synchronous calls by design
    "EntitlementCacheSeconds": 60                 // bounds how long a lapsed plan keeps working
  }
}

BaseUrl is validated at startup, not on first use. The client this replaced read its URL inside an AddHttpClient lambda, which runs when the client is first resolved — so a missing value produced a healthy-looking deploy followed by a failure on every request.

Use

Entitlements — "did this tenant pay for it?"

public sealed class MyGate(IIdentityEntitlementClient identity)
{
    public async Task<bool> IsAllowedAsync(Guid tenantId, Guid appId, Guid? appObjectId, Guid? moduleId)
    {
        var plan = await identity.ResolveAsync(tenantId, appId);

        if (!SubscriptionStateMap.AllowsRead(plan.State))
            return false;

        return plan.GetAccessForObject(appObjectId, moduleId, ancestry) != FeatureAccessLevel.None;
    }
}

ResolveAsync never throws and never denies. An unreachable Identity, an unreadable body or no subscription all return PlanEntitlements.Ungated, which permits everything. Entitlement is a commercial control, not a security boundary — tenant isolation and permissions are enforced elsewhere and do not depend on this answering.

The consequence deserves stating plainly, because it is what let a broken client survive for months: when this is misconfigured, everything is allowed and the caller logs nothing alarming. Watch for the SDK's own warning, which names the status and the URL it tried.

Lifecycle sweeps — for the scheduler

var result = await identityLifecycle.RunReconcileAsync(ct);
logger.LogInformation("Reconcile repaired {Repaired} of {Scanned}.", result?.Repaired, result?.LedgerRowsScanned);

Unlike entitlements, these do surface failures. A sweep that did not run is something an operator needs to know about, and there is no "carry on regardless" answer available. A rejected credential throws IdentityServiceUnauthorizedException and is deliberately not retryable: it will be rejected identically on every attempt, and burying it in retry noise is how a silently disabled billing sweep goes unnoticed for a week.

Routes

IdentityRoutes holds every path. IdentityService's own ApiRoutes is defined from these constants, so the route a controller serves and the route a consumer requests cannot drift apart without breaking a build on one side or the other.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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 was computed.  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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 130 8/5/2026