IBeam.Licensing.Services
2.9.43
dotnet add package IBeam.Licensing.Services --version 2.9.43
NuGet\Install-Package IBeam.Licensing.Services -Version 2.9.43
<PackageReference Include="IBeam.Licensing.Services" Version="2.9.43" />
<PackageVersion Include="IBeam.Licensing.Services" Version="2.9.43" />
<PackageReference Include="IBeam.Licensing.Services" />
paket add IBeam.Licensing.Services --version 2.9.43
#r "nuget: IBeam.Licensing.Services, 2.9.43"
#:package IBeam.Licensing.Services@2.9.43
#addin nuget:?package=IBeam.Licensing.Services&version=2.9.43
#tool nuget:?package=IBeam.Licensing.Services&version=2.9.43
IBeam.Licensing.Services
IBeam.Licensing.Services provides the service-layer implementation for IBeam tenant licensing: plan lookup, tenant license grants, license updates/revocation, seat assignment, and entitlement authorization.
dotnet add package IBeam.Licensing.Services
For ASP.NET Core endpoints, use IBeam.Licensing.Api.
When To Use This
- You want runtime services for tenant license administration.
- You need
ILicenseAuthorizerto guard product features. - You want service-operation tags and audit support around licensing mutations.
- You want an in-memory licensing store for tests, local development, or simple prototypes.
What This Package Contains
| Area | Type(s) | Purpose |
|---|---|---|
| Plan catalog | ConfigurationLicensePlanCatalogProvider |
Reads product and plan definitions from IBeam:Licensing. |
| Tenant licenses | TenantLicenseService |
Grants, updates, lists, and revokes tenant licenses. |
| Seat assignments | LicenseSeatAssignmentService |
Assigns and revokes seats for users, credentials, agents, or external subjects. |
| Seat policy helpers | LicenseSeatPolicyService |
One-call helpers for single-user and tenant/team seat grants. |
| Entitlement checks | LicenseAuthorizer |
Checks tenant license status, entitlements, and seat requirements. |
| License gate | LicenseGate |
Returns structured allow/deny details and a throwing helper for service/API boundaries. |
| Store | in-memory ILicensingStore implementation |
Default development/test persistence. |
| DI | AddIBeamLicensingServices(...) |
Registers the licensing service stack. |
Architecture Fit
API <-- DTO/model object --> Service <-- Entity --> Repository
This package is the service layer. Licensing business rules live here. APIs should call these services, and repository implementations should persist state without owning authorization decisions.
Quick Start
using IBeam.Licensing.Services;
builder.Services.AddIBeamLicensingServices(builder.Configuration);
To enforce licensing automatically on attributed IBeam service operations, opt in after registering licensing:
builder.Services
.AddIBeamLicensingServices(builder.Configuration)
.AddIBeamLicensedServiceOperations();
Then annotate a service class or method:
[IBeamRequiresEntitlement("notes:use")]
public sealed class NotesService
{
private readonly IServiceOperationExecutor _operations;
[IBeamOperation("notes.create")]
[IBeamRequiresEntitlement("notes:write")]
public Task CreateAsync(CancellationToken ct)
=> _operations.ExecuteAsync(this, _ => CreateCoreAsync(), ct: ct);
}
Class-level entitlements apply by default; method-level entitlements override them. Tenant id is resolved from ServiceOperationExecutionOptions.TenantId or ITenantContext. The subject is resolved from the current IServiceOperationPrincipalProvider using explicit IBeam subject claims, agent/API credential claims, or standard user claims.
You can also configure a default entitlement and operation-specific exceptions:
{
"IBeam": {
"Licensing": {
"ServiceOperations": {
"DefaultEntitlement": "app:use",
"OperationEntitlements": {
"ai.chat.*": "ai:chat",
"patients.create": "patients:write"
},
"NoLicenseOperations": [
"auth.*",
"billing.portal.*"
]
}
}
}
}
Attributes override configuration. No-license patterns skip licensing entirely for operations such as auth, billing portal, or renewal flows.
Configure plans:
{
"IBeam": {
"Licensing": {
"Products": [
{
"Key": "hubbsly",
"DisplayName": "Hubbsly"
}
],
"Plans": [
{
"Key": "hubbsly-work",
"ProductKey": "hubbsly",
"DisplayName": "Hubbsly Work",
"Description": "Work module access for users and agents.",
"Classification": "tenant",
"Level": 2,
"Entitlements": [ "feature:work", "work:cards:create", "mcp:tools" ],
"Limits": {
"Seats": 4,
"McpCallsPerMonth": 10000
},
"DefaultSeatLimit": 4,
"DefaultCreditGrants": [
{
"BucketKey": "ai-chat",
"Amount": 500,
"Period": "monthly"
}
],
"ProviderPrices": [
{
"ProviderName": "stripe",
"PriceId": "price_123",
"Currency": "USD",
"BillingPeriod": "monthly"
}
],
"Metadata": {
"product": "hubbsly",
"module": "work"
}
}
]
}
}
}
Grant a tenant license:
var license = await tenantLicenses.GrantLicenseAsync(
tenantId,
new GrantTenantLicenseRequest
{
PlanKey = "hubbsly-work",
ProviderName = "stripe",
ProviderCustomerId = "cus_123",
ProviderSubscriptionId = "sub_123"
},
createdByUserId,
ct);
Assign a seat:
await seatAssignments.AssignSeatAsync(
tenantId,
license.LicenseId,
new AssignLicenseSeatRequest
{
Subject = new LicenseSubject(LicenseSubjectTypes.Agent, "codex")
},
createdByUserId,
ct);
Grant a single-user license and assign the buying user in one call:
var grant = await seatPolicies.GrantSingleUserLicenseAsync(
tenantId,
new GrantSingleUserLicenseRequest
{
License = new GrantTenantLicenseRequest
{
PlanKey = "hubbsly-work"
},
Subject = new LicenseSubject(LicenseSubjectTypes.User, userId.ToString())
},
createdByUserId,
ct);
Grant a tenant/team license with multiple initial seats:
var teamGrant = await seatPolicies.GrantTenantSeatLicenseAsync(
tenantId,
new GrantTenantSeatLicenseRequest
{
SeatLimit = 10,
License = new GrantTenantLicenseRequest
{
PlanKey = "hubbsly-work"
},
InitialSubjects =
[
new LicenseSubject(LicenseSubjectTypes.User, ownerUserId.ToString()),
new LicenseSubject(LicenseSubjectTypes.ApiCredential, apiCredentialId)
]
},
createdByUserId,
ct);
Check access before a feature runs:
await licenseAuthorizer.RequireEntitlementAsync(
tenantId,
new LicenseSubject(LicenseSubjectTypes.User, userId.ToString()),
"work:cards:create",
ct);
Use the gate when an API or service needs structured denial details:
var gate = await licenseGate.CheckAsync(
new LicenseGateRequest
{
TenantId = tenantId,
Subject = new LicenseSubject(LicenseSubjectTypes.User, userId.ToString()),
Entitlement = "work:cards:create",
OperationName = "work.cards.create"
},
ct);
if (!gate.Allowed)
{
// gate.DenialCode is no-license, inactive-license, missing-entitlement, or missing-seat.
}
Service Operations
Licensing mutation methods are tagged with IBeam operation names. These names are used by service policies, audit logging, and future permission tooling.
| Service | Class Operation | Representative Method Operations |
|---|---|---|
| Tenant licenses | licensing.licenses |
licensing.licenses.list, licensing.licenses.grant, licensing.licenses.update, licensing.licenses.revoke |
| Seat assignments | licensing.seats |
licensing.seats.list, licensing.seats.assign, licensing.seats.revoke |
Example policy:
{
"IBeam": {
"Services": {
"Authorization": {
"Operations": {
"licensing.licenses.grant": {
"AllowedRoles": [ "Owner", "Admin" ]
},
"licensing.seats.revoke": {
"AllowedRoles": [ "Owner", "Admin" ]
}
}
}
}
}
}
Auditing
When IBeam service auditing is enabled, license grants, updates, revocations, and seat mutations should be captured at the service boundary. The audit record should describe the database-facing entity state before and after mutation, not an API DTO decorated with external data.
Data Storage
The bundled store is in-memory and intended for local development, tests, and simple hosts. Production applications should replace ILicensingStore with an Azure Table, EF, SQL, or application-specific provider.
builder.Services.AddIBeamLicensingServices(builder.Configuration);
builder.Services.AddScoped<ILicensingStore, MyLicensingStore>();
Register the replacement after AddIBeamLicensingServices so the host application's store wins.
Extension Points
| Extension Point | Interface | Why Replace It |
|---|---|---|
| License persistence | ILicensingStore |
Store licenses and seats in the host data platform. |
| Plan catalog | ILicensePlanCatalogProvider |
Load plans from database, billing provider, or another config source. |
| Product catalog | ILicenseProductCatalogProvider |
Load product metadata independently from plan lookups. |
| Entitlement checks | ILicenseAuthorizer |
Add product-specific quota or billing-state rules. |
| Provider hooks | ILicenseExtension |
Integrate Stripe, Azure Marketplace, manual grants, or custom billing. |
Extended Docs And Agent Guidance
- AI prompt:
.agent/prompt.md - Root implementation guide:
../.agent/implementation-guide.md - Service logging and audit:
../docs/service-logging-and-audit.md - Service operation permissions:
../docs/service-operation-permissions.md - Consuming API migration prompt:
../IBeam.AI.Enablement/examples/consuming-api-migration-prompt.md
Agents should tag new custom licensing methods with [IBeamOperation("licensing.<area>.<action>")] and route work through IServiceOperationExecutor when policy/audit behavior is required.
Troubleshooting
| Problem | Likely Cause | Fix |
|---|---|---|
| Entitlement check fails | Tenant has no active license with the entitlement | Verify plan configuration and tenant license status. |
| Seat check fails | Subject does not have an active assignment | Assign a seat or use a plan/rule that does not require one. |
| Data disappears after restart | In-memory store is active | Register a persistent ILicensingStore. |
| Audits are missing | Service auditing not configured | Register IBeam service auditing and a sink/logger package. |
Version Notes
- Targets
net10.0. - Uses IBeam service-operation patterns.
- Package version is assigned by the repository release workflow.
| 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
- IBeam.Licensing (>= 2.9.43)
- IBeam.Services (>= 2.9.43)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.3)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on IBeam.Licensing.Services:
| Package | Downloads |
|---|---|
|
IBeam.Licensing.Api
ASP.NET Core endpoint wiring for IBeam tenant application licensing. |
|
|
IBeam.Credits.Api
ASP.NET Core endpoint wiring for IBeam credit balance summaries, ledger queries, and reservations. |
GitHub repositories
This package is not used by any popular GitHub repositories.